diff options
Diffstat (limited to 'drivers/media/dvb')
299 files changed, 0 insertions, 121981 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig deleted file mode 100644 index 40ebde53b3c..00000000000 --- a/drivers/media/dvb/Kconfig +++ /dev/null @@ -1,58 +0,0 @@ -# -# DVB device configuration -# - -config DVB_DYNAMIC_MINORS - bool "Dynamic DVB minor allocation" - depends on DVB_CORE - default n - help - If you say Y here, the DVB subsystem will use dynamic minor - allocation for any device that uses the DVB major number. - This means that you can have more than 4 of a single type - of device (like demuxes and frontends) per adapter, but udev - will be required to manage the device nodes. - - If you are unsure about this, say N here. - -menuconfig DVB_CAPTURE_DRIVERS - bool "DVB/ATSC adapters" - depends on DVB_CORE - default y - ---help--- - Say Y to select Digital TV adapters - -if DVB_CAPTURE_DRIVERS && DVB_CORE - -comment "Supported SAA7146 based PCI Adapters" - depends on DVB_CORE && PCI && I2C -source "drivers/media/dvb/ttpci/Kconfig" - -comment "Supported USB Adapters" - depends on DVB_CORE && USB && I2C -source "drivers/media/dvb/dvb-usb/Kconfig" -source "drivers/media/dvb/ttusb-budget/Kconfig" -source "drivers/media/dvb/ttusb-dec/Kconfig" -source "drivers/media/dvb/siano/Kconfig" - -comment "Supported FlexCopII (B2C2) Adapters" - depends on DVB_CORE && (PCI || USB) && I2C -source "drivers/media/dvb/b2c2/Kconfig" - -comment "Supported BT878 Adapters" - depends on DVB_CORE && PCI && I2C -source "drivers/media/dvb/bt8xx/Kconfig" - -comment "Supported Pluto2 Adapters" - depends on DVB_CORE && PCI && I2C -source "drivers/media/dvb/pluto2/Kconfig" - -comment "Supported SDMC DM1105 Adapters" - depends on DVB_CORE && PCI && I2C -source "drivers/media/dvb/dm1105/Kconfig" - -comment "Supported DVB Frontends" - depends on DVB_CORE -source "drivers/media/dvb/frontends/Kconfig" - -endif # DVB_CAPTURE_DRIVERS diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile deleted file mode 100644 index f91e9eb15e5..00000000000 --- a/drivers/media/dvb/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the kernel multimedia device drivers. -# - -obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig deleted file mode 100644 index a8c6249c409..00000000000 --- a/drivers/media/dvb/b2c2/Kconfig +++ /dev/null @@ -1,45 +0,0 @@ -config DVB_B2C2_FLEXCOP - tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" - depends on DVB_CORE && I2C - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_MT352 if !DVB_FE_CUSTOMISE - select DVB_MT312 if !DVB_FE_CUSTOMISE - select DVB_NXT200X if !DVB_FE_CUSTOMISE - select DVB_STV0297 if !DVB_FE_CUSTOMISE - select DVB_BCM3510 if !DVB_FE_CUSTOMISE - select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_S5H1420 if !DVB_FE_CUSTOMISE - select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE - select DVB_ISL6421 if !DVB_FE_CUSTOMISE - select DVB_CX24123 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE - select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE - help - Support for the digital TV receiver chip made by B2C2 Inc. included in - Technisats PCI cards and USB boxes. - - Say Y if you own such a device and want to use it. - -config DVB_B2C2_FLEXCOP_PCI - tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI" - depends on DVB_B2C2_FLEXCOP && PCI && I2C - help - Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2. - - Say Y if you own such a device and want to use it. - -config DVB_B2C2_FLEXCOP_USB - tristate "Technisat/B2C2 Air/Sky/Cable2PC USB" - depends on DVB_B2C2_FLEXCOP && USB && I2C - help - Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2, - - Say Y if you own such a device and want to use it. - -config DVB_B2C2_FLEXCOP_DEBUG - bool "Enable debug for the B2C2 FlexCop drivers" - depends on DVB_B2C2_FLEXCOP - help - Say Y if you want to enable the module option to control debug messages - of all B2C2 FlexCop drivers. diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile deleted file mode 100644 index d9db066f985..00000000000 --- a/drivers/media/dvb/b2c2/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \ - flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o -obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o - - -ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),) -b2c2-flexcop-objs += flexcop-dma.o -endif - -b2c2-flexcop-pci-objs = flexcop-pci.o -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/ diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h deleted file mode 100644 index 8ce06336e76..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-common.h - common header file for device-specific source files also. - * - * see flexcop.c for copyright information. - */ -#ifndef __FLEXCOP_COMMON_H__ -#define __FLEXCOP_COMMON_H__ - -#include <linux/pci.h> -#include <linux/mutex.h> - -#include "flexcop-reg.h" - -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_filter.h" -#include "dvb_net.h" -#include "dvb_frontend.h" - -#define FC_MAX_FEED 256 - -#ifndef FC_LOG_PREFIX -#warning please define a log prefix for your file, using a default one -#define FC_LOG_PREFIX "b2c2-undef" -#endif - -/* Steal from usb.h */ -#undef err -#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg) -#undef info -#define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg) -#undef warn -#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg) - -struct flexcop_dma { - struct pci_dev *pdev; - - u8 *cpu_addr0; - dma_addr_t dma_addr0; - u8 *cpu_addr1; - dma_addr_t dma_addr1; - u32 size; /* size of each address in bytes */ -}; - -struct flexcop_i2c_adapter { - struct flexcop_device *fc; - struct i2c_adapter i2c_adap; - - u8 no_base_addr; - flexcop_i2c_port_t port; -}; - -/* Control structure for data definitions that are common to - * the B2C2-based PCI and USB devices. - */ -struct flexcop_device { - /* general */ - struct device *dev; /* for firmware_class */ - -#define FC_STATE_DVB_INIT 0x01 -#define FC_STATE_I2C_INIT 0x02 -#define FC_STATE_FE_INIT 0x04 - int init_state; - - /* device information */ - int has_32_hw_pid_filter; - flexcop_revision_t rev; - flexcop_device_type_t dev_type; - flexcop_bus_t bus_type; - - /* dvb stuff */ - struct dvb_adapter dvb_adapter; - struct dvb_frontend *fe; - struct dvb_net dvbnet; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - int (*fe_sleep) (struct dvb_frontend *); - - struct flexcop_i2c_adapter fc_i2c_adap[3]; - struct mutex i2c_mutex; - struct module *owner; - - /* options and status */ - int extra_feedcount; - int feedcount; - int pid_filtering; - int fullts_streaming_state; - - /* bus specific callbacks */ - flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register); - int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value); - - - int (*i2c_request) (struct flexcop_i2c_adapter*, - flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); - int (*stream_control) (struct flexcop_device*, int); - - int (*get_mac_addr) (struct flexcop_device *fc, int extended); - - void *bus_specific; -}; - -/* exported prototypes */ - -/* from flexcop.c */ -void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len); -void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no); - -struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len); -void flexcop_device_kfree(struct flexcop_device*); - -int flexcop_device_initialize(struct flexcop_device*); -void flexcop_device_exit(struct flexcop_device *fc); - -void flexcop_reset_block_300(struct flexcop_device *fc); - -/* from flexcop-dma.c */ -int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size); -void flexcop_dma_free(struct flexcop_dma *dma); - -int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); -int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); -int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); -int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); -int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); - -/* from flexcop-eeprom.c */ -/* the PCI part uses this call to get the MAC address, the USB part has its own */ -int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended); - -/* from flexcop-i2c.c */ -/* the PCI part uses this a i2c_request callback, whereas the usb part has its own - * one. We have it in flexcop-i2c.c, because it is going via the actual - * I2C-channel of the flexcop. - */ -int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t, - u8 chipaddr, u8 addr, u8 *buf, u16 len); - -/* from flexcop-sram.c */ -int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target); -void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s); -void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill); - -/* global prototypes for the flexcop-chip */ -/* from flexcop-fe-tuner.c */ -int flexcop_frontend_init(struct flexcop_device *card); -void flexcop_frontend_exit(struct flexcop_device *fc); - -/* from flexcop-i2c.c */ -int flexcop_i2c_init(struct flexcop_device *fc); -void flexcop_i2c_exit(struct flexcop_device *fc); - -/* from flexcop-sram.c */ -int flexcop_sram_init(struct flexcop_device *fc); - -/* from flexcop-misc.c */ -void flexcop_determine_revision(struct flexcop_device *fc); -void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix); -void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num); - -/* from flexcop-hw-filter.c */ -int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff); -void flexcop_hw_filter_init(struct flexcop_device *fc); - -void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); - -void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]); -void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff); - -#endif diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c deleted file mode 100644 index 26f0011a507..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-dma.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop. - * - * see flexcop.c for copyright information. - */ -#include "flexcop.h" - -int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) -{ - u8 *tcpu; - dma_addr_t tdma = 0; - - if (size % 2) { - err("dma buffersize has to be even."); - return -EINVAL; - } - - if ((tcpu = pci_alloc_consistent(pdev, size, &tdma)) != NULL) { - dma->pdev = pdev; - dma->cpu_addr0 = tcpu; - dma->dma_addr0 = tdma; - dma->cpu_addr1 = tcpu + size/2; - dma->dma_addr1 = tdma + size/2; - dma->size = size/2; - return 0; - } - return -ENOMEM; -} -EXPORT_SYMBOL(flexcop_dma_allocate); - -void flexcop_dma_free(struct flexcop_dma *dma) -{ - pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0); - memset(dma,0,sizeof(struct flexcop_dma)); -} -EXPORT_SYMBOL(flexcop_dma_free); - -int flexcop_dma_config(struct flexcop_device *fc, - struct flexcop_dma *dma, - flexcop_dma_index_t dma_idx) -{ - flexcop_ibi_value v0x0,v0x4,v0xc; - v0x0.raw = v0x4.raw = v0xc.raw = 0; - - v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; - v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; - v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; - - if ((dma_idx & FC_DMA_1) == dma_idx) { - fc->write_ibi_reg(fc,dma1_000,v0x0); - fc->write_ibi_reg(fc,dma1_004,v0x4); - fc->write_ibi_reg(fc,dma1_00c,v0xc); - } else if ((dma_idx & FC_DMA_2) == dma_idx) { - fc->write_ibi_reg(fc,dma2_010,v0x0); - fc->write_ibi_reg(fc,dma2_014,v0x4); - fc->write_ibi_reg(fc,dma2_01c,v0xc); - } else { - err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call."); - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL(flexcop_dma_config); - -/* start the DMA transfers, but not the DMA IRQs */ -int flexcop_dma_xfer_control(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, - flexcop_dma_addr_index_t index, - int onoff) -{ - flexcop_ibi_value v0x0,v0xc; - flexcop_ibi_register r0x0,r0xc; - - if ((dma_idx & FC_DMA_1) == dma_idx) { - r0x0 = dma1_000; - r0xc = dma1_00c; - } else if ((dma_idx & FC_DMA_2) == dma_idx) { - r0x0 = dma2_010; - r0xc = dma2_01c; - } else { - err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call."); - return -EINVAL; - } - - v0x0 = fc->read_ibi_reg(fc,r0x0); - v0xc = fc->read_ibi_reg(fc,r0xc); - - deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw); - deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw); - - if (index & FC_DMA_SUBADDR_0) - v0x0.dma_0x0.dma_0start = onoff; - - if (index & FC_DMA_SUBADDR_1) - v0xc.dma_0xc.dma_1start = onoff; - - fc->write_ibi_reg(fc,r0x0,v0x0); - fc->write_ibi_reg(fc,r0xc,v0xc); - - deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw); - deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw); - return 0; -} -EXPORT_SYMBOL(flexcop_dma_xfer_control); - -static int flexcop_dma_remap(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, - int onoff) -{ - flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c; - flexcop_ibi_value v = fc->read_ibi_reg(fc,r); - deb_info("%s\n",__func__); - v.dma_0xc.remap_enable = onoff; - fc->write_ibi_reg(fc,r,v); - return 0; -} - -int flexcop_dma_control_size_irq(struct flexcop_device *fc, - flexcop_dma_index_t no, - int onoff) -{ - flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); - - if (no & FC_DMA_1) - v.ctrl_208.DMA1_IRQ_Enable_sig = onoff; - - if (no & FC_DMA_2) - v.ctrl_208.DMA2_IRQ_Enable_sig = onoff; - - fc->write_ibi_reg(fc,ctrl_208,v); - return 0; -} -EXPORT_SYMBOL(flexcop_dma_control_size_irq); - -int flexcop_dma_control_timer_irq(struct flexcop_device *fc, - flexcop_dma_index_t no, - int onoff) -{ - flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); - - if (no & FC_DMA_1) - v.ctrl_208.DMA1_Timer_Enable_sig = onoff; - - if (no & FC_DMA_2) - v.ctrl_208.DMA2_Timer_Enable_sig = onoff; - - fc->write_ibi_reg(fc,ctrl_208,v); - return 0; -} -EXPORT_SYMBOL(flexcop_dma_control_timer_irq); - -/* 1 cycles = 1.97 msec */ -int flexcop_dma_config_timer(struct flexcop_device *fc, - flexcop_dma_index_t dma_idx, - u8 cycles) -{ - flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; - flexcop_ibi_value v = fc->read_ibi_reg(fc,r); - - flexcop_dma_remap(fc,dma_idx,0); - - deb_info("%s\n",__func__); - v.dma_0x4_write.dmatimer = cycles; - fc->write_ibi_reg(fc,r,v); - return 0; -} -EXPORT_SYMBOL(flexcop_dma_config_timer); - diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c deleted file mode 100644 index 8a8ae8a3e6b..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-eeprom.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used) - * - * see flexcop.c for copyright information. - */ -#include "flexcop.h" - -#if 0 -/*EEPROM (Skystar2 has one "24LC08B" chip on board) */ -static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len) -{ - return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len); -} - -static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries) -{ - int i; - - for (i = 0; i < retries; i++) { - if (eeprom_write(adapter, addr, wbuf, len) == len) { - if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) - return 1; - } - } - - return 0; -} - -/* These functions could be used to unlock SkyStar2 cards. */ - -static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len) -{ - u8 rbuf[20]; - u8 wbuf[20]; - - if (len != 16) - return 0; - - memcpy(wbuf, key, len); - - wbuf[16] = 0; - wbuf[17] = 0; - wbuf[18] = 0; - wbuf[19] = calc_lrc(wbuf, 19); - - return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4); -} - -static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len) -{ - u8 buf[20]; - - if (len != 16) - return 0; - - if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0) - return 0; - - memcpy(key, buf, len); - - return 1; -} - -static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) -{ - u8 tmp[8]; - - if (type != 0) { - tmp[0] = mac[0]; - tmp[1] = mac[1]; - tmp[2] = mac[2]; - tmp[3] = mac[5]; - tmp[4] = mac[6]; - tmp[5] = mac[7]; - - } else { - - tmp[0] = mac[0]; - tmp[1] = mac[1]; - tmp[2] = mac[2]; - tmp[3] = mac[3]; - tmp[4] = mac[4]; - tmp[5] = mac[5]; - } - - tmp[6] = 0; - tmp[7] = calc_lrc(tmp, 7); - - if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8) - return 1; - - return 0; -} - -static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len) -{ - return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len); -} - -#endif - -static u8 calc_lrc(u8 *buf, int len) -{ - int i; - u8 sum = 0; - for (i = 0; i < len; i++) - sum = sum ^ buf[i]; - return sum; -} - -static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) -{ - int i,ret = 0; - u8 chipaddr = 0x50 | ((addr >> 8) & 3); - for (i = 0; i < retries; i++) { - ret = fc->i2c_request(&fc->fc_i2c_adap[1], op, chipaddr, - addr & 0xff, buf, len); - if (ret == 0) - break; - } - return ret; -} - -static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries) -{ - int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries); - if (ret == 0) - if (calc_lrc(buf, len - 1) != buf[len - 1]) - ret = -EINVAL; - return ret; -} - -/* JJ's comment about extended == 1: it is not presently used anywhere but was - * added to the low-level functions for possible support of EUI64 - */ -int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) -{ - u8 buf[8]; - int ret = 0; - - if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) { - if (extended != 0) { - err("TODO: extended (EUI64) MAC addresses aren't completely supported yet"); - ret = -EINVAL; -/* memcpy(fc->dvb_adapter.proposed_mac,buf,3); - mac[3] = 0xfe; - mac[4] = 0xff; - memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */ - } else - memcpy(fc->dvb_adapter.proposed_mac,buf,6); - } - return ret; -} -EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr); diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c deleted file mode 100644 index 5cded370854..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC. - * - * see flexcop.c for copyright information. - */ -#include <media/tuner.h> - -#include "flexcop.h" - -#include "stv0299.h" -#include "mt352.h" -#include "nxt200x.h" -#include "bcm3510.h" -#include "stv0297.h" -#include "mt312.h" -#include "lgdt330x.h" -#include "dvb-pll.h" -#include "tuner-simple.h" - -#include "s5h1420.h" -#include "itd1000.h" - -#include "cx24123.h" -#include "cx24113.h" - -#include "isl6421.h" - -/* lnb control */ - -static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct flexcop_device *fc = fe->dvb->priv; - flexcop_ibi_value v; - deb_tuner("polarity/voltage = %u\n", voltage); - - v = fc->read_ibi_reg(fc, misc_204); - switch (voltage) { - case SEC_VOLTAGE_OFF: - v.misc_204.ACPI1_sig = 1; - break; - case SEC_VOLTAGE_13: - v.misc_204.ACPI1_sig = 0; - v.misc_204.LNB_L_H_sig = 0; - break; - case SEC_VOLTAGE_18: - v.misc_204.ACPI1_sig = 0; - v.misc_204.LNB_L_H_sig = 1; - break; - default: - err("unknown SEC_VOLTAGE value"); - return -EINVAL; - } - return fc->write_ibi_reg(fc, misc_204, v); -} - -static int flexcop_sleep(struct dvb_frontend* fe) -{ - struct flexcop_device *fc = fe->dvb->priv; -/* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */ - - if (fc->fe_sleep) - return fc->fe_sleep(fe); - -/* v.misc_204.ACPI3_sig = 1; - fc->write_ibi_reg(fc,misc_204,v);*/ - - return 0; -} - -static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ - struct flexcop_device *fc = fe->dvb->priv; - flexcop_ibi_value v; - u16 ax; - v.raw = 0; - - deb_tuner("tone = %u\n",tone); - - switch (tone) { - case SEC_TONE_ON: - ax = 0x01ff; - break; - case SEC_TONE_OFF: - ax = 0; - break; - default: - err("unknown SEC_TONE value"); - return -EINVAL; - } - - v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */ - - v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax; - v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax; - - return fc->write_ibi_reg(fc,lnb_switch_freq_200,v); -} - -static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data) -{ - flexcop_set_tone(fe, SEC_TONE_ON); - udelay(data ? 500 : 1000); - flexcop_set_tone(fe, SEC_TONE_OFF); - udelay(data ? 1000 : 500); -} - -static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data) -{ - int i, par = 1, d; - - for (i = 7; i >= 0; i--) { - d = (data >> i) & 1; - par ^= d; - flexcop_diseqc_send_bit(fe, d); - } - - flexcop_diseqc_send_bit(fe, par); -} - -static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst) -{ - int i; - - flexcop_set_tone(fe, SEC_TONE_OFF); - mdelay(16); - - for (i = 0; i < len; i++) - flexcop_diseqc_send_byte(fe,msg[i]); - - mdelay(16); - - if (burst != -1) { - if (burst) - flexcop_diseqc_send_byte(fe, 0xff); - else { - flexcop_set_tone(fe, SEC_TONE_ON); - mdelay(12); - udelay(500); - flexcop_set_tone(fe, SEC_TONE_OFF); - } - msleep(20); - } - return 0; -} - -static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) -{ - return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0); -} - -static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); -} - -/* dvb-s stv0299 */ -static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg (fe, 0x13, aclk); - stv0299_writereg (fe, 0x14, bclk); - stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); - - return 0; -} - -static int samsung_tbmu24112_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct flexcop_device *fc = fe->dvb->priv; - - div = params->frequency / 125; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x84; /* 0xC4 */ - buf[3] = 0x08; - - if (params->frequency < 1500000) - buf[3] |= 0x10; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static u8 samsung_tbmu24112_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7D, - 0x05, 0x35, - 0x06, 0x02, - 0x07, 0x00, - 0x08, 0xC3, - 0x0C, 0x00, - 0x0D, 0x81, - 0x0E, 0x23, - 0x0F, 0x12, - 0x10, 0x7E, - 0x11, 0x84, - 0x12, 0xB9, - 0x13, 0x88, - 0x14, 0x89, - 0x15, 0xC9, - 0x16, 0x00, - 0x17, 0x5C, - 0x18, 0x00, - 0x19, 0x00, - 0x1A, 0x00, - 0x1C, 0x00, - 0x1D, 0x00, - 0x1E, 0x00, - 0x1F, 0x3A, - 0x20, 0x2E, - 0x21, 0x80, - 0x22, 0xFF, - 0x23, 0xC1, - 0x28, 0x00, - 0x29, 0x1E, - 0x2A, 0x14, - 0x2B, 0x0F, - 0x2C, 0x09, - 0x2D, 0x05, - 0x31, 0x1F, - 0x32, 0x19, - 0x33, 0xFE, - 0x34, 0x93, - 0xff, 0xff, -}; - -static struct stv0299_config samsung_tbmu24112_config = { - .demod_address = 0x68, - .inittab = samsung_tbmu24112_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_LK, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, -}; - -/* dvb-t mt352 */ -static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) -{ - static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d }; - static u8 mt352_reset [] = { 0x50, 0x80 }; - static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 }; - static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; - - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - udelay(2000); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - - mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); - mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); - - return 0; -} - -static int samsung_tdtc9251dh0_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters *params, u8* pllbuf, int buf_len) -{ - u32 div; - unsigned char bs = 0; - - if (buf_len < 5) - return -EINVAL; - - #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - - if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09; - if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; - if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; - - pllbuf[0] = 0x61; - pllbuf[1] = div >> 8; - pllbuf[2] = div & 0xff; - pllbuf[3] = 0xcc; - pllbuf[4] = bs; - - return 5; -} - -static struct mt352_config samsung_tdtc9251dh0_config = { - .demod_address = 0x0f, - .demod_init = samsung_tdtc9251dh0_demod_init, -}; - -static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) -{ - struct flexcop_device *fc = fe->dvb->priv; - return request_firmware(fw, name, fc->dev); -} - -static struct lgdt330x_config air2pc_atsc_hd5000_config = { - .demod_address = 0x59, - .demod_chip = LGDT3303, - .serial_mpeg = 0x04, - .clock_polarity_flip = 1, -}; - -static struct nxt200x_config samsung_tbmv_config = { - .demod_address = 0x0a, -}; - -static struct bcm3510_config air2pc_atsc_first_gen_config = { - .demod_address = 0x0f, - .request_firmware = flexcop_fe_request_firmware, -}; - -static int skystar23_samsung_tbdu18132_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct flexcop_device *fc = fe->dvb->priv; - - div = (params->frequency + (125/2)) / 125; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = (div >> 0) & 0xff; - buf[2] = 0x84 | ((div >> 10) & 0x60); - buf[3] = 0x80; - - if (params->frequency < 1550000) - buf[3] |= 0x02; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&fc->fc_i2c_adap[0].i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct mt312_config skystar23_samsung_tbdu18132_config = { - - .demod_address = 0x0e, -}; - -static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct flexcop_device *fc = fe->dvb->priv; - u8 buf[4]; - u16 div; - int ret; - -/* 62.5 kHz * 10 */ -#define REF_FREQ 625 -#define FREQ_OFFSET 36125 - - div = ((fep->frequency/1000 + FREQ_OFFSET ) * 10) / REF_FREQ; // 4 MHz = 4000 KHz - - buf[0] = (u8)( div >> 8) & 0x7f; - buf[1] = (u8) div & 0xff; - -/* F(osc) = N * Reference Freq. (62.5 kHz) - * byte 2 : 0 N14 N13 N12 N11 N10 N9 N8 - * byte 3 : N7 N6 N5 N4 N3 N2 N1 N0 - * byte 4 : 1 * * AGD R3 R2 R1 R0 - * byte 5 : C1 * RE RTS BS4 BS3 BS2 BS1 - * AGD = 1, R3 R2 R1 R0 = 0 1 0 1 => byte 4 = 1**10101 = 0x95 */ - buf[2] = 0x95; - -// Range(MHz) C1 * RE RTS BS4 BS3 BS2 BS1 Byte 5 -// 47 - 153 0 * 0 0 0 0 0 1 0x01 -// 153 - 430 0 * 0 0 0 0 1 0 0x02 -// 430 - 822 0 * 0 0 1 0 0 0 0x08 -// 822 - 862 1 * 0 0 1 0 0 0 0x88 - - if (fep->frequency <= 153000000) buf[3] = 0x01; - else if (fep->frequency <= 430000000) buf[3] = 0x02; - else if (fep->frequency <= 822000000) buf[3] = 0x08; - else buf[3] = 0x88; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); - ret = fc->i2c_request(&fc->fc_i2c_adap[2], - FC_WRITE, 0x61, buf[0], &buf[1], 3); - deb_tuner("tuner write returned: %d\n",ret); - - return ret; -} - -static u8 alps_tdee4_stv0297_inittab[] = { - 0x80, 0x01, - 0x80, 0x00, - 0x81, 0x01, - 0x81, 0x00, - 0x00, 0x48, - 0x01, 0x58, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x30, 0xff, - 0x31, 0x9d, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x29, - 0x35, 0x55, - 0x36, 0x80, - 0x37, 0x6e, - 0x38, 0x9c, - 0x40, 0x1a, - 0x41, 0xfe, - 0x42, 0x33, - 0x43, 0x00, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0x51, - 0x4b, 0xf8, - 0x52, 0x30, - 0x53, 0x06, - 0x59, 0x06, - 0x5a, 0x5e, - 0x5b, 0x04, - 0x61, 0x49, - 0x62, 0x0a, - 0x70, 0xff, - 0x71, 0x04, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x20, - 0x81, 0x00, - 0x82, 0x30, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x22, - 0x86, 0x08, - 0x87, 0x1b, - 0x88, 0x00, - 0x89, 0x00, - 0x90, 0x00, - 0x91, 0x04, - 0xa0, 0x86, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x5b, - 0xc1, 0x10, - 0xc2, 0x12, - 0xd0, 0x02, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x02, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x01, - 0xff, 0xff, -}; - -static struct stv0297_config alps_tdee4_stv0297_config = { - .demod_address = 0x1c, - .inittab = alps_tdee4_stv0297_inittab, -// .invert = 1, -// .pll_set = alps_tdee4_stv0297_pll_set, -}; - - -/* SkyStar2 rev2.7 (a/u) */ -static struct s5h1420_config skystar2_rev2_7_s5h1420_config = { - .demod_address = 0x53, - .invert = 1, - .repeated_start_workaround = 1, - .serial_mpeg = 1, -}; - -static struct itd1000_config skystar2_rev2_7_itd1000_config = { - .i2c_address = 0x61, -}; - -/* SkyStar2 rev2.8 */ -static struct cx24123_config skystar2_rev2_8_cx24123_config = { - .demod_address = 0x55, - .dont_use_pll = 1, - .agc_callback = cx24113_agc_callback, -}; - -static const struct cx24113_config skystar2_rev2_8_cx24113_config = { - .i2c_addr = 0x54, - .xtal_khz = 10111, -}; - -/* try to figure out the frontend, each card/box can have on of the following list */ -int flexcop_frontend_init(struct flexcop_device *fc) -{ - struct dvb_frontend_ops *ops; - struct i2c_adapter *i2c = &fc->fc_i2c_adap[0].i2c_adap; - struct i2c_adapter *i2c_tuner; - - /* enable no_base_addr - no repeated start when reading */ - fc->fc_i2c_adap[0].no_base_addr = 1; - fc->fe = dvb_attach(s5h1420_attach, &skystar2_rev2_7_s5h1420_config, i2c); - if (fc->fe != NULL) { - flexcop_ibi_value r108; - i2c_tuner = s5h1420_get_tuner_i2c_adapter(fc->fe); - ops = &fc->fe->ops; - - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; - - fc->dev_type = FC_SKY_REV27; - - /* enable no_base_addr - no repeated start when reading */ - fc->fc_i2c_adap[2].no_base_addr = 1; - if (dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap, 0x08, 1, 1) == NULL) - err("ISL6421 could NOT be attached"); - else - info("ISL6421 successfully attached"); - - /* the ITD1000 requires a lower i2c clock - it slows down the stuff for everyone - but is it a problem ? */ - r108.raw = 0x00000506; - fc->write_ibi_reg(fc, tw_sm_c_108, r108); - if (i2c_tuner) { - if (dvb_attach(itd1000_attach, fc->fe, i2c_tuner, &skystar2_rev2_7_itd1000_config) == NULL) - err("ITD1000 could NOT be attached"); - else - info("ITD1000 successfully attached"); - } - goto fe_found; - } - fc->fc_i2c_adap[0].no_base_addr = 0; /* for the next devices we need it again */ - - /* try the sky v2.8 (cx24123, isl6421) */ - fc->fe = dvb_attach(cx24123_attach, - &skystar2_rev2_8_cx24123_config, i2c); - if (fc->fe != NULL) { - i2c_tuner = cx24123_get_tuner_i2c_adapter(fc->fe); - if (i2c_tuner != NULL) { - if (dvb_attach(cx24113_attach, fc->fe, - &skystar2_rev2_8_cx24113_config, - i2c_tuner) == NULL) - err("CX24113 could NOT be attached"); - else - info("CX24113 successfully attached"); - } - - fc->dev_type = FC_SKY_REV28; - - fc->fc_i2c_adap[2].no_base_addr = 1; - if (dvb_attach(isl6421_attach, fc->fe, - &fc->fc_i2c_adap[2].i2c_adap, 0x08, 0, 0) == NULL) - err("ISL6421 could NOT be attached"); - else - info("ISL6421 successfully attached"); - - /* TODO on i2c_adap[1] addr 0x11 (EEPROM) there seems to be an - * IR-receiver (PIC16F818) - but the card has no input for - * that ??? */ - - goto fe_found; - } - - /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ - fc->fe = dvb_attach(stv0299_attach, &samsung_tbmu24112_config, i2c); - if (fc->fe != NULL) { - ops = &fc->fe->ops; - - ops->tuner_ops.set_params = samsung_tbmu24112_tuner_set_params; - - ops->set_voltage = flexcop_set_voltage; - - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; - - fc->dev_type = FC_SKY; - goto fe_found; - } - - /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ - fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_DVB; - fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs; - goto fe_found; - } - - /* try the air atsc 2nd generation (nxt2002) */ - fc->fe = dvb_attach(nxt200x_attach, &samsung_tbmv_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_ATSC2; - dvb_attach(dvb_pll_attach, fc->fe, 0x61, NULL, DVB_PLL_SAMSUNG_TBMV); - goto fe_found; - } - - fc->fe = dvb_attach(lgdt330x_attach, &air2pc_atsc_hd5000_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_ATSC3; - dvb_attach(simple_tuner_attach, fc->fe, i2c, 0x61, - TUNER_LG_TDVS_H06XF); - goto fe_found; - } - - /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */ - fc->fe = dvb_attach(bcm3510_attach, &air2pc_atsc_first_gen_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_AIR_ATSC1; - goto fe_found; - } - - /* try the cable dvb (stv0297) */ - fc->fc_i2c_adap[0].no_base_addr = 1; - fc->fe = dvb_attach(stv0297_attach, &alps_tdee4_stv0297_config, i2c); - if (fc->fe != NULL) { - fc->dev_type = FC_CABLE; - fc->fe->ops.tuner_ops.set_params = alps_tdee4_stv0297_tuner_set_params; - goto fe_found; - } - fc->fc_i2c_adap[0].no_base_addr = 0; - - /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ - fc->fe = dvb_attach(mt312_attach, - &skystar23_samsung_tbdu18132_config, i2c); - if (fc->fe != NULL) { - ops = &fc->fe->ops; - - ops->tuner_ops.set_params = skystar23_samsung_tbdu18132_tuner_set_params; - - ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; - ops->diseqc_send_burst = flexcop_diseqc_send_burst; - ops->set_tone = flexcop_set_tone; - ops->set_voltage = flexcop_set_voltage; - - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; - - fc->dev_type = FC_SKY_OLD; - goto fe_found; - } - - err("no frontend driver found for this B2C2/FlexCop adapter"); - return -ENODEV; - -fe_found: - info("found '%s' .", fc->fe->ops.info.name); - if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { - err("frontend registration failed!"); - ops = &fc->fe->ops; - if (ops->release != NULL) - ops->release(fc->fe); - fc->fe = NULL; - return -EINVAL; - } - fc->init_state |= FC_STATE_FE_INIT; - return 0; -} - -void flexcop_frontend_exit(struct flexcop_device *fc) -{ - if (fc->init_state & FC_STATE_FE_INIT) { - dvb_unregister_frontend(fc->fe); - dvb_frontend_detach(fc->fe); - } - - fc->init_state &= ~FC_STATE_FE_INIT; -} diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c deleted file mode 100644 index b386cc66c6b..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions. - * - * see flexcop.c for copyright information. - */ -#include "flexcop.h" - -static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff) -{ - flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff); - - deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off"); -} - -void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) -{ - flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff); -} - -static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff) -{ - flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff); -} - -void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]) -{ - flexcop_ibi_value v418,v41c; - v41c = fc->read_ibi_reg(fc,mac_address_41c); - - v418.mac_address_418.MAC1 = mac[0]; - v418.mac_address_418.MAC2 = mac[1]; - v418.mac_address_418.MAC3 = mac[2]; - v418.mac_address_418.MAC6 = mac[3]; - v41c.mac_address_41c.MAC7 = mac[4]; - v41c.mac_address_41c.MAC8 = mac[5]; - - fc->write_ibi_reg(fc,mac_address_418,v418); - fc->write_ibi_reg(fc,mac_address_41c,v41c); -} - -void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff) -{ - flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff); -} - -static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask) -{ - /* index_reg_310.extra_index_reg need to 0 or 7 to work */ - flexcop_ibi_value v30c; - v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid; - v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask; - fc->write_ibi_reg(fc,pid_filter_30c,v30c); -} - -static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff) -{ - flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff); -} - -/* this fancy define reduces the code size of the quite similar PID controlling of - * the first 6 PIDs - */ - -#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \ - flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \ - v208 = fc->read_ibi_reg(fc, ctrl_208); \ -\ - vpid.vregname.field = onoff ? pid : 0x1fff; \ - vpid.vregname.trans_field = transval; \ - v208.ctrl_208.enablefield = onoff; \ -\ - fc->write_ibi_reg(fc,vregname,vpid); \ - fc->write_ibi_reg(fc,ctrl_208,v208); - -static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) -{ - pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0); -} - -static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) -{ - pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0); -} - -static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) -{ - pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0); -} - -static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) -{ - pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0); -} - -static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) -{ - pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0); -} - -static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) -{ - pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0); -} - -static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) -{ - if (pid == 0x2000) - return; - - deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off"); - - /* We could use bit magic here to reduce source code size. - * I decided against it, but to use the real register names */ - switch (index) { - case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break; - case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break; - case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break; - case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break; - case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break; - case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break; - default: - if (fc->has_32_hw_pid_filter && index < 38) { - flexcop_ibi_value vpid,vid; - - /* set the index */ - vid = fc->read_ibi_reg(fc,index_reg_310); - vid.index_reg_310.index_reg = index - 6; - fc->write_ibi_reg(fc,index_reg_310, vid); - - vpid = fc->read_ibi_reg(fc,pid_n_reg_314); - vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff; - vpid.pid_n_reg_314.PID_enable_bit = onoff; - fc->write_ibi_reg(fc,pid_n_reg_314, vpid); - } - break; - } -} - -static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff) -{ - if (fc->fullts_streaming_state != onoff) { - deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling"); - flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff)); - flexcop_pid_group_filter_ctrl(fc,onoff); - fc->fullts_streaming_state = onoff; - } - return 0; -} - -int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) -{ - int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; - - fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */ - if (dvbdmxfeed->index >= max_pid_filter) - fc->extra_feedcount += onoff ? 1 : -1; - - /* toggle complete-TS-streaming when: - * - pid_filtering is not enabled and it is the first or last feed requested - * - pid_filtering is enabled, - * - but the number of requested feeds is exceeded - * - or the requested pid is 0x2000 */ - - if (!fc->pid_filtering && fc->feedcount == onoff) - flexcop_toggle_fullts_streaming(fc,onoff); - - if (fc->pid_filtering) { - flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); - - if (fc->extra_feedcount > 0) - flexcop_toggle_fullts_streaming(fc,1); - else if (dvbdmxfeed->pid == 0x2000) - flexcop_toggle_fullts_streaming(fc,onoff); - else - flexcop_toggle_fullts_streaming(fc,0); - } - - /* if it was the first or last feed request change the stream-status */ - if (fc->feedcount == onoff) { - flexcop_rcv_data_ctrl(fc,onoff); - if (fc->stream_control) /* device specific stream control */ - fc->stream_control(fc,onoff); - - /* feeding stopped -> reset the flexcop filter*/ - if (onoff == 0) { - flexcop_reset_block_300(fc); - flexcop_hw_filter_init(fc); - } - } - - return 0; -} - -void flexcop_hw_filter_init(struct flexcop_device *fc) -{ - int i; - flexcop_ibi_value v; - for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) - flexcop_pid_control(fc,i,0x1fff,0); - - flexcop_pid_group_filter(fc, 0, 0x1fe0); - flexcop_pid_group_filter_ctrl(fc,0); - - v = fc->read_ibi_reg(fc,pid_filter_308); - v.pid_filter_308.EMM_filter_4 = 1; - v.pid_filter_308.EMM_filter_6 = 0; - fc->write_ibi_reg(fc,pid_filter_308,v); - - flexcop_null_filter_ctrl(fc, 1); -} diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c deleted file mode 100644 index f13783f08f0..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization - * - * see flexcop.c for copyright information. - */ -#include "flexcop.h" - -#define FC_MAX_I2C_RETRIES 100000 - -/* #define DUMP_I2C_MESSAGES */ - -static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100) -{ - int i; - flexcop_ibi_value r; - - r100->tw_sm_c_100.working_start = 1; - deb_i2c("r100 before: %08x\n",r100->raw); - - fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero); - fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */ - - for (i = 0; i < FC_MAX_I2C_RETRIES; i++) { - r = fc->read_ibi_reg(fc, tw_sm_c_100); - - if (!r.tw_sm_c_100.no_base_addr_ack_error) { - if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */ - *r100 = r; - deb_i2c("i2c success\n"); - return 0; - } - } else { - deb_i2c("suffering from an i2c ack_error\n"); - return -EREMOTEIO; - } - } - deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i); - return -EREMOTEIO; -} - -static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c, - flexcop_ibi_value r100, u8 *buf) -{ - flexcop_ibi_value r104; - int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */ - ret; - - ret = flexcop_i2c_operation(i2c->fc, &r100); - if (ret != 0) { - deb_i2c("Retrying operation\n"); - r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr; - ret = flexcop_i2c_operation(i2c->fc, &r100); - } - if (ret != 0) { - deb_i2c("read failed. %d\n", ret); - return ret; - } - - buf[0] = r100.tw_sm_c_100.data1_reg; - - if (len > 0) { - r104 = i2c->fc->read_ibi_reg(i2c->fc, tw_sm_c_104); - deb_i2c("read: r100: %08x, r104: %08x\n", r100.raw, r104.raw); - - /* there is at least one more byte, otherwise we wouldn't be here */ - buf[1] = r104.tw_sm_c_104.data2_reg; - if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg; - if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg; - } - - return 0; -} - -static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf) -{ - flexcop_ibi_value r104; - int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */ - r104.raw = 0; - - /* there is at least one byte, otherwise we wouldn't be here */ - r100.tw_sm_c_100.data1_reg = buf[0]; - - r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0; - r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0; - r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0; - - deb_i2c("write: r100: %08x, r104: %08x\n", r100.raw, r104.raw); - - /* write the additional i2c data before doing the actual i2c operation */ - fc->write_ibi_reg(fc, tw_sm_c_104, r104); - return flexcop_i2c_operation(fc, &r100); -} - -int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c, - flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) -{ - int ret; - -#ifdef DUMP_I2C_MESSAGES - int i; -#endif - - u16 bytes_to_transfer; - flexcop_ibi_value r100; - - deb_i2c("op = %d\n",op); - r100.raw = 0; - r100.tw_sm_c_100.chipaddr = chipaddr; - r100.tw_sm_c_100.twoWS_rw = op; - r100.tw_sm_c_100.twoWS_port_reg = i2c->port; - -#ifdef DUMP_I2C_MESSAGES - printk(KERN_DEBUG "%d ", i2c->port); - if (op == FC_READ) - printk("rd("); - else - printk("wr("); - - printk("%02x): %02x ", chipaddr, addr); -#endif - - /* in that case addr is the only value -> - * we write it twice as baseaddr and val0 - * BBTI is doing it like that for ISL6421 at least */ - if (i2c->no_base_addr && len == 0 && op == FC_WRITE) { - buf = &addr; - len = 1; - } - - while (len != 0) { - bytes_to_transfer = len > 4 ? 4 : len; - - r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1; - r100.tw_sm_c_100.baseaddr = addr; - - if (op == FC_READ) - ret = flexcop_i2c_read4(i2c, r100, buf); - else - ret = flexcop_i2c_write4(i2c->fc, r100, buf); - -#ifdef DUMP_I2C_MESSAGES - for (i = 0; i < bytes_to_transfer; i++) - printk("%02x ", buf[i]); -#endif - - if (ret < 0) - return ret; - - buf += bytes_to_transfer; - addr += bytes_to_transfer; - len -= bytes_to_transfer; - } - -#ifdef DUMP_I2C_MESSAGES - printk("\n"); -#endif - - return 0; -} -/* exported for PCI i2c */ -EXPORT_SYMBOL(flexcop_i2c_request); - -/* master xfer callback for demodulator */ -static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) -{ - struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap); - int i, ret = 0; - - /* Some drivers use 1 byte or 0 byte reads as probes, which this - * driver doesn't support. These probes will always fail, so this - * hack makes them always succeed. If one knew how, it would of - * course be better to actually do the read. */ - if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1) - return 1; - - if (mutex_lock_interruptible(&i2c->fc->i2c_mutex)) - return -ERESTARTSYS; - - for (i = 0; i < num; i++) { - /* reading */ - if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) { - ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr, - msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len); - i++; /* skip the following message */ - } else /* writing */ - ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr, - msgs[i].buf[0], &msgs[i].buf[1], - msgs[i].len - 1); - if (ret < 0) { - err("i2c master_xfer failed"); - break; - } - } - - mutex_unlock(&i2c->fc->i2c_mutex); - - if (ret == 0) - ret = num; - return ret; -} - -static u32 flexcop_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm flexcop_algo = { - .master_xfer = flexcop_master_xfer, - .functionality = flexcop_i2c_func, -}; - -int flexcop_i2c_init(struct flexcop_device *fc) -{ - int ret; - - mutex_init(&fc->i2c_mutex); - - fc->fc_i2c_adap[0].fc = fc; - fc->fc_i2c_adap[1].fc = fc; - fc->fc_i2c_adap[2].fc = fc; - - fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD; - fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM; - fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER; - - strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod", - sizeof(fc->fc_i2c_adap[0].i2c_adap.name)); - strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom", - sizeof(fc->fc_i2c_adap[1].i2c_adap.name)); - strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner", - sizeof(fc->fc_i2c_adap[2].i2c_adap.name)); - - i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]); - i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]); - i2c_set_adapdata(&fc->fc_i2c_adap[2].i2c_adap, &fc->fc_i2c_adap[2]); - - fc->fc_i2c_adap[0].i2c_adap.class = - fc->fc_i2c_adap[1].i2c_adap.class = - fc->fc_i2c_adap[2].i2c_adap.class = I2C_CLASS_TV_DIGITAL; - fc->fc_i2c_adap[0].i2c_adap.algo = - fc->fc_i2c_adap[1].i2c_adap.algo = - fc->fc_i2c_adap[2].i2c_adap.algo = &flexcop_algo; - fc->fc_i2c_adap[0].i2c_adap.algo_data = - fc->fc_i2c_adap[1].i2c_adap.algo_data = - fc->fc_i2c_adap[2].i2c_adap.algo_data = NULL; - fc->fc_i2c_adap[0].i2c_adap.dev.parent = - fc->fc_i2c_adap[1].i2c_adap.dev.parent = - fc->fc_i2c_adap[2].i2c_adap.dev.parent = fc->dev; - - ret = i2c_add_adapter(&fc->fc_i2c_adap[0].i2c_adap); - if (ret < 0) - return ret; - - ret = i2c_add_adapter(&fc->fc_i2c_adap[1].i2c_adap); - if (ret < 0) - goto adap_1_failed; - - ret = i2c_add_adapter(&fc->fc_i2c_adap[2].i2c_adap); - if (ret < 0) - goto adap_2_failed; - - fc->init_state |= FC_STATE_I2C_INIT; - return 0; - -adap_2_failed: - i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); -adap_1_failed: - i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); - - return ret; -} - -void flexcop_i2c_exit(struct flexcop_device *fc) -{ - if (fc->init_state & FC_STATE_I2C_INIT) { - i2c_del_adapter(&fc->fc_i2c_adap[2].i2c_adap); - i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap); - i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap); - } - - fc->init_state &= ~FC_STATE_I2C_INIT; -} diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c deleted file mode 100644 index 93d20e56f90..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-misc.c - miscellaneous functions. - * - * see flexcop.c for copyright information. - */ -#include "flexcop.h" - -void flexcop_determine_revision(struct flexcop_device *fc) -{ - flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); - - switch (v.misc_204.Rev_N_sig_revision_hi) { - case 0x2: - deb_info("found a FlexCopII.\n"); - fc->rev = FLEXCOP_II; - break; - case 0x3: - deb_info("found a FlexCopIIb.\n"); - fc->rev = FLEXCOP_IIB; - break; - case 0x0: - deb_info("found a FlexCopIII.\n"); - fc->rev = FLEXCOP_III; - break; - default: - err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi); - break; - } - - if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps)) - deb_info("this FlexCop has the additional 32 hardware pid filter.\n"); - else - deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n"); - /* bus parts have to decide if hw pid filtering is used or not. */ -} - -static const char *flexcop_revision_names[] = { - "Unkown chip", - "FlexCopII", - "FlexCopIIb", - "FlexCopIII", -}; - -static const char *flexcop_device_names[] = { - "Unkown device", - "Air2PC/AirStar 2 DVB-T", - "Air2PC/AirStar 2 ATSC 1st generation", - "Air2PC/AirStar 2 ATSC 2nd generation", - "Sky2PC/SkyStar 2 DVB-S", - "Sky2PC/SkyStar 2 DVB-S (old version)", - "Cable2PC/CableStar 2 DVB-C", - "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", - "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", - "Sky2PC/SkyStar 2 DVB-S rev 2.8", -}; - -static const char *flexcop_bus_names[] = { - "USB", - "PCI", -}; - -void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const - char *suffix) -{ - info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix, - flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type], - flexcop_revision_names[fc->rev],suffix); -} - -void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num) -{ - flexcop_ibi_value v; - int i; - for (i = 0; i < num; i++) { - v = fc->read_ibi_reg(fc,reg+4*i); - deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw); - } - deb_rdump("\n"); -} -EXPORT_SYMBOL(flexcop_dump_reg); diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c deleted file mode 100644 index 5b30dfc7846..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-pci.c - covers the PCI part including DMA transfers. - * - * see flexcop.c for copyright information. - */ - -#define FC_LOG_PREFIX "flexcop-pci" -#include "flexcop-common.h" - -static int enable_pid_filtering = 1; -module_param(enable_pid_filtering, int, 0444); -MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); - -static int irq_chk_intv; -module_param(irq_chk_intv, int, 0644); -MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging)."); - -#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG -#define dprintk(level,args...) \ - do { if ((debug & level)) printk(args); } while (0) -#define DEBSTATUS "" -#else -#define dprintk(level,args...) -#define DEBSTATUS " (debugging is not enabled)" -#endif - -#define deb_info(args...) dprintk(0x01,args) -#define deb_reg(args...) dprintk(0x02,args) -#define deb_ts(args...) dprintk(0x04,args) -#define deb_irq(args...) dprintk(0x08,args) -#define deb_chk(args...) dprintk(0x10,args) - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); - -#define DRIVER_VERSION "0.1" -#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" -#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" - -struct flexcop_pci { - struct pci_dev *pdev; - -#define FC_PCI_INIT 0x01 -#define FC_PCI_DMA_INIT 0x02 - int init_state; - - void __iomem *io_mem; - u32 irq; -/* buffersize (at least for DMA1, need to be % 188 == 0, - * this logic is required */ -#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) -#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) - struct flexcop_dma dma[2]; - - int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ - u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ - int count; - - spinlock_t irq_lock; - - unsigned long last_irq; - - struct delayed_work irq_check_work; - - struct flexcop_device *fc_dev; -}; - -static int lastwreg,lastwval,lastrreg,lastrval; - -static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r) -{ - struct flexcop_pci *fc_pci = fc->bus_specific; - flexcop_ibi_value v; - v.raw = readl(fc_pci->io_mem + r); - - if (lastrreg != r || lastrval != v.raw) { - lastrreg = r; lastrval = v.raw; - deb_reg("new rd: %3x: %08x\n",r,v.raw); - } - - return v; -} - -static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v) -{ - struct flexcop_pci *fc_pci = fc->bus_specific; - - if (lastwreg != r || lastwval != v.raw) { - lastwreg = r; lastwval = v.raw; - deb_reg("new wr: %3x: %08x\n",r,v.raw); - } - - writel(v.raw, fc_pci->io_mem + r); - return 0; -} - -static void flexcop_pci_irq_check_work(struct work_struct *work) -{ - struct flexcop_pci *fc_pci = - container_of(work, struct flexcop_pci, irq_check_work.work); - struct flexcop_device *fc = fc_pci->fc_dev; - - flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); - - flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4); - - if (v.sram_dest_reg_714.net_ovflow_error) - deb_chk("sram net_ovflow_error\n"); - if (v.sram_dest_reg_714.media_ovflow_error) - deb_chk("sram media_ovflow_error\n"); - if (v.sram_dest_reg_714.cai_ovflow_error) - deb_chk("sram cai_ovflow_error\n"); - if (v.sram_dest_reg_714.cai_ovflow_error) - deb_chk("sram cai_ovflow_error\n"); - - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); -} - -/* When PID filtering is turned on, we use the timer IRQ, because small amounts - * of data need to be passed to the user space instantly as well. When PID - * filtering is turned off, we use the page-change-IRQ */ -static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) -{ - struct flexcop_pci *fc_pci = dev_id; - struct flexcop_device *fc = fc_pci->fc_dev; - unsigned long flags; - flexcop_ibi_value v; - irqreturn_t ret = IRQ_HANDLED; - - spin_lock_irqsave(&fc_pci->irq_lock,flags); - - v = fc->read_ibi_reg(fc,irq_20c); - - /* errors */ - if (v.irq_20c.Data_receiver_error) - deb_chk("data receiver error\n"); - if (v.irq_20c.Continuity_error_flag) - deb_chk("Contunuity error flag is set\n"); - if (v.irq_20c.LLC_SNAP_FLAG_set) - deb_chk("LLC_SNAP_FLAG_set is set\n"); - if (v.irq_20c.Transport_Error) - deb_chk("Transport error\n"); - - if ((fc_pci->count % 1000) == 0) - deb_chk("%d valid irq took place so far\n",fc_pci->count); - - if (v.irq_20c.DMA1_IRQ_Status == 1) { - if (fc_pci->active_dma1_addr == 0) - flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); - else - flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188); - - deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr); - fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr; - } else if (v.irq_20c.DMA1_Timer_Status == 1) { - /* for the timer IRQ we only can use buffer dmx feeding, because we don't have - * complete TS packets when reading from the DMA memory */ - dma_addr_t cur_addr = - fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; - u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; - - deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", - jiffies_to_usecs(jiffies - fc_pci->last_irq), - v.raw, (unsigned long long)cur_addr, cur_pos, - fc_pci->last_dma1_cur_pos); - fc_pci->last_irq = jiffies; - - /* buffer end was reached, restarted from the beginning - * pass the data from last_cur_pos to the buffer end to the demux - */ - if (cur_pos < fc_pci->last_dma1_cur_pos) { - deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos); - flexcop_pass_dmx_data(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, - (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos); - fc_pci->last_dma1_cur_pos = 0; - } - - if (cur_pos > fc_pci->last_dma1_cur_pos) { - deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos); - flexcop_pass_dmx_data(fc_pci->fc_dev, - fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, - cur_pos - fc_pci->last_dma1_cur_pos); - } - deb_irq("\n"); - - fc_pci->last_dma1_cur_pos = cur_pos; - fc_pci->count++; - } else { - deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw); - ret = IRQ_NONE; - } - - spin_unlock_irqrestore(&fc_pci->irq_lock,flags); - - return ret; -} - -static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) -{ - struct flexcop_pci *fc_pci = fc->bus_specific; - if (onoff) { - flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1); - flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2); - - flexcop_dma_config_timer(fc,FC_DMA_1,0); - - flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1); - deb_irq("DMA xfer enabled\n"); - - fc_pci->last_dma1_cur_pos = 0; - flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); - deb_irq("IRQ enabled\n"); - -// fc_pci->active_dma1_addr = 0; -// flexcop_dma_control_size_irq(fc,FC_DMA_1,1); - - if (irq_chk_intv > 0) - schedule_delayed_work(&fc_pci->irq_check_work, - msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv)); - } else { - if (irq_chk_intv > 0) - cancel_delayed_work(&fc_pci->irq_check_work); - - flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); - deb_irq("IRQ disabled\n"); - -// flexcop_dma_control_size_irq(fc,FC_DMA_1,0); - - flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0); - deb_irq("DMA xfer disabled\n"); - } - - return 0; -} - -static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) -{ - int ret; - if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) - return ret; - - if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) { - flexcop_dma_free(&fc_pci->dma[0]); - return ret; - } - - flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); - flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); - - fc_pci->init_state |= FC_PCI_DMA_INIT; - - return ret; -} - -static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci) -{ - if (fc_pci->init_state & FC_PCI_DMA_INIT) { - flexcop_dma_free(&fc_pci->dma[0]); - flexcop_dma_free(&fc_pci->dma[1]); - } - fc_pci->init_state &= ~FC_PCI_DMA_INIT; -} - -static int flexcop_pci_init(struct flexcop_pci *fc_pci) -{ - int ret; - u8 card_rev; - - pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev); - info("card revision %x", card_rev); - - if ((ret = pci_enable_device(fc_pci->pdev)) != 0) - return ret; - - pci_set_master(fc_pci->pdev); - - /* enable interrupts */ - // pci_write_config_dword(pdev, 0x6c, 0x8000); - - if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0) - goto err_pci_disable_device; - - fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800); - - if (!fc_pci->io_mem) { - err("cannot map io memory\n"); - ret = -EIO; - goto err_pci_release_regions; - } - - pci_set_drvdata(fc_pci->pdev, fc_pci); - spin_lock_init(&fc_pci->irq_lock); - if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr, - IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0) - goto err_pci_iounmap; - - - - fc_pci->init_state |= FC_PCI_INIT; - return ret; - -err_pci_iounmap: - pci_iounmap(fc_pci->pdev, fc_pci->io_mem); - pci_set_drvdata(fc_pci->pdev, NULL); -err_pci_release_regions: - pci_release_regions(fc_pci->pdev); -err_pci_disable_device: - pci_disable_device(fc_pci->pdev); - return ret; -} - -static void flexcop_pci_exit(struct flexcop_pci *fc_pci) -{ - if (fc_pci->init_state & FC_PCI_INIT) { - free_irq(fc_pci->pdev->irq, fc_pci); - pci_iounmap(fc_pci->pdev, fc_pci->io_mem); - pci_set_drvdata(fc_pci->pdev, NULL); - pci_release_regions(fc_pci->pdev); - pci_disable_device(fc_pci->pdev); - } - fc_pci->init_state &= ~FC_PCI_INIT; -} - - -static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct flexcop_device *fc; - struct flexcop_pci *fc_pci; - int ret = -ENOMEM; - - if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) { - err("out of memory\n"); - return -ENOMEM; - } - -/* general flexcop init */ - fc_pci = fc->bus_specific; - fc_pci->fc_dev = fc; - - fc->read_ibi_reg = flexcop_pci_read_ibi_reg; - fc->write_ibi_reg = flexcop_pci_write_ibi_reg; - fc->i2c_request = flexcop_i2c_request; - fc->get_mac_addr = flexcop_eeprom_check_mac_addr; - - fc->stream_control = flexcop_pci_stream_control; - - if (enable_pid_filtering) - info("will use the HW PID filter."); - else - info("will pass the complete TS to the demuxer."); - - fc->pid_filtering = enable_pid_filtering; - fc->bus_type = FC_PCI; - - fc->dev = &pdev->dev; - fc->owner = THIS_MODULE; - -/* bus specific part */ - fc_pci->pdev = pdev; - if ((ret = flexcop_pci_init(fc_pci)) != 0) - goto err_kfree; - -/* init flexcop */ - if ((ret = flexcop_device_initialize(fc)) != 0) - goto err_pci_exit; - -/* init dma */ - if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) - goto err_fc_exit; - - INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); - - return ret; - -err_fc_exit: - flexcop_device_exit(fc); -err_pci_exit: - flexcop_pci_exit(fc_pci); -err_kfree: - flexcop_device_kfree(fc); - return ret; -} - -/* in theory every _exit function should be called exactly two times, - * here and in the bail-out-part of the _init-function - */ -static void flexcop_pci_remove(struct pci_dev *pdev) -{ - struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); - - flexcop_pci_dma_exit(fc_pci); - flexcop_device_exit(fc_pci->fc_dev); - flexcop_pci_exit(fc_pci); - flexcop_device_kfree(fc_pci->fc_dev); -} - -static struct pci_device_id flexcop_pci_tbl[] = { - { PCI_DEVICE(0x13d0, 0x2103) }, -/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */ - { }, -}; - -MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl); - -static struct pci_driver flexcop_pci_driver = { - .name = "b2c2_flexcop_pci", - .id_table = flexcop_pci_tbl, - .probe = flexcop_pci_probe, - .remove = flexcop_pci_remove, -}; - -static int __init flexcop_pci_module_init(void) -{ - return pci_register_driver(&flexcop_pci_driver); -} - -static void __exit flexcop_pci_module_exit(void) -{ - pci_unregister_driver(&flexcop_pci_driver); -} - -module_init(flexcop_pci_module_init); -module_exit(flexcop_pci_module_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_NAME); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h deleted file mode 100644 index 7599fccc1a5..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII - * - * see flexcop.c for copyright information. - */ -#ifndef __FLEXCOP_REG_H__ -#define __FLEXCOP_REG_H__ - - -typedef enum { - FLEXCOP_UNK = 0, - FLEXCOP_II, - FLEXCOP_IIB, - FLEXCOP_III, -} flexcop_revision_t; - -typedef enum { - FC_UNK = 0, - FC_AIR_DVB, - FC_AIR_ATSC1, - FC_AIR_ATSC2, - FC_SKY, - FC_SKY_OLD, - FC_CABLE, - FC_AIR_ATSC3, - FC_SKY_REV27, - FC_SKY_REV28, -} flexcop_device_type_t; - -typedef enum { - FC_USB = 0, - FC_PCI, -} flexcop_bus_t; - -/* FlexCop IBI Registers */ -#if defined(__LITTLE_ENDIAN) - #include "flexcop_ibi_value_le.h" -#else -#if defined(__BIG_ENDIAN) - #include "flexcop_ibi_value_be.h" -#else - #error no endian defined -#endif -#endif - -#define fc_data_Tag_ID_DVB 0x3e -#define fc_data_Tag_ID_ATSC 0x3f -#define fc_data_Tag_ID_IDSB 0x8b - -#define fc_key_code_default 0x1 -#define fc_key_code_even 0x2 -#define fc_key_code_odd 0x3 - -extern flexcop_ibi_value ibi_zero; - -typedef enum { - FC_I2C_PORT_DEMOD = 1, - FC_I2C_PORT_EEPROM = 2, - FC_I2C_PORT_TUNER = 3, -} flexcop_i2c_port_t; - -typedef enum { - FC_WRITE = 0, - FC_READ = 1, -} flexcop_access_op_t; - -typedef enum { - FC_SRAM_DEST_NET = 1, - FC_SRAM_DEST_CAI = 2, - FC_SRAM_DEST_CAO = 4, - FC_SRAM_DEST_MEDIA = 8 -} flexcop_sram_dest_t; - -typedef enum { - FC_SRAM_DEST_TARGET_WAN_USB = 0, - FC_SRAM_DEST_TARGET_DMA1 = 1, - FC_SRAM_DEST_TARGET_DMA2 = 2, - FC_SRAM_DEST_TARGET_FC3_CA = 3 -} flexcop_sram_dest_target_t; - -typedef enum { - FC_SRAM_2_32KB = 0, /* 64KB */ - FC_SRAM_1_32KB = 1, /* 32KB - default fow FCII */ - FC_SRAM_1_128KB = 2, /* 128KB */ - FC_SRAM_1_48KB = 3, /* 48KB - default for FCIII */ -} flexcop_sram_type_t; - -typedef enum { - FC_WAN_SPEED_4MBITS = 0, - FC_WAN_SPEED_8MBITS = 1, - FC_WAN_SPEED_12MBITS = 2, - FC_WAN_SPEED_16MBITS = 3, -} flexcop_wan_speed_t; - -typedef enum { - FC_DMA_1 = 1, - FC_DMA_2 = 2, -} flexcop_dma_index_t; - -typedef enum { - FC_DMA_SUBADDR_0 = 1, - FC_DMA_SUBADDR_1 = 2, -} flexcop_dma_addr_index_t; - -/* names of the particular registers */ -typedef enum { - dma1_000 = 0x000, - dma1_004 = 0x004, - dma1_008 = 0x008, - dma1_00c = 0x00c, - dma2_010 = 0x010, - dma2_014 = 0x014, - dma2_018 = 0x018, - dma2_01c = 0x01c, - - tw_sm_c_100 = 0x100, - tw_sm_c_104 = 0x104, - tw_sm_c_108 = 0x108, - tw_sm_c_10c = 0x10c, - tw_sm_c_110 = 0x110, - - lnb_switch_freq_200 = 0x200, - misc_204 = 0x204, - ctrl_208 = 0x208, - irq_20c = 0x20c, - sw_reset_210 = 0x210, - misc_214 = 0x214, - mbox_v8_to_host_218 = 0x218, - mbox_host_to_v8_21c = 0x21c, - - pid_filter_300 = 0x300, - pid_filter_304 = 0x304, - pid_filter_308 = 0x308, - pid_filter_30c = 0x30c, - index_reg_310 = 0x310, - pid_n_reg_314 = 0x314, - mac_low_reg_318 = 0x318, - mac_high_reg_31c = 0x31c, - - data_tag_400 = 0x400, - card_id_408 = 0x408, - card_id_40c = 0x40c, - mac_address_418 = 0x418, - mac_address_41c = 0x41c, - - ci_600 = 0x600, - pi_604 = 0x604, - pi_608 = 0x608, - dvb_reg_60c = 0x60c, - - sram_ctrl_reg_700 = 0x700, - net_buf_reg_704 = 0x704, - cai_buf_reg_708 = 0x708, - cao_buf_reg_70c = 0x70c, - media_buf_reg_710 = 0x710, - sram_dest_reg_714 = 0x714, - net_buf_reg_718 = 0x718, - wan_ctrl_reg_71c = 0x71c, -} flexcop_ibi_register; - -#define flexcop_set_ibi_value(reg,attr,val) { \ - flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \ - v.reg.attr = val; \ - fc->write_ibi_reg(fc,reg,v); \ -} - -#endif diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c deleted file mode 100644 index cda69528548..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-sram.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-sram.c - functions for controlling the SRAM. - * - * see flexcop.c for copyright information. - */ -#include "flexcop.h" - -static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type) -{ - flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type); -} - -int flexcop_sram_init(struct flexcop_device *fc) -{ - switch (fc->rev) { - case FLEXCOP_II: - case FLEXCOP_IIB: - flexcop_sram_set_chip(fc,FC_SRAM_1_32KB); - break; - case FLEXCOP_III: - flexcop_sram_set_chip(fc,FC_SRAM_1_48KB); - break; - default: - return -EINVAL; - } - return 0; -} - -int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target) -{ - flexcop_ibi_value v; - - v = fc->read_ibi_reg(fc,sram_dest_reg_714); - - if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) { - err("SRAM destination target to available on FlexCopII(b)\n"); - return -EINVAL; - } - - deb_sram("sram dest: %x target: %x\n",dest, target); - - if (dest & FC_SRAM_DEST_NET) - v.sram_dest_reg_714.NET_Dest = target; - if (dest & FC_SRAM_DEST_CAI) - v.sram_dest_reg_714.CAI_Dest = target; - if (dest & FC_SRAM_DEST_CAO) - v.sram_dest_reg_714.CAO_Dest = target; - if (dest & FC_SRAM_DEST_MEDIA) - v.sram_dest_reg_714.MEDIA_Dest = target; - - fc->write_ibi_reg(fc,sram_dest_reg_714,v); - udelay(1000); /* TODO delay really necessary */ - - return 0; -} -EXPORT_SYMBOL(flexcop_sram_set_dest); - -void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s) -{ - flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s); -} -EXPORT_SYMBOL(flexcop_wan_set_speed); - -void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill) -{ - flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); - v.sram_dest_reg_714.ctrl_usb_wan = usb_wan; - v.sram_dest_reg_714.ctrl_sramdma = sramdma; - v.sram_dest_reg_714.ctrl_maximumfill = maximumfill; - fc->write_ibi_reg(fc,sram_dest_reg_714,v); -} -EXPORT_SYMBOL(flexcop_sram_ctrl); - -#if 0 -static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len) -{ - int i, retries; - u32 command; - - for (i = 0; i < len; i++) { - command = bank | addr | 0x04000000 | (*buf << 0x10); - - retries = 2; - - while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { - mdelay(1); - retries--; - }; - - if (retries == 0) - printk("%s: SRAM timeout\n", __func__); - - write_reg_dw(adapter, 0x700, command); - - buf++; - addr++; - } -} - -static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len) -{ - int i, retries; - u32 command, value; - - for (i = 0; i < len; i++) { - command = bank | addr | 0x04008000; - - retries = 10000; - - while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { - mdelay(1); - retries--; - }; - - if (retries == 0) - printk("%s: SRAM timeout\n", __func__); - - write_reg_dw(adapter, 0x700, command); - - retries = 10000; - - while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { - mdelay(1); - retries--; - }; - - if (retries == 0) - printk("%s: SRAM timeout\n", __func__); - - value = read_reg_dw(adapter, 0x700) >> 0x10; - - *buf = (value & 0xff); - - addr++; - buf++; - } -} - -static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) -{ - u32 bank; - - bank = 0; - - if (adapter->dw_sram_type == 0x20000) { - bank = (addr & 0x18000) << 0x0d; - } - - if (adapter->dw_sram_type == 0x00000) { - if ((addr >> 0x0f) == 0) - bank = 0x20000000; - else - bank = 0x10000000; - } - - flex_sram_write(adapter, bank, addr & 0x7fff, buf, len); -} - -static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) -{ - u32 bank; - - bank = 0; - - if (adapter->dw_sram_type == 0x20000) { - bank = (addr & 0x18000) << 0x0d; - } - - if (adapter->dw_sram_type == 0x00000) { - if ((addr >> 0x0f) == 0) - bank = 0x20000000; - else - bank = 0x10000000; - } - - flex_sram_read(adapter, bank, addr & 0x7fff, buf, len); -} - -static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len) -{ - u32 length; - - while (len != 0) { - length = len; - - // check if the address range belongs to the same - // 32K memory chip. If not, the data is read from - // one chip at a time. - if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { - length = (((addr >> 0x0f) + 1) << 0x0f) - addr; - } - - sram_read_chunk(adapter, addr, buf, length); - - addr = addr + length; - buf = buf + length; - len = len - length; - } -} - -static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len) -{ - u32 length; - - while (len != 0) { - length = len; - - // check if the address range belongs to the same - // 32K memory chip. If not, the data is written to - // one chip at a time. - if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { - length = (((addr >> 0x0f) + 1) << 0x0f) - addr; - } - - sram_write_chunk(adapter, addr, buf, length); - - addr = addr + length; - buf = buf + length; - len = len - length; - } -} - -static void sram_set_size(struct adapter *adapter, u32 mask) -{ - write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c)))); -} - -static void sram_init(struct adapter *adapter) -{ - u32 tmp; - - tmp = read_reg_dw(adapter, 0x71c); - - write_reg_dw(adapter, 0x71c, 1); - - if (read_reg_dw(adapter, 0x71c) != 0) { - write_reg_dw(adapter, 0x71c, tmp); - - adapter->dw_sram_type = tmp & 0x30000; - - ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); - - } else { - - adapter->dw_sram_type = 0x10000; - - ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type); - } - - /* return value is never used? */ -/* return adapter->dw_sram_type; */ -} - -static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) -{ - u8 tmp1, tmp2; - - dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr); - - sram_set_size(adapter, mask); - sram_init(adapter); - - tmp2 = 0xa5; - tmp1 = 0x4f; - - sram_write(adapter, addr, &tmp2, 1); - sram_write(adapter, addr + 4, &tmp1, 1); - - tmp2 = 0; - - mdelay(20); - - sram_read(adapter, addr, &tmp2, 1); - sram_read(adapter, addr, &tmp2, 1); - - dprintk("%s: wrote 0xa5, read 0x%2x\n", __func__, tmp2); - - if (tmp2 != 0xa5) - return 0; - - tmp2 = 0x5a; - tmp1 = 0xf4; - - sram_write(adapter, addr, &tmp2, 1); - sram_write(adapter, addr + 4, &tmp1, 1); - - tmp2 = 0; - - mdelay(20); - - sram_read(adapter, addr, &tmp2, 1); - sram_read(adapter, addr, &tmp2, 1); - - dprintk("%s: wrote 0x5a, read 0x%2x\n", __func__, tmp2); - - if (tmp2 != 0x5a) - return 0; - - return 1; -} - -static u32 sram_length(struct adapter *adapter) -{ - if (adapter->dw_sram_type == 0x10000) - return 32768; // 32K - if (adapter->dw_sram_type == 0x00000) - return 65536; // 64K - if (adapter->dw_sram_type == 0x20000) - return 131072; // 128K - - return 32768; // 32K -} - -/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory. - - for 128K there are 4x32K chips at bank 0,1,2,3. - - for 64K there are 2x32K chips at bank 1,2. - - for 32K there is one 32K chip at bank 0. - - FlexCop works only with one bank at a time. The bank is selected - by bits 28-29 of the 0x700 register. - - bank 0 covers addresses 0x00000-0x07fff - bank 1 covers addresses 0x08000-0x0ffff - bank 2 covers addresses 0x10000-0x17fff - bank 3 covers addresses 0x18000-0x1ffff -*/ - -static int flexcop_sram_detect(struct flexcop_device *fc) -{ - flexcop_ibi_value r208,r71c_0,vr71c_1; - - r208 = fc->read_ibi_reg(fc, ctrl_208); - fc->write_ibi_reg(fc, ctrl_208, ibi_zero); - - r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c); - - write_reg_dw(adapter, 0x71c, 1); - - tmp3 = read_reg_dw(adapter, 0x71c); - - dprintk("%s: tmp3 = %x\n", __func__, tmp3); - - write_reg_dw(adapter, 0x71c, tmp2); - - // check for internal SRAM ??? - tmp3--; - if (tmp3 != 0) { - sram_set_size(adapter, 0x10000); - sram_init(adapter); - write_reg_dw(adapter, 0x208, tmp); - - dprintk("%s: sram size = 32K\n", __func__); - - return 32; - } - - if (sram_test_location(adapter, 0x20000, 0x18000) != 0) { - sram_set_size(adapter, 0x20000); - sram_init(adapter); - write_reg_dw(adapter, 0x208, tmp); - - dprintk("%s: sram size = 128K\n", __func__); - - return 128; - } - - if (sram_test_location(adapter, 0x00000, 0x10000) != 0) { - sram_set_size(adapter, 0x00000); - sram_init(adapter); - write_reg_dw(adapter, 0x208, tmp); - - dprintk("%s: sram size = 64K\n", __func__); - - return 64; - } - - if (sram_test_location(adapter, 0x10000, 0x00000) != 0) { - sram_set_size(adapter, 0x10000); - sram_init(adapter); - write_reg_dw(adapter, 0x208, tmp); - - dprintk("%s: sram size = 32K\n", __func__); - - return 32; - } - - sram_set_size(adapter, 0x10000); - sram_init(adapter); - write_reg_dw(adapter, 0x208, tmp); - - dprintk("%s: SRAM detection failed. Set to 32K \n", __func__); - - return 0; -} - -static void sll_detect_sram_size(struct adapter *adapter) -{ - sram_detect_for_flex2(adapter); -} - -#endif diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c deleted file mode 100644 index ae0d76a5d51..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ /dev/null @@ -1,578 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop-usb.c - covers the USB part. - * - * see flexcop.c for copyright information. - */ - -#define FC_LOG_PREFIX "flexcop_usb" -#include "flexcop-usb.h" -#include "flexcop-common.h" - -/* Version information */ -#define DRIVER_VERSION "0.1" -#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver" -#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" - -/* debug */ -#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG -#define dprintk(level,args...) \ - do { if ((debug & level)) { printk(args); } } while (0) -#define debug_dump(b,l,method) {\ - int i; \ - for (i = 0; i < l; i++) method("%02x ", b[i]); \ - method("\n");\ -} - -#define DEBSTATUS "" -#else -#define dprintk(level,args...) -#define debug_dump(b,l,method) -#define DEBSTATUS " (debugging is not enabled)" -#endif - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); -#undef DEBSTATUS - -#define deb_info(args...) dprintk(0x01,args) -#define deb_ts(args...) dprintk(0x02,args) -#define deb_ctrl(args...) dprintk(0x04,args) -#define deb_i2c(args...) dprintk(0x08,args) -#define deb_v8(args...) dprintk(0x10,args) - -/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits - * in the IBI address, to make the V8 code simpler. - * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used) - * in general: 0000 0HHH 000L LL00 - * IBI ADDRESS FORMAT: RHHH BLLL - * - * where R is the read(1)/write(0) bit, B is the busy bit - * and HHH and LLL are the two sets of three bits from the PCI address. - */ -#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) -#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) - -/* - * DKT 020228 - * - forget about this VENDOR_BUFFER_SIZE, read and write register - * deal with DWORD or 4 bytes, that should be should from now on - * - from now on, we don't support anything older than firm 1.00 - * I eliminated the write register as a 2 trip of writing hi word and lo word - * and force this to write only 4 bytes at a time. - * NOTE: this should work with all the firmware from 1.00 and newer - */ -static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read) -{ - struct flexcop_usb *fc_usb = fc->bus_specific; - u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG; - u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR; - u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0); - - int len = usb_control_msg(fc_usb->udev, - read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT, - request, - request_type, /* 0xc0 read or 0x40 write*/ - wAddress, - 0, - val, - sizeof(u32), - B2C2_WAIT_FOR_OPERATION_RDW * HZ); - - if (len != sizeof(u32)) { - err("error while %s dword from %d (%d).",read ? "reading" : "writing", - wAddress,wRegOffsPCI); - return -EIO; - } - return 0; -} - -/* - * DKT 010817 - add support for V8 memory read/write and flash update - */ -static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, - flexcop_usb_request_t req, u8 page, u16 wAddress, - u8 *pbBuffer,u32 buflen) -{ -// u8 dwRequestType; - u8 request_type = USB_TYPE_VENDOR; - u16 wIndex; - int nWaitTime,pipe,len; - - wIndex = page << 8; - - switch (req) { - case B2C2_USB_READ_V8_MEM: - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; - request_type |= USB_DIR_IN; -// dwRequestType = (u8) RTYPE_READ_V8_MEMORY; - pipe = B2C2_USB_CTRL_PIPE_IN; - break; - case B2C2_USB_WRITE_V8_MEM: - wIndex |= pbBuffer[0]; - request_type |= USB_DIR_OUT; - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; -// dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY; - pipe = B2C2_USB_CTRL_PIPE_OUT; - break; - case B2C2_USB_FLASH_BLOCK: - request_type |= USB_DIR_OUT; - nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; -// dwRequestType = (u8) RTYPE_WRITE_V8_FLASH; - pipe = B2C2_USB_CTRL_PIPE_OUT; - break; - default: - deb_info("unsupported request for v8_mem_req %x.\n",req); - return -EINVAL; - } - deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req, - wAddress,wIndex,buflen); - - len = usb_control_msg(fc_usb->udev,pipe, - req, - request_type, - wAddress, - wIndex, - pbBuffer, - buflen, - nWaitTime * HZ); - - debug_dump(pbBuffer,len,deb_v8); - - return len == buflen ? 0 : -EIO; -} - -#define bytes_left_to_read_on_page(paddr,buflen) \ - ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ - ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) - -static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req, - flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len) -{ - int i,ret = 0; - u16 wMax; - u32 pagechunk = 0; - - switch(req) { - case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break; - case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break; - case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break; - default: - return -EINVAL; - break; - } - for (i = 0; i < len;) { - pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len); - deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended)); - if ((ret = flexcop_usb_v8_memory_req(fc_usb,req, - page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */ - (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended), - &buf[i],pagechunk)) < 0) - return ret; - - addr += pagechunk; - len -= pagechunk; - } - return 0; -} - -static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended) -{ - return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM, - V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6); -} - -#if 0 -static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set, - flexcop_usb_utility_function_t func, u8 extra, u16 wIndex, - u16 buflen, u8 *pvBuffer) -{ - u16 wValue; - u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR; -// u8 dwRequestType = (u8) RTYPE_GENERIC, - int nWaitTime = 2, - pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, - len; - - wValue = (func << 8) | extra; - - len = usb_control_msg(fc_usb->udev,pipe, - B2C2_USB_UTILITY, - request_type, - wValue, - wIndex, - pvBuffer, - buflen, - nWaitTime * HZ); - return len == buflen ? 0 : -EIO; -} -#endif - -/* usb i2c stuff */ -static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, - flexcop_usb_request_t req, flexcop_usb_i2c_function_t func, - u8 chipaddr, u8 addr, u8 *buf, u8 buflen) -{ - struct flexcop_usb *fc_usb = i2c->fc->bus_specific; - u16 wValue, wIndex; - int nWaitTime,pipe,len; -// u8 dwRequestType; - u8 request_type = USB_TYPE_VENDOR; - - switch (func) { - case USB_FUNC_I2C_WRITE: - case USB_FUNC_I2C_MULTIWRITE: - case USB_FUNC_I2C_REPEATWRITE: - /* DKT 020208 - add this to support special case of DiSEqC */ - case USB_FUNC_I2C_CHECKWRITE: - pipe = B2C2_USB_CTRL_PIPE_OUT; - nWaitTime = 2; -// dwRequestType = (u8) RTYPE_GENERIC; - request_type |= USB_DIR_OUT; - break; - case USB_FUNC_I2C_READ: - case USB_FUNC_I2C_REPEATREAD: - pipe = B2C2_USB_CTRL_PIPE_IN; - nWaitTime = 2; -// dwRequestType = (u8) RTYPE_GENERIC; - request_type |= USB_DIR_IN; - break; - default: - deb_info("unsupported function for i2c_req %x\n",func); - return -EINVAL; - } - wValue = (func << 8) | (i2c->port << 4); - wIndex = (chipaddr << 8 ) | addr; - - deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, - wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8); - - len = usb_control_msg(fc_usb->udev,pipe, - req, - request_type, - wValue, - wIndex, - buf, - buflen, - nWaitTime * HZ); - - return len == buflen ? 0 : -EREMOTEIO; -} - -/* actual bus specific access functions, make sure prototype are/will be equal to pci */ -static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg) -{ - flexcop_ibi_value val; - val.raw = 0; - flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1); - return val; -} - -static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val) -{ - return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0); -} - -static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c, - flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len) -{ - if (op == FC_READ) - return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, - USB_FUNC_I2C_READ, chipaddr, addr, buf, len); - else - return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST, - USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len); -} - -static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) -{ - u8 *b; - int l; - - deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length); - - if (fc_usb->tmp_buffer_length > 0) { - memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length); - fc_usb->tmp_buffer_length += buffer_length; - b = fc_usb->tmp_buffer; - l = fc_usb->tmp_buffer_length; - } else { - b=buffer; - l=buffer_length; - } - - while (l >= 190) { - if (*b == 0xff) - switch (*(b+1) & 0x03) { - case 0x01: /* media packet */ - if ( *(b+2) == 0x47 ) - flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1); - else - deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) ); - - b += 190; - l -= 190; - break; - default: - deb_ts("wrong packet type\n"); - l = 0; - break; - } - else { - deb_ts("wrong header\n"); - l = 0; - } - } - - if (l>0) - memcpy(fc_usb->tmp_buffer, b, l); - fc_usb->tmp_buffer_length = l; -} - -static void flexcop_usb_urb_complete(struct urb *urb) -{ - struct flexcop_usb *fc_usb = urb->context; - int i; - - if (urb->actual_length > 0) - deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length); - - for (i = 0; i < urb->number_of_packets; i++) { - if (urb->iso_frame_desc[i].status < 0) { - err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status); - } else - if (urb->iso_frame_desc[i].actual_length > 0) { - deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); - - flexcop_usb_process_frame(fc_usb, - urb->transfer_buffer + urb->iso_frame_desc[i].offset, - urb->iso_frame_desc[i].actual_length); - } - urb->iso_frame_desc[i].status = 0; - urb->iso_frame_desc[i].actual_length = 0; - } - - usb_submit_urb(urb,GFP_ATOMIC); -} - -static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff) -{ - /* submit/kill iso packets */ - return 0; -} - -static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) -{ - int i; - for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) - if (fc_usb->iso_urb[i] != NULL) { - deb_ts("unlinking/killing urb no. %d\n",i); - usb_kill_urb(fc_usb->iso_urb[i]); - usb_free_urb(fc_usb->iso_urb[i]); - } - - if (fc_usb->iso_buffer != NULL) - pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr); -} - -static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) -{ - u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); - int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; - int buffer_offset = 0; - - deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n", - B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize); - - fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr); - if (fc_usb->iso_buffer == NULL) - return -ENOMEM; - memset(fc_usb->iso_buffer, 0, bufsize); - fc_usb->buffer_size = bufsize; - - /* creating iso urbs */ - for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) - if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) { - ret = -ENOMEM; - goto urb_error; - } - /* initialising and submitting iso urbs */ - for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { - int frame_offset = 0; - struct urb *urb = fc_usb->iso_urb[i]; - deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset); - - urb->dev = fc_usb->udev; - urb->context = fc_usb; - urb->complete = flexcop_usb_urb_complete; - urb->pipe = B2C2_USB_DATA_PIPE; - urb->transfer_flags = URB_ISO_ASAP; - urb->interval = 1; - urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO; - urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO; - urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset; - - buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO; - for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) { - deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset); - urb->iso_frame_desc[j].offset = frame_offset; - urb->iso_frame_desc[j].length = frame_size; - frame_offset += frame_size; - } - - if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) { - err("submitting urb %d failed with %d.",i,ret); - goto urb_error; - } - deb_ts("submitted urb no. %d.\n",i); - } - -/* SRAM */ - - flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET | - FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB); - flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); - flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); - - return 0; - -urb_error: - flexcop_usb_transfer_exit(fc_usb); - return ret; -} - -static int flexcop_usb_init(struct flexcop_usb *fc_usb) -{ - /* use the alternate setting with the larges buffer */ - usb_set_interface(fc_usb->udev,0,1); - switch (fc_usb->udev->speed) { - case USB_SPEED_LOW: - err("cannot handle USB speed because it is to sLOW."); - return -ENODEV; - break; - case USB_SPEED_FULL: - info("running at FULL speed."); - break; - case USB_SPEED_HIGH: - info("running at HIGH speed."); - break; - case USB_SPEED_UNKNOWN: /* fall through */ - default: - err("cannot handle USB speed because it is unkown."); - return -ENODEV; - } - usb_set_intfdata(fc_usb->uintf, fc_usb); - return 0; -} - -static void flexcop_usb_exit(struct flexcop_usb *fc_usb) -{ - usb_set_intfdata(fc_usb->uintf, NULL); -} - -static int flexcop_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct flexcop_usb *fc_usb = NULL; - struct flexcop_device *fc = NULL; - int ret; - - if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) { - err("out of memory\n"); - return -ENOMEM; - } - -/* general flexcop init */ - fc_usb = fc->bus_specific; - fc_usb->fc_dev = fc; - - fc->read_ibi_reg = flexcop_usb_read_ibi_reg; - fc->write_ibi_reg = flexcop_usb_write_ibi_reg; - fc->i2c_request = flexcop_usb_i2c_request; - fc->get_mac_addr = flexcop_usb_get_mac_addr; - - fc->stream_control = flexcop_usb_stream_control; - - fc->pid_filtering = 1; - fc->bus_type = FC_USB; - - fc->dev = &udev->dev; - fc->owner = THIS_MODULE; - -/* bus specific part */ - fc_usb->udev = udev; - fc_usb->uintf = intf; - if ((ret = flexcop_usb_init(fc_usb)) != 0) - goto err_kfree; - -/* init flexcop */ - if ((ret = flexcop_device_initialize(fc)) != 0) - goto err_usb_exit; - -/* xfer init */ - if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0) - goto err_fc_exit; - - info("%s successfully initialized and connected.",DRIVER_NAME); - return 0; - -err_fc_exit: - flexcop_device_exit(fc); -err_usb_exit: - flexcop_usb_exit(fc_usb); -err_kfree: - flexcop_device_kfree(fc); - return ret; -} - -static void flexcop_usb_disconnect(struct usb_interface *intf) -{ - struct flexcop_usb *fc_usb = usb_get_intfdata(intf); - flexcop_usb_transfer_exit(fc_usb); - flexcop_device_exit(fc_usb->fc_dev); - flexcop_usb_exit(fc_usb); - flexcop_device_kfree(fc_usb->fc_dev); - info("%s successfully deinitialized and disconnected.",DRIVER_NAME); -} - -static struct usb_device_id flexcop_usb_table [] = { - { USB_DEVICE(0x0af7, 0x0101) }, - { } -}; -MODULE_DEVICE_TABLE (usb, flexcop_usb_table); - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver flexcop_usb_driver = { - .name = "b2c2_flexcop_usb", - .probe = flexcop_usb_probe, - .disconnect = flexcop_usb_disconnect, - .id_table = flexcop_usb_table, -}; - -/* module stuff */ -static int __init flexcop_usb_module_init(void) -{ - int result; - if ((result = usb_register(&flexcop_usb_driver))) { - err("usb_register failed. (%d)",result); - return result; - } - - return 0; -} - -static void __exit flexcop_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&flexcop_usb_driver); -} - -module_init(flexcop_usb_module_init); -module_exit(flexcop_usb_module_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_NAME); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h deleted file mode 100644 index 630e647a2ca..00000000000 --- a/drivers/media/dvb/b2c2/flexcop-usb.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef __FLEXCOP_USB_H_INCLUDED__ -#define __FLEXCOP_USB_H_INCLUDED__ - -#include <linux/usb.h> - -/* transfer parameters */ -#define B2C2_USB_FRAMES_PER_ISO 4 -#define B2C2_USB_NUM_ISO_URB 4 - -#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0) -#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0) -#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81) - -struct flexcop_usb { - struct usb_device *udev; - struct usb_interface *uintf; - - u8 *iso_buffer; - int buffer_size; - dma_addr_t dma_addr; - struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; - - struct flexcop_device *fc_dev; - - u8 tmp_buffer[1023+190]; - int tmp_buffer_length; -}; - -#if 0 -/* request types TODO What is its use?*/ -typedef enum { - -/* something is wrong with this part - RTYPE_READ_DW = (1 << 6), - RTYPE_WRITE_DW_1 = (3 << 6), - RTYPE_READ_V8_MEMORY = (6 << 6), - RTYPE_WRITE_V8_MEMORY = (7 << 6), - RTYPE_WRITE_V8_FLASH = (8 << 6), - RTYPE_GENERIC = (9 << 6), -*/ -} flexcop_usb_request_type_t; -#endif - -/* request */ -typedef enum { - B2C2_USB_WRITE_V8_MEM = 0x04, - B2C2_USB_READ_V8_MEM = 0x05, - B2C2_USB_READ_REG = 0x08, - B2C2_USB_WRITE_REG = 0x0A, -/* B2C2_USB_WRITEREGLO = 0x0A, */ - B2C2_USB_WRITEREGHI = 0x0B, - B2C2_USB_FLASH_BLOCK = 0x10, - B2C2_USB_I2C_REQUEST = 0x11, - B2C2_USB_UTILITY = 0x12, -} flexcop_usb_request_t; - -/* function definition for I2C_REQUEST */ -typedef enum { - USB_FUNC_I2C_WRITE = 0x01, - USB_FUNC_I2C_MULTIWRITE = 0x02, - USB_FUNC_I2C_READ = 0x03, - USB_FUNC_I2C_REPEATWRITE = 0x04, - USB_FUNC_GET_DESCRIPTOR = 0x05, - USB_FUNC_I2C_REPEATREAD = 0x06, -/* DKT 020208 - add this to support special case of DiSEqC */ - USB_FUNC_I2C_CHECKWRITE = 0x07, - USB_FUNC_I2C_CHECKRESULT = 0x08, -} flexcop_usb_i2c_function_t; - -/* - * function definition for UTILITY request 0x12 - * DKT 020304 - new utility function - */ -typedef enum { - UTILITY_SET_FILTER = 0x01, - UTILITY_DATA_ENABLE = 0x02, - UTILITY_FLEX_MULTIWRITE = 0x03, - UTILITY_SET_BUFFER_SIZE = 0x04, - UTILITY_FLEX_OPERATOR = 0x05, - UTILITY_FLEX_RESET300_START = 0x06, - UTILITY_FLEX_RESET300_STOP = 0x07, - UTILITY_FLEX_RESET300 = 0x08, - UTILITY_SET_ISO_SIZE = 0x09, - UTILITY_DATA_RESET = 0x0A, - UTILITY_GET_DATA_STATUS = 0x10, - UTILITY_GET_V8_REG = 0x11, -/* DKT 020326 - add function for v1.14 */ - UTILITY_SRAM_WRITE = 0x12, - UTILITY_SRAM_READ = 0x13, - UTILITY_SRAM_TESTFILL = 0x14, - UTILITY_SRAM_TESTSET = 0x15, - UTILITY_SRAM_TESTVERIFY = 0x16, -} flexcop_usb_utility_function_t; - -#define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */ -#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */ -#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */ - -#define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */ -#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */ -#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */ - -typedef enum { - V8_MEMORY_PAGE_DVB_CI = 0x20, - V8_MEMORY_PAGE_DVB_DS = 0x40, - V8_MEMORY_PAGE_MULTI2 = 0x60, - V8_MEMORY_PAGE_FLASH = 0x80 -} flexcop_usb_mem_page_t; - -#define V8_MEMORY_EXTENDED (1 << 15) - -#define USB_MEM_READ_MAX 32 -#define USB_MEM_WRITE_MAX 1 -#define USB_FLASH_MAX 8 - -#define V8_MEMORY_PAGE_SIZE 0x8000 // 32K -#define V8_MEMORY_PAGE_MASK 0x7FFF - -#endif diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c deleted file mode 100644 index 676413a915b..00000000000 --- a/drivers/media/dvb/b2c2/flexcop.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de> - * - * based on the skystar2-driver - * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc - * - * Acknowledgements: - * John Jurrius from BBTI, Inc. for extensive support with - * code examples and data books - * - * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting) - * - * Contributions to the skystar2-driver have been done by - * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes) - * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code) - * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering) - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include "flexcop.h" - -#define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip" -#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de" - -#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG -#define DEBSTATUS "" -#else -#define DEBSTATUS " (debugging is not enabled)" -#endif - -int b2c2_flexcop_debug; -module_param_named(debug, b2c2_flexcop_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS); -#undef DEBSTATUS - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -/* global zero for ibi values */ -flexcop_ibi_value ibi_zero; - -static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct flexcop_device *fc = dvbdmxfeed->demux->priv; - return flexcop_pid_feed_control(fc,dvbdmxfeed,1); -} - -static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct flexcop_device *fc = dvbdmxfeed->demux->priv; - return flexcop_pid_feed_control(fc,dvbdmxfeed,0); -} - -static int flexcop_dvb_init(struct flexcop_device *fc) -{ - int ret = dvb_register_adapter(&fc->dvb_adapter, - "FlexCop Digital TV device", fc->owner, - fc->dev, adapter_nr); - if (ret < 0) { - err("error registering DVB adapter"); - return ret; - } - fc->dvb_adapter.priv = fc; - - fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); - fc->demux.priv = fc; - - fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED; - - fc->demux.start_feed = flexcop_dvb_start_feed; - fc->demux.stop_feed = flexcop_dvb_stop_feed; - fc->demux.write_to_decoder = NULL; - - if ((ret = dvb_dmx_init(&fc->demux)) < 0) { - err("dvb_dmx failed: error %d",ret); - goto err_dmx; - } - - fc->hw_frontend.source = DMX_FRONTEND_0; - - fc->dmxdev.filternum = fc->demux.feednum; - fc->dmxdev.demux = &fc->demux.dmx; - fc->dmxdev.capabilities = 0; - if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) { - err("dvb_dmxdev_init failed: error %d",ret); - goto err_dmx_dev; - } - - if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { - err("adding hw_frontend to dmx failed: error %d",ret); - goto err_dmx_add_hw_frontend; - } - - fc->mem_frontend.source = DMX_MEMORY_FE; - if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) { - err("adding mem_frontend to dmx failed: error %d",ret); - goto err_dmx_add_mem_frontend; - } - - if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { - err("connect frontend failed: error %d",ret); - goto err_connect_frontend; - } - - dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); - - fc->init_state |= FC_STATE_DVB_INIT; - return 0; - -err_connect_frontend: - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); -err_dmx_add_mem_frontend: - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); -err_dmx_add_hw_frontend: - dvb_dmxdev_release(&fc->dmxdev); -err_dmx_dev: - dvb_dmx_release(&fc->demux); -err_dmx: - dvb_unregister_adapter(&fc->dvb_adapter); - return ret; -} - -static void flexcop_dvb_exit(struct flexcop_device *fc) -{ - if (fc->init_state & FC_STATE_DVB_INIT) { - dvb_net_release(&fc->dvbnet); - - fc->demux.dmx.close(&fc->demux.dmx); - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); - fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); - dvb_dmxdev_release(&fc->dmxdev); - dvb_dmx_release(&fc->demux); - dvb_unregister_adapter(&fc->dvb_adapter); - - deb_info("deinitialized dvb stuff\n"); - } - fc->init_state &= ~FC_STATE_DVB_INIT; -} - -/* these methods are necessary to achieve the long-term-goal of hiding the - * struct flexcop_device from the bus-parts */ -void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len) -{ - dvb_dmx_swfilter(&fc->demux, buf, len); -} -EXPORT_SYMBOL(flexcop_pass_dmx_data); - -void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no) -{ - dvb_dmx_swfilter_packets(&fc->demux, buf, no); -} -EXPORT_SYMBOL(flexcop_pass_dmx_packets); - -static void flexcop_reset(struct flexcop_device *fc) -{ - flexcop_ibi_value v210,v204; - -/* reset the flexcop itself */ - fc->write_ibi_reg(fc,ctrl_208,ibi_zero); - - v210.raw = 0; - v210.sw_reset_210.reset_block_000 = 1; - v210.sw_reset_210.reset_block_100 = 1; - v210.sw_reset_210.reset_block_200 = 1; - v210.sw_reset_210.reset_block_300 = 1; - v210.sw_reset_210.reset_block_400 = 1; - v210.sw_reset_210.reset_block_500 = 1; - v210.sw_reset_210.reset_block_600 = 1; - v210.sw_reset_210.reset_block_700 = 1; - v210.sw_reset_210.Block_reset_enable = 0xb2; - - v210.sw_reset_210.Special_controls = 0xc259; - - fc->write_ibi_reg(fc,sw_reset_210,v210); - msleep(1); - -/* reset the periphical devices */ - - v204 = fc->read_ibi_reg(fc,misc_204); - v204.misc_204.Per_reset_sig = 0; - fc->write_ibi_reg(fc,misc_204,v204); - msleep(1); - v204.misc_204.Per_reset_sig = 1; - fc->write_ibi_reg(fc,misc_204,v204); -} - -void flexcop_reset_block_300(struct flexcop_device *fc) -{ - flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208), - v210 = fc->read_ibi_reg(fc,sw_reset_210); - - deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw); - - fc->write_ibi_reg(fc,ctrl_208,ibi_zero); - - v210.sw_reset_210.reset_block_300 = 1; - v210.sw_reset_210.Block_reset_enable = 0xb2; - - fc->write_ibi_reg(fc,sw_reset_210,v210); - msleep(1); - - fc->write_ibi_reg(fc,ctrl_208,v208_save); -} - -struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len) -{ - void *bus; - struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL); - if (!fc) { - err("no memory"); - return NULL; - } - - bus = kzalloc(bus_specific_len, GFP_KERNEL); - if (!bus) { - err("no memory"); - kfree(fc); - return NULL; - } - - fc->bus_specific = bus; - - return fc; -} -EXPORT_SYMBOL(flexcop_device_kmalloc); - -void flexcop_device_kfree(struct flexcop_device *fc) -{ - kfree(fc->bus_specific); - kfree(fc); -} -EXPORT_SYMBOL(flexcop_device_kfree); - -int flexcop_device_initialize(struct flexcop_device *fc) -{ - int ret; - ibi_zero.raw = 0; - - flexcop_reset(fc); - flexcop_determine_revision(fc); - flexcop_sram_init(fc); - flexcop_hw_filter_init(fc); - - flexcop_smc_ctrl(fc, 0); - - if ((ret = flexcop_dvb_init(fc))) - goto error; - - /* i2c has to be done before doing EEProm stuff - - * because the EEProm is accessed via i2c */ - ret = flexcop_i2c_init(fc); - if (ret) - goto error; - - /* do the MAC address reading after initializing the dvb_adapter */ - if (fc->get_mac_addr(fc, 0) == 0) { - u8 *b = fc->dvb_adapter.proposed_mac; - info("MAC address = %pM", b); - flexcop_set_mac_filter(fc,b); - flexcop_mac_filter_ctrl(fc,1); - } else - warn("reading of MAC address failed.\n"); - - if ((ret = flexcop_frontend_init(fc))) - goto error; - - flexcop_device_name(fc,"initialization of","complete"); - - return 0; - -error: - flexcop_device_exit(fc); - return ret; -} -EXPORT_SYMBOL(flexcop_device_initialize); - -void flexcop_device_exit(struct flexcop_device *fc) -{ - flexcop_frontend_exit(fc); - flexcop_i2c_exit(fc); - flexcop_dvb_exit(fc); -} -EXPORT_SYMBOL(flexcop_device_exit); - -static int flexcop_module_init(void) -{ - info(DRIVER_NAME " loaded successfully"); - return 0; -} - -static void flexcop_module_cleanup(void) -{ - info(DRIVER_NAME " unloaded successfully"); -} - -module_init(flexcop_module_init); -module_exit(flexcop_module_cleanup); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_NAME); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h deleted file mode 100644 index 0cebe1d92e0..00000000000 --- a/drivers/media/dvb/b2c2/flexcop.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * flexcop.h - private header file for all flexcop-chip-source files. - * - * see flexcop.c for copyright information. - */ -#ifndef __FLEXCOP_H__ -#define __FLEXCOP_H___ - -#define FC_LOG_PREFIX "b2c2-flexcop" -#include "flexcop-common.h" - -extern int b2c2_flexcop_debug; - -/* debug */ -#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG -#define dprintk(level,args...) \ - do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0) -#else -#define dprintk(level,args...) -#endif - -#define deb_info(args...) dprintk(0x01,args) -#define deb_tuner(args...) dprintk(0x02,args) -#define deb_i2c(args...) dprintk(0x04,args) -#define deb_ts(args...) dprintk(0x08,args) -#define deb_sram(args...) dprintk(0x10,args) -#define deb_rdump(args...) dprintk(0x20,args) - -#endif diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h deleted file mode 100644 index ed9a6756b19..00000000000 --- a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h +++ /dev/null @@ -1,458 +0,0 @@ -/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * register descriptions - * - * see flexcop.c for copyright information. - */ - -/* This file is automatically generated, do not edit things here. */ -#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__ -#define __FLEXCOP_IBI_VALUE_INCLUDED__ - -typedef union { - u32 raw; - - struct { - u32 dma_address0 :30; - u32 dma_0No_update : 1; - u32 dma_0start : 1; - } dma_0x0; - - struct { - u32 dma_addr_size :24; - u32 DMA_maxpackets : 8; - } dma_0x4_remap; - - struct { - u32 dma_addr_size :24; - u32 unused : 1; - u32 dma1timer : 7; - } dma_0x4_read; - - struct { - u32 dma_addr_size :24; - u32 dmatimer : 7; - u32 unused : 1; - } dma_0x4_write; - - struct { - u32 dma_cur_addr :30; - u32 unused : 2; - } dma_0x8; - - struct { - u32 dma_address1 :30; - u32 remap_enable : 1; - u32 dma_1start : 1; - } dma_0xc; - - struct { - u32 st_done : 1; - u32 no_base_addr_ack_error : 1; - u32 twoWS_port_reg : 2; - u32 total_bytes : 2; - u32 twoWS_rw : 1; - u32 working_start : 1; - u32 data1_reg : 8; - u32 baseaddr : 8; - u32 reserved1 : 1; - u32 chipaddr : 7; - } tw_sm_c_100; - - struct { - u32 unused : 6; - u32 force_stop : 1; - u32 exlicit_stops : 1; - u32 data4_reg : 8; - u32 data3_reg : 8; - u32 data2_reg : 8; - } tw_sm_c_104; - - struct { - u32 reserved2 :19; - u32 tlo1 : 5; - u32 reserved1 : 2; - u32 thi1 : 6; - } tw_sm_c_108; - - struct { - u32 reserved2 :19; - u32 tlo1 : 5; - u32 reserved1 : 2; - u32 thi1 : 6; - } tw_sm_c_10c; - - struct { - u32 reserved2 :19; - u32 tlo1 : 5; - u32 reserved1 : 2; - u32 thi1 : 6; - } tw_sm_c_110; - - struct { - u32 LNB_CTLPrescaler_sig : 2; - u32 LNB_CTLLowCount_sig :15; - u32 LNB_CTLHighCount_sig :15; - } lnb_switch_freq_200; - - struct { - u32 Rev_N_sig_reserved2 : 1; - u32 Rev_N_sig_caps : 1; - u32 Rev_N_sig_reserved1 : 2; - u32 Rev_N_sig_revision_hi : 4; - u32 reserved :20; - u32 Per_reset_sig : 1; - u32 LNB_L_H_sig : 1; - u32 ACPI3_sig : 1; - u32 ACPI1_sig : 1; - } misc_204; - - struct { - u32 unused : 9; - u32 Mailbox_from_V8_Enable_sig : 1; - u32 DMA2_Size_IRQ_Enable_sig : 1; - u32 DMA1_Size_IRQ_Enable_sig : 1; - u32 DMA2_Timer_Enable_sig : 1; - u32 DMA2_IRQ_Enable_sig : 1; - u32 DMA1_Timer_Enable_sig : 1; - u32 DMA1_IRQ_Enable_sig : 1; - u32 Rcv_Data_sig : 1; - u32 MAC_filter_Mode_sig : 1; - u32 Multi2_Enable_sig : 1; - u32 Per_CA_Enable_sig : 1; - u32 SMC_Enable_sig : 1; - u32 CA_Enable_sig : 1; - u32 WAN_CA_Enable_sig : 1; - u32 WAN_Enable_sig : 1; - u32 Mask_filter_sig : 1; - u32 Null_filter_sig : 1; - u32 ECM_filter_sig : 1; - u32 EMM_filter_sig : 1; - u32 PMT_filter_sig : 1; - u32 PCR_filter_sig : 1; - u32 Stream2_filter_sig : 1; - u32 Stream1_filter_sig : 1; - } ctrl_208; - - struct { - u32 reserved :21; - u32 Transport_Error : 1; - u32 LLC_SNAP_FLAG_set : 1; - u32 Continuity_error_flag : 1; - u32 Data_receiver_error : 1; - u32 Mailbox_from_V8_Status_sig : 1; - u32 DMA2_Size_IRQ_Status : 1; - u32 DMA1_Size_IRQ_Status : 1; - u32 DMA2_Timer_Status : 1; - u32 DMA2_IRQ_Status : 1; - u32 DMA1_Timer_Status : 1; - u32 DMA1_IRQ_Status : 1; - } irq_20c; - - struct { - u32 Special_controls :16; - u32 Block_reset_enable : 8; - u32 reset_block_700 : 1; - u32 reset_block_600 : 1; - u32 reset_block_500 : 1; - u32 reset_block_400 : 1; - u32 reset_block_300 : 1; - u32 reset_block_200 : 1; - u32 reset_block_100 : 1; - u32 reset_block_000 : 1; - } sw_reset_210; - - struct { - u32 unused2 :20; - u32 polarity_PS_ERR_sig : 1; - u32 polarity_PS_SYNC_sig : 1; - u32 polarity_PS_VALID_sig : 1; - u32 polarity_PS_CLK_sig : 1; - u32 unused1 : 3; - u32 s2p_sel_sig : 1; - u32 section_pkg_enable_sig : 1; - u32 halt_V8_sig : 1; - u32 v2WS_oe_sig : 1; - u32 vuart_oe_sig : 1; - } misc_214; - - struct { - u32 Mailbox_from_V8 :32; - } mbox_v8_to_host_218; - - struct { - u32 sysramaccess_busmuster : 1; - u32 sysramaccess_write : 1; - u32 unused : 7; - u32 sysramaccess_addr :15; - u32 sysramaccess_data : 8; - } mbox_host_to_v8_21c; - - struct { - u32 debug_fifo_problem : 1; - u32 debug_flag_write_status00 : 1; - u32 Stream2_trans : 1; - u32 Stream2_PID :13; - u32 debug_flag_pid_saved : 1; - u32 MAC_Multicast_filter : 1; - u32 Stream1_trans : 1; - u32 Stream1_PID :13; - } pid_filter_300; - - struct { - u32 reserved : 2; - u32 PMT_trans : 1; - u32 PMT_PID :13; - u32 debug_overrun2 : 1; - u32 debug_overrun3 : 1; - u32 PCR_trans : 1; - u32 PCR_PID :13; - } pid_filter_304; - - struct { - u32 reserved : 2; - u32 ECM_trans : 1; - u32 ECM_PID :13; - u32 EMM_filter_6 : 1; - u32 EMM_filter_4 : 1; - u32 EMM_trans : 1; - u32 EMM_PID :13; - } pid_filter_308; - - struct { - u32 unused2 : 3; - u32 Group_mask :13; - u32 unused1 : 2; - u32 Group_trans : 1; - u32 Group_PID :13; - } pid_filter_30c_ext_ind_0_7; - - struct { - u32 unused :15; - u32 net_master_read :17; - } pid_filter_30c_ext_ind_1; - - struct { - u32 unused :15; - u32 net_master_write :17; - } pid_filter_30c_ext_ind_2; - - struct { - u32 unused :15; - u32 next_net_master_write :17; - } pid_filter_30c_ext_ind_3; - - struct { - u32 reserved2 : 5; - u32 stack_read :10; - u32 reserved1 : 6; - u32 state_write :10; - u32 unused1 : 1; - } pid_filter_30c_ext_ind_4; - - struct { - u32 unused :22; - u32 stack_cnt :10; - } pid_filter_30c_ext_ind_5; - - struct { - u32 unused : 4; - u32 data_size_reg :12; - u32 write_status4 : 2; - u32 write_status1 : 2; - u32 pid_fsm_save_reg300 : 2; - u32 pid_fsm_save_reg4 : 2; - u32 pid_fsm_save_reg3 : 2; - u32 pid_fsm_save_reg2 : 2; - u32 pid_fsm_save_reg1 : 2; - u32 pid_fsm_save_reg0 : 2; - } pid_filter_30c_ext_ind_6; - - struct { - u32 unused :22; - u32 pass_alltables : 1; - u32 AB_select : 1; - u32 extra_index_reg : 3; - u32 index_reg : 5; - } index_reg_310; - - struct { - u32 reserved :17; - u32 PID_enable_bit : 1; - u32 PID_trans : 1; - u32 PID :13; - } pid_n_reg_314; - - struct { - u32 reserved : 6; - u32 HighAB_bit : 1; - u32 Enable_bit : 1; - u32 A6_byte : 8; - u32 A5_byte : 8; - u32 A4_byte : 8; - } mac_low_reg_318; - - struct { - u32 reserved : 8; - u32 A3_byte : 8; - u32 A2_byte : 8; - u32 A1_byte : 8; - } mac_high_reg_31c; - - struct { - u32 data_Tag_ID :16; - u32 reserved :16; - } data_tag_400; - - struct { - u32 Card_IDbyte3 : 8; - u32 Card_IDbyte4 : 8; - u32 Card_IDbyte5 : 8; - u32 Card_IDbyte6 : 8; - } card_id_408; - - struct { - u32 Card_IDbyte1 : 8; - u32 Card_IDbyte2 : 8; - } card_id_40c; - - struct { - u32 MAC6 : 8; - u32 MAC3 : 8; - u32 MAC2 : 8; - u32 MAC1 : 8; - } mac_address_418; - - struct { - u32 reserved :16; - u32 MAC8 : 8; - u32 MAC7 : 8; - } mac_address_41c; - - struct { - u32 reserved :21; - u32 txbuffempty : 1; - u32 ReceiveByteFrameError : 1; - u32 ReceiveDataReady : 1; - u32 transmitter_data_byte : 8; - } ci_600; - - struct { - u32 pi_component_reg : 3; - u32 pi_rw : 1; - u32 pi_ha :20; - u32 pi_d : 8; - } pi_604; - - struct { - u32 pi_busy_n : 1; - u32 pi_wait_n : 1; - u32 pi_timeout_status : 1; - u32 pi_CiMax_IRQ_n : 1; - u32 config_cclk : 1; - u32 config_cs_n : 1; - u32 config_wr_n : 1; - u32 config_Prog_n : 1; - u32 config_Init_stat : 1; - u32 config_Done_stat : 1; - u32 pcmcia_b_mod_pwr_n : 1; - u32 pcmcia_a_mod_pwr_n : 1; - u32 reserved : 3; - u32 Timer_addr : 5; - u32 unused : 1; - u32 timer_data : 7; - u32 Timer_Load_req : 1; - u32 Timer_Read_req : 1; - u32 oncecycle_read : 1; - u32 serialReset : 1; - } pi_608; - - struct { - u32 reserved : 6; - u32 rw_flag : 1; - u32 dvb_en : 1; - u32 key_array_row : 5; - u32 key_array_col : 3; - u32 key_code : 2; - u32 key_enable : 1; - u32 PID :13; - } dvb_reg_60c; - - struct { - u32 start_sram_ibi : 1; - u32 reserved2 : 1; - u32 ce_pin_reg : 1; - u32 oe_pin_reg : 1; - u32 reserved1 : 3; - u32 sc_xfer_bit : 1; - u32 sram_data : 8; - u32 sram_rw : 1; - u32 sram_addr :15; - } sram_ctrl_reg_700; - - struct { - u32 net_addr_write :16; - u32 net_addr_read :16; - } net_buf_reg_704; - - struct { - u32 cai_cnt : 4; - u32 reserved2 : 6; - u32 cai_write :11; - u32 reserved1 : 5; - u32 cai_read :11; - } cai_buf_reg_708; - - struct { - u32 cao_cnt : 4; - u32 reserved2 : 6; - u32 cap_write :11; - u32 reserved1 : 5; - u32 cao_read :11; - } cao_buf_reg_70c; - - struct { - u32 media_cnt : 4; - u32 reserved2 : 6; - u32 media_write :11; - u32 reserved1 : 5; - u32 media_read :11; - } media_buf_reg_710; - - struct { - u32 reserved :17; - u32 ctrl_maximumfill : 1; - u32 ctrl_sramdma : 1; - u32 ctrl_usb_wan : 1; - u32 cao_ovflow_error : 1; - u32 cai_ovflow_error : 1; - u32 media_ovflow_error : 1; - u32 net_ovflow_error : 1; - u32 MEDIA_Dest : 2; - u32 CAO_Dest : 2; - u32 CAI_Dest : 2; - u32 NET_Dest : 2; - } sram_dest_reg_714; - - struct { - u32 reserved3 :11; - u32 net_addr_write : 1; - u32 reserved2 : 3; - u32 net_addr_read : 1; - u32 reserved1 : 4; - u32 net_cnt :12; - } net_buf_reg_718; - - struct { - u32 reserved3 : 4; - u32 wan_pkt_frame : 4; - u32 reserved2 : 4; - u32 sram_memmap : 2; - u32 sram_chip : 2; - u32 wan_wait_state : 8; - u32 reserved1 : 6; - u32 wan_speed_sig : 2; - } wan_ctrl_reg_71c; -} flexcop_ibi_value; - -#endif diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h deleted file mode 100644 index 49f2315b6e5..00000000000 --- a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h +++ /dev/null @@ -1,458 +0,0 @@ -/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III - * - * register descriptions - * - * see flexcop.c for copyright information. - */ - -/* This file is automatically generated, do not edit things here. */ -#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__ -#define __FLEXCOP_IBI_VALUE_INCLUDED__ - -typedef union { - u32 raw; - - struct { - u32 dma_0start : 1; - u32 dma_0No_update : 1; - u32 dma_address0 :30; - } dma_0x0; - - struct { - u32 DMA_maxpackets : 8; - u32 dma_addr_size :24; - } dma_0x4_remap; - - struct { - u32 dma1timer : 7; - u32 unused : 1; - u32 dma_addr_size :24; - } dma_0x4_read; - - struct { - u32 unused : 1; - u32 dmatimer : 7; - u32 dma_addr_size :24; - } dma_0x4_write; - - struct { - u32 unused : 2; - u32 dma_cur_addr :30; - } dma_0x8; - - struct { - u32 dma_1start : 1; - u32 remap_enable : 1; - u32 dma_address1 :30; - } dma_0xc; - - struct { - u32 chipaddr : 7; - u32 reserved1 : 1; - u32 baseaddr : 8; - u32 data1_reg : 8; - u32 working_start : 1; - u32 twoWS_rw : 1; - u32 total_bytes : 2; - u32 twoWS_port_reg : 2; - u32 no_base_addr_ack_error : 1; - u32 st_done : 1; - } tw_sm_c_100; - - struct { - u32 data2_reg : 8; - u32 data3_reg : 8; - u32 data4_reg : 8; - u32 exlicit_stops : 1; - u32 force_stop : 1; - u32 unused : 6; - } tw_sm_c_104; - - struct { - u32 thi1 : 6; - u32 reserved1 : 2; - u32 tlo1 : 5; - u32 reserved2 :19; - } tw_sm_c_108; - - struct { - u32 thi1 : 6; - u32 reserved1 : 2; - u32 tlo1 : 5; - u32 reserved2 :19; - } tw_sm_c_10c; - - struct { - u32 thi1 : 6; - u32 reserved1 : 2; - u32 tlo1 : 5; - u32 reserved2 :19; - } tw_sm_c_110; - - struct { - u32 LNB_CTLHighCount_sig :15; - u32 LNB_CTLLowCount_sig :15; - u32 LNB_CTLPrescaler_sig : 2; - } lnb_switch_freq_200; - - struct { - u32 ACPI1_sig : 1; - u32 ACPI3_sig : 1; - u32 LNB_L_H_sig : 1; - u32 Per_reset_sig : 1; - u32 reserved :20; - u32 Rev_N_sig_revision_hi : 4; - u32 Rev_N_sig_reserved1 : 2; - u32 Rev_N_sig_caps : 1; - u32 Rev_N_sig_reserved2 : 1; - } misc_204; - - struct { - u32 Stream1_filter_sig : 1; - u32 Stream2_filter_sig : 1; - u32 PCR_filter_sig : 1; - u32 PMT_filter_sig : 1; - u32 EMM_filter_sig : 1; - u32 ECM_filter_sig : 1; - u32 Null_filter_sig : 1; - u32 Mask_filter_sig : 1; - u32 WAN_Enable_sig : 1; - u32 WAN_CA_Enable_sig : 1; - u32 CA_Enable_sig : 1; - u32 SMC_Enable_sig : 1; - u32 Per_CA_Enable_sig : 1; - u32 Multi2_Enable_sig : 1; - u32 MAC_filter_Mode_sig : 1; - u32 Rcv_Data_sig : 1; - u32 DMA1_IRQ_Enable_sig : 1; - u32 DMA1_Timer_Enable_sig : 1; - u32 DMA2_IRQ_Enable_sig : 1; - u32 DMA2_Timer_Enable_sig : 1; - u32 DMA1_Size_IRQ_Enable_sig : 1; - u32 DMA2_Size_IRQ_Enable_sig : 1; - u32 Mailbox_from_V8_Enable_sig : 1; - u32 unused : 9; - } ctrl_208; - - struct { - u32 DMA1_IRQ_Status : 1; - u32 DMA1_Timer_Status : 1; - u32 DMA2_IRQ_Status : 1; - u32 DMA2_Timer_Status : 1; - u32 DMA1_Size_IRQ_Status : 1; - u32 DMA2_Size_IRQ_Status : 1; - u32 Mailbox_from_V8_Status_sig : 1; - u32 Data_receiver_error : 1; - u32 Continuity_error_flag : 1; - u32 LLC_SNAP_FLAG_set : 1; - u32 Transport_Error : 1; - u32 reserved :21; - } irq_20c; - - struct { - u32 reset_block_000 : 1; - u32 reset_block_100 : 1; - u32 reset_block_200 : 1; - u32 reset_block_300 : 1; - u32 reset_block_400 : 1; - u32 reset_block_500 : 1; - u32 reset_block_600 : 1; - u32 reset_block_700 : 1; - u32 Block_reset_enable : 8; - u32 Special_controls :16; - } sw_reset_210; - - struct { - u32 vuart_oe_sig : 1; - u32 v2WS_oe_sig : 1; - u32 halt_V8_sig : 1; - u32 section_pkg_enable_sig : 1; - u32 s2p_sel_sig : 1; - u32 unused1 : 3; - u32 polarity_PS_CLK_sig : 1; - u32 polarity_PS_VALID_sig : 1; - u32 polarity_PS_SYNC_sig : 1; - u32 polarity_PS_ERR_sig : 1; - u32 unused2 :20; - } misc_214; - - struct { - u32 Mailbox_from_V8 :32; - } mbox_v8_to_host_218; - - struct { - u32 sysramaccess_data : 8; - u32 sysramaccess_addr :15; - u32 unused : 7; - u32 sysramaccess_write : 1; - u32 sysramaccess_busmuster : 1; - } mbox_host_to_v8_21c; - - struct { - u32 Stream1_PID :13; - u32 Stream1_trans : 1; - u32 MAC_Multicast_filter : 1; - u32 debug_flag_pid_saved : 1; - u32 Stream2_PID :13; - u32 Stream2_trans : 1; - u32 debug_flag_write_status00 : 1; - u32 debug_fifo_problem : 1; - } pid_filter_300; - - struct { - u32 PCR_PID :13; - u32 PCR_trans : 1; - u32 debug_overrun3 : 1; - u32 debug_overrun2 : 1; - u32 PMT_PID :13; - u32 PMT_trans : 1; - u32 reserved : 2; - } pid_filter_304; - - struct { - u32 EMM_PID :13; - u32 EMM_trans : 1; - u32 EMM_filter_4 : 1; - u32 EMM_filter_6 : 1; - u32 ECM_PID :13; - u32 ECM_trans : 1; - u32 reserved : 2; - } pid_filter_308; - - struct { - u32 Group_PID :13; - u32 Group_trans : 1; - u32 unused1 : 2; - u32 Group_mask :13; - u32 unused2 : 3; - } pid_filter_30c_ext_ind_0_7; - - struct { - u32 net_master_read :17; - u32 unused :15; - } pid_filter_30c_ext_ind_1; - - struct { - u32 net_master_write :17; - u32 unused :15; - } pid_filter_30c_ext_ind_2; - - struct { - u32 next_net_master_write :17; - u32 unused :15; - } pid_filter_30c_ext_ind_3; - - struct { - u32 unused1 : 1; - u32 state_write :10; - u32 reserved1 : 6; - u32 stack_read :10; - u32 reserved2 : 5; - } pid_filter_30c_ext_ind_4; - - struct { - u32 stack_cnt :10; - u32 unused :22; - } pid_filter_30c_ext_ind_5; - - struct { - u32 pid_fsm_save_reg0 : 2; - u32 pid_fsm_save_reg1 : 2; - u32 pid_fsm_save_reg2 : 2; - u32 pid_fsm_save_reg3 : 2; - u32 pid_fsm_save_reg4 : 2; - u32 pid_fsm_save_reg300 : 2; - u32 write_status1 : 2; - u32 write_status4 : 2; - u32 data_size_reg :12; - u32 unused : 4; - } pid_filter_30c_ext_ind_6; - - struct { - u32 index_reg : 5; - u32 extra_index_reg : 3; - u32 AB_select : 1; - u32 pass_alltables : 1; - u32 unused :22; - } index_reg_310; - - struct { - u32 PID :13; - u32 PID_trans : 1; - u32 PID_enable_bit : 1; - u32 reserved :17; - } pid_n_reg_314; - - struct { - u32 A4_byte : 8; - u32 A5_byte : 8; - u32 A6_byte : 8; - u32 Enable_bit : 1; - u32 HighAB_bit : 1; - u32 reserved : 6; - } mac_low_reg_318; - - struct { - u32 A1_byte : 8; - u32 A2_byte : 8; - u32 A3_byte : 8; - u32 reserved : 8; - } mac_high_reg_31c; - - struct { - u32 reserved :16; - u32 data_Tag_ID :16; - } data_tag_400; - - struct { - u32 Card_IDbyte6 : 8; - u32 Card_IDbyte5 : 8; - u32 Card_IDbyte4 : 8; - u32 Card_IDbyte3 : 8; - } card_id_408; - - struct { - u32 Card_IDbyte2 : 8; - u32 Card_IDbyte1 : 8; - } card_id_40c; - - struct { - u32 MAC1 : 8; - u32 MAC2 : 8; - u32 MAC3 : 8; - u32 MAC6 : 8; - } mac_address_418; - - struct { - u32 MAC7 : 8; - u32 MAC8 : 8; - u32 reserved :16; - } mac_address_41c; - - struct { - u32 transmitter_data_byte : 8; - u32 ReceiveDataReady : 1; - u32 ReceiveByteFrameError : 1; - u32 txbuffempty : 1; - u32 reserved :21; - } ci_600; - - struct { - u32 pi_d : 8; - u32 pi_ha :20; - u32 pi_rw : 1; - u32 pi_component_reg : 3; - } pi_604; - - struct { - u32 serialReset : 1; - u32 oncecycle_read : 1; - u32 Timer_Read_req : 1; - u32 Timer_Load_req : 1; - u32 timer_data : 7; - u32 unused : 1; - u32 Timer_addr : 5; - u32 reserved : 3; - u32 pcmcia_a_mod_pwr_n : 1; - u32 pcmcia_b_mod_pwr_n : 1; - u32 config_Done_stat : 1; - u32 config_Init_stat : 1; - u32 config_Prog_n : 1; - u32 config_wr_n : 1; - u32 config_cs_n : 1; - u32 config_cclk : 1; - u32 pi_CiMax_IRQ_n : 1; - u32 pi_timeout_status : 1; - u32 pi_wait_n : 1; - u32 pi_busy_n : 1; - } pi_608; - - struct { - u32 PID :13; - u32 key_enable : 1; - u32 key_code : 2; - u32 key_array_col : 3; - u32 key_array_row : 5; - u32 dvb_en : 1; - u32 rw_flag : 1; - u32 reserved : 6; - } dvb_reg_60c; - - struct { - u32 sram_addr :15; - u32 sram_rw : 1; - u32 sram_data : 8; - u32 sc_xfer_bit : 1; - u32 reserved1 : 3; - u32 oe_pin_reg : 1; - u32 ce_pin_reg : 1; - u32 reserved2 : 1; - u32 start_sram_ibi : 1; - } sram_ctrl_reg_700; - - struct { - u32 net_addr_read :16; - u32 net_addr_write :16; - } net_buf_reg_704; - - struct { - u32 cai_read :11; - u32 reserved1 : 5; - u32 cai_write :11; - u32 reserved2 : 6; - u32 cai_cnt : 4; - } cai_buf_reg_708; - - struct { - u32 cao_read :11; - u32 reserved1 : 5; - u32 cap_write :11; - u32 reserved2 : 6; - u32 cao_cnt : 4; - } cao_buf_reg_70c; - - struct { - u32 media_read :11; - u32 reserved1 : 5; - u32 media_write :11; - u32 reserved2 : 6; - u32 media_cnt : 4; - } media_buf_reg_710; - - struct { - u32 NET_Dest : 2; - u32 CAI_Dest : 2; - u32 CAO_Dest : 2; - u32 MEDIA_Dest : 2; - u32 net_ovflow_error : 1; - u32 media_ovflow_error : 1; - u32 cai_ovflow_error : 1; - u32 cao_ovflow_error : 1; - u32 ctrl_usb_wan : 1; - u32 ctrl_sramdma : 1; - u32 ctrl_maximumfill : 1; - u32 reserved :17; - } sram_dest_reg_714; - - struct { - u32 net_cnt :12; - u32 reserved1 : 4; - u32 net_addr_read : 1; - u32 reserved2 : 3; - u32 net_addr_write : 1; - u32 reserved3 :11; - } net_buf_reg_718; - - struct { - u32 wan_speed_sig : 2; - u32 reserved1 : 6; - u32 wan_wait_state : 8; - u32 sram_chip : 2; - u32 sram_memmap : 2; - u32 reserved2 : 4; - u32 wan_pkt_frame : 4; - u32 reserved3 : 4; - } wan_ctrl_reg_71c; -} flexcop_ibi_value; - -#endif diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig deleted file mode 100644 index 27edb0ece58..00000000000 --- a/drivers/media/dvb/bt8xx/Kconfig +++ /dev/null @@ -1,22 +0,0 @@ -config DVB_BT8XX - tristate "BT8xx based PCI cards" - depends on DVB_CORE && PCI && I2C && VIDEO_BT848 - select DVB_MT352 if !DVB_FE_CUSTOMISE - select DVB_SP887X if !DVB_FE_CUSTOMISE - select DVB_NXT6000 if !DVB_FE_CUSTOMISE - select DVB_CX24110 if !DVB_FE_CUSTOMISE - select DVB_OR51211 if !DVB_FE_CUSTOMISE - select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE - help - Support for PCI cards based on the Bt8xx PCI bridge. Examples are - the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards, - the pcHDTV HD2000 cards, the DViCO FusionHDTV Lite cards, and - some AVerMedia cards. - - Since these cards have no MPEG decoder onboard, they transmit - only compressed MPEG data over the PCI bus, so you need - an external software decoder to watch TV on your computer. - - Say Y if you own such a device and want to use it. diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile deleted file mode 100644 index d98f1d49ffa..00000000000 --- a/drivers/media/dvb/bt8xx/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -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 diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c deleted file mode 100644 index 56d8fab688b..00000000000 --- a/drivers/media/dvb/bt8xx/bt878.c +++ /dev/null @@ -1,628 +0,0 @@ -/* - * bt878.c: part of the driver for the Pinnacle PCTV Sat DVB PCI card - * - * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> - * - * large parts based on the bttv driver - * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de) - * & Marcus Metzler (mocm@metzlerbros.de) - * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/pci.h> -#include <asm/io.h> -#include <linux/ioport.h> -#include <asm/pgtable.h> -#include <asm/page.h> -#include <linux/types.h> -#include <linux/interrupt.h> -#include <linux/kmod.h> -#include <linux/vmalloc.h> -#include <linux/init.h> - -#include "dmxdev.h" -#include "dvbdev.h" -#include "bt878.h" -#include "dst_priv.h" - - -/**************************************/ -/* Miscellaneous utility definitions */ -/**************************************/ - -static unsigned int bt878_verbose = 1; -static unsigned int bt878_debug; - -module_param_named(verbose, bt878_verbose, int, 0444); -MODULE_PARM_DESC(verbose, - "verbose startup messages, default is 1 (yes)"); -module_param_named(debug, bt878_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off)."); - -int bt878_num; -struct bt878 bt878[BT878_MAX]; - -EXPORT_SYMBOL(bt878_num); -EXPORT_SYMBOL(bt878); - -#define btwrite(dat,adr) bmtwrite((dat), (bt->bt878_mem+(adr))) -#define btread(adr) bmtread(bt->bt878_mem+(adr)) - -#define btand(dat,adr) btwrite((dat) & btread(adr), adr) -#define btor(dat,adr) btwrite((dat) | btread(adr), adr) -#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) - -#if defined(dprintk) -#undef dprintk -#endif -#define dprintk(fmt, arg...) \ - do { \ - if (bt878_debug) \ - printk(KERN_DEBUG fmt, ##arg); \ - } while (0) - -static void bt878_mem_free(struct bt878 *bt) -{ - if (bt->buf_cpu) { - pci_free_consistent(bt->dev, bt->buf_size, bt->buf_cpu, - bt->buf_dma); - bt->buf_cpu = NULL; - } - - if (bt->risc_cpu) { - pci_free_consistent(bt->dev, bt->risc_size, bt->risc_cpu, - bt->risc_dma); - bt->risc_cpu = NULL; - } -} - -static int bt878_mem_alloc(struct bt878 *bt) -{ - if (!bt->buf_cpu) { - bt->buf_size = 128 * 1024; - - bt->buf_cpu = - pci_alloc_consistent(bt->dev, bt->buf_size, - &bt->buf_dma); - - if (!bt->buf_cpu) - return -ENOMEM; - - memset(bt->buf_cpu, 0, bt->buf_size); - } - - if (!bt->risc_cpu) { - bt->risc_size = PAGE_SIZE; - bt->risc_cpu = - pci_alloc_consistent(bt->dev, bt->risc_size, - &bt->risc_dma); - - if (!bt->risc_cpu) { - bt878_mem_free(bt); - return -ENOMEM; - } - - memset(bt->risc_cpu, 0, bt->risc_size); - } - - return 0; -} - -/* RISC instructions */ -#define RISC_WRITE (0x01 << 28) -#define RISC_JUMP (0x07 << 28) -#define RISC_SYNC (0x08 << 28) - -/* RISC bits */ -#define RISC_WR_SOL (1 << 27) -#define RISC_WR_EOL (1 << 26) -#define RISC_IRQ (1 << 24) -#define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16)) -#define RISC_SYNC_RESYNC (1 << 15) -#define RISC_SYNC_FM1 0x06 -#define RISC_SYNC_VRO 0x0C - -#define RISC_FLUSH() bt->risc_pos = 0 -#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) - -static int bt878_make_risc(struct bt878 *bt) -{ - bt->block_bytes = bt->buf_size >> 4; - bt->block_count = 1 << 4; - bt->line_bytes = bt->block_bytes; - bt->line_count = bt->block_count; - - while (bt->line_bytes > 4095) { - bt->line_bytes >>= 1; - bt->line_count <<= 1; - } - - if (bt->line_count > 255) { - printk(KERN_ERR "bt878: buffer size error!\n"); - return -EINVAL; - } - return 0; -} - - -static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin) -{ - u32 buf_pos = 0; - u32 line; - - RISC_FLUSH(); - RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); - RISC_INSTR(0); - - dprintk("bt878: risc len lines %u, bytes per line %u\n", - bt->line_count, bt->line_bytes); - for (line = 0; line < bt->line_count; line++) { - // At the beginning of every block we issue an IRQ with previous (finished) block number set - if (!(buf_pos % bt->block_bytes)) - RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | - RISC_IRQ | - RISC_STATUS(((buf_pos / - bt->block_bytes) + - (bt->block_count - - 1)) % - bt->block_count) | bt-> - line_bytes); - else - RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | - bt->line_bytes); - RISC_INSTR(bt->buf_dma + buf_pos); - buf_pos += bt->line_bytes; - } - - RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO); - RISC_INSTR(0); - - RISC_INSTR(RISC_JUMP); - RISC_INSTR(bt->risc_dma); - - btwrite((bt->line_count << 16) | bt->line_bytes, BT878_APACK_LEN); -} - -/*****************************/ -/* Start/Stop grabbing funcs */ -/*****************************/ - -void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, - u32 irq_err_ignore) -{ - u32 int_mask; - - dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg); - /* complete the writing of the risc dma program now we have - * the card specifics - */ - bt878_risc_program(bt, op_sync_orin); - controlreg &= ~0x1f; - controlreg |= 0x1b; - - btwrite(bt->risc_dma, BT878_ARISC_START); - - /* original int mask had : - * 6 2 8 4 0 - * 1111 1111 1000 0000 0000 - * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI - * Hacked for DST to: - * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI - */ - int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | - BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | - BT878_AFBUS | BT878_ARISCI; - - - /* ignore pesky bits */ - int_mask &= ~irq_err_ignore; - - btwrite(int_mask, BT878_AINT_MASK); - btwrite(controlreg, BT878_AGPIO_DMA_CTL); -} - -void bt878_stop(struct bt878 *bt) -{ - u32 stat; - int i = 0; - - dprintk("bt878 debug: bt878_stop\n"); - - btwrite(0, BT878_AINT_MASK); - btand(~0x13, BT878_AGPIO_DMA_CTL); - - do { - stat = btread(BT878_AINT_STAT); - if (!(stat & BT878_ARISC_EN)) - break; - i++; - } while (i < 500); - - dprintk("bt878(%d) debug: bt878_stop, i=%d, stat=0x%8.8x\n", - bt->nr, i, stat); -} - -EXPORT_SYMBOL(bt878_start); -EXPORT_SYMBOL(bt878_stop); - -/*****************************/ -/* Interrupt service routine */ -/*****************************/ - -static irqreturn_t bt878_irq(int irq, void *dev_id) -{ - u32 stat, astat, mask; - int count; - struct bt878 *bt; - - bt = (struct bt878 *) dev_id; - - count = 0; - while (1) { - stat = btread(BT878_AINT_STAT); - mask = btread(BT878_AINT_MASK); - if (!(astat = (stat & mask))) - return IRQ_NONE; /* this interrupt is not for me */ -/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */ - btwrite(astat, BT878_AINT_STAT); /* try to clear interrupt condition */ - - - if (astat & (BT878_ASCERR | BT878_AOCERR)) { - if (bt878_verbose) { - printk(KERN_INFO - "bt878(%d): irq%s%s risc_pc=%08x\n", - bt->nr, - (astat & BT878_ASCERR) ? " SCERR" : - "", - (astat & BT878_AOCERR) ? " OCERR" : - "", btread(BT878_ARISC_PC)); - } - } - if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) { - if (bt878_verbose) { - printk(KERN_INFO - "bt878(%d): irq%s%s%s risc_pc=%08x\n", - bt->nr, - (astat & BT878_APABORT) ? " PABORT" : - "", - (astat & BT878_ARIPERR) ? " RIPERR" : - "", - (astat & BT878_APPERR) ? " PPERR" : - "", btread(BT878_ARISC_PC)); - } - } - if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) { - if (bt878_verbose) { - printk(KERN_INFO - "bt878(%d): irq%s%s%s risc_pc=%08x\n", - bt->nr, - (astat & BT878_AFDSR) ? " FDSR" : "", - (astat & BT878_AFTRGT) ? " FTRGT" : - "", - (astat & BT878_AFBUS) ? " FBUS" : "", - btread(BT878_ARISC_PC)); - } - } - if (astat & BT878_ARISCI) { - bt->finished_block = (stat & BT878_ARISCS) >> 28; - tasklet_schedule(&bt->tasklet); - break; - } - count++; - if (count > 20) { - btwrite(0, BT878_AINT_MASK); - printk(KERN_ERR - "bt878(%d): IRQ lockup, cleared int mask\n", - bt->nr); - break; - } - } - return IRQ_HANDLED; -} - -int -bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp) -{ - int retval; - - retval = 0; - if (mutex_lock_interruptible(&bt->gpio_lock)) - return -ERESTARTSYS; - /* special gpio signal */ - switch (cmd) { - case DST_IG_ENABLE: - // dprintk("dvb_bt8xx: dst enable mask 0x%02x enb 0x%02x \n", mp->dstg.enb.mask, mp->dstg.enb.enable); - retval = bttv_gpio_enable(bt->bttv_nr, - mp->enb.mask, - mp->enb.enable); - break; - case DST_IG_WRITE: - // dprintk("dvb_bt8xx: dst write gpio mask 0x%02x out 0x%02x\n", mp->dstg.outp.mask, mp->dstg.outp.highvals); - retval = bttv_write_gpio(bt->bttv_nr, - mp->outp.mask, - mp->outp.highvals); - - break; - case DST_IG_READ: - /* read */ - retval = bttv_read_gpio(bt->bttv_nr, &mp->rd.value); - // dprintk("dvb_bt8xx: dst read gpio 0x%02x\n", (unsigned)mp->dstg.rd.value); - break; - case DST_IG_TS: - /* Set packet size */ - bt->TS_Size = mp->psize; - break; - - default: - retval = -EINVAL; - break; - } - mutex_unlock(&bt->gpio_lock); - return retval; -} - -EXPORT_SYMBOL(bt878_device_control); - -#define BROOKTREE_878_DEVICE(vend, dev, name) \ - { \ - .vendor = PCI_VENDOR_ID_BROOKTREE, \ - .device = PCI_DEVICE_ID_BROOKTREE_878, \ - .subvendor = (vend), .subdevice = (dev), \ - .driver_data = (unsigned long) name \ - } - -static struct pci_device_id bt878_pci_tbl[] __devinitdata = { - BROOKTREE_878_DEVICE(0x0071, 0x0101, "Nebula Electronics DigiTV"), - BROOKTREE_878_DEVICE(0x1461, 0x0761, "AverMedia AverTV DVB-T 761"), - BROOKTREE_878_DEVICE(0x11bd, 0x001c, "Pinnacle PCTV Sat"), - BROOKTREE_878_DEVICE(0x11bd, 0x0026, "Pinnacle PCTV SAT CI"), - BROOKTREE_878_DEVICE(0x1822, 0x0001, "Twinhan VisionPlus DVB"), - BROOKTREE_878_DEVICE(0x270f, 0xfc00, - "ChainTech digitop DST-1000 DVB-S"), - BROOKTREE_878_DEVICE(0x1461, 0x0771, "AVermedia AverTV DVB-T 771"), - BROOKTREE_878_DEVICE(0x18ac, 0xdb10, "DViCO FusionHDTV DVB-T Lite"), - BROOKTREE_878_DEVICE(0x18ac, 0xdb11, "Ultraview DVB-T Lite"), - BROOKTREE_878_DEVICE(0x18ac, 0xd500, "DViCO FusionHDTV 5 Lite"), - BROOKTREE_878_DEVICE(0x7063, 0x2000, "pcHDTV HD-2000 TV"), - BROOKTREE_878_DEVICE(0x1822, 0x0026, "DNTV Live! Mini"), - { } -}; - -MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); - -static const char * __devinit card_name(const struct pci_device_id *id) -{ - return id->driver_data ? (const char *)id->driver_data : "Unknown"; -} - -/***********************/ -/* PCI device handling */ -/***********************/ - -static int __devinit bt878_probe(struct pci_dev *dev, - const struct pci_device_id *pci_id) -{ - int result = 0; - unsigned char lat; - struct bt878 *bt; -#if defined(__powerpc__) - unsigned int cmd; -#endif - unsigned int cardid; - - printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", - bt878_num); - if (bt878_num >= BT878_MAX) { - printk(KERN_ERR "bt878: Too many devices inserted\n"); - result = -ENOMEM; - goto fail0; - } - if (pci_enable_device(dev)) - return -EIO; - - cardid = dev->subsystem_device << 16; - cardid |= dev->subsystem_vendor; - - printk(KERN_INFO "%s: card id=[0x%x],[ %s ] has DVB functions.\n", - __func__, cardid, card_name(pci_id)); - - bt = &bt878[bt878_num]; - bt->dev = dev; - bt->nr = bt878_num; - bt->shutdown = 0; - - bt->id = dev->device; - bt->irq = dev->irq; - bt->bt878_adr = pci_resource_start(dev, 0); - if (!request_mem_region(pci_resource_start(dev, 0), - pci_resource_len(dev, 0), "bt878")) { - result = -EBUSY; - goto fail0; - } - - pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); - - - printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", - bt878_num, bt->id, bt->revision, dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - printk("irq: %d, latency: %d, memory: 0x%lx\n", - bt->irq, lat, bt->bt878_adr); - - -#if defined(__powerpc__) - /* on OpenFirmware machines (PowerMac at least), PCI memory cycle */ - /* response on cards with no firmware is not enabled by OF */ - pci_read_config_dword(dev, PCI_COMMAND, &cmd); - cmd = (cmd | PCI_COMMAND_MEMORY); - pci_write_config_dword(dev, PCI_COMMAND, cmd); -#endif - -#ifdef __sparc__ - bt->bt878_mem = (unsigned char *) bt->bt878_adr; -#else - bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000); -#endif - - /* clear interrupt mask */ - btwrite(0, BT848_INT_MASK); - - result = request_irq(bt->irq, bt878_irq, - IRQF_SHARED | IRQF_DISABLED, "bt878", - (void *) bt); - if (result == -EINVAL) { - printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", - bt878_num); - goto fail1; - } - if (result == -EBUSY) { - printk(KERN_ERR - "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n", - bt878_num, bt->irq); - goto fail1; - } - if (result < 0) - goto fail1; - - pci_set_master(dev); - pci_set_drvdata(dev, bt); - -/* if(init_bt878(btv) < 0) { - bt878_remove(dev); - return -EIO; - } -*/ - - if ((result = bt878_mem_alloc(bt))) { - printk(KERN_ERR "bt878: failed to allocate memory!\n"); - goto fail2; - } - - bt878_make_risc(bt); - btwrite(0, BT878_AINT_MASK); - bt878_num++; - - return 0; - - fail2: - free_irq(bt->irq, bt); - fail1: - release_mem_region(pci_resource_start(bt->dev, 0), - pci_resource_len(bt->dev, 0)); - fail0: - pci_disable_device(dev); - return result; -} - -static void __devexit bt878_remove(struct pci_dev *pci_dev) -{ - u8 command; - struct bt878 *bt = pci_get_drvdata(pci_dev); - - if (bt878_verbose) - printk(KERN_INFO "bt878(%d): unloading\n", bt->nr); - - /* turn off all capturing, DMA and IRQs */ - btand(~0x13, BT878_AGPIO_DMA_CTL); - - /* first disable interrupts before unmapping the memory! */ - btwrite(0, BT878_AINT_MASK); - btwrite(~0U, BT878_AINT_STAT); - - /* disable PCI bus-mastering */ - pci_read_config_byte(bt->dev, PCI_COMMAND, &command); - /* Should this be &=~ ?? */ - command &= ~PCI_COMMAND_MASTER; - pci_write_config_byte(bt->dev, PCI_COMMAND, command); - - free_irq(bt->irq, bt); - printk(KERN_DEBUG "bt878_mem: 0x%p.\n", bt->bt878_mem); - if (bt->bt878_mem) - iounmap(bt->bt878_mem); - - release_mem_region(pci_resource_start(bt->dev, 0), - pci_resource_len(bt->dev, 0)); - /* wake up any waiting processes - because shutdown flag is set, no new processes (in this queue) - are expected - */ - bt->shutdown = 1; - bt878_mem_free(bt); - - pci_set_drvdata(pci_dev, NULL); - pci_disable_device(pci_dev); - return; -} - -static struct pci_driver bt878_pci_driver = { - .name = "bt878", - .id_table = bt878_pci_tbl, - .probe = bt878_probe, - .remove = bt878_remove, -}; - -static int bt878_pci_driver_registered; - -/*******************************/ -/* Module management functions */ -/*******************************/ - -static int bt878_init_module(void) -{ - bt878_num = 0; - bt878_pci_driver_registered = 0; - - printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", - (BT878_VERSION_CODE >> 16) & 0xff, - (BT878_VERSION_CODE >> 8) & 0xff, - BT878_VERSION_CODE & 0xff); -/* - bt878_check_chipset(); -*/ - /* later we register inside of bt878_find_audio_dma() - * because we may want to ignore certain cards */ - bt878_pci_driver_registered = 1; - return pci_register_driver(&bt878_pci_driver); -} - -static void bt878_cleanup_module(void) -{ - if (bt878_pci_driver_registered) { - bt878_pci_driver_registered = 0; - pci_unregister_driver(&bt878_pci_driver); - } - return; -} - -module_init(bt878_init_module); -module_exit(bt878_cleanup_module); - -//MODULE_AUTHOR("XXX"); -MODULE_LICENSE("GPL"); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h deleted file mode 100644 index d19b59299d7..00000000000 --- a/drivers/media/dvb/bt8xx/bt878.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - bt878.h - Bt878 audio module (register offsets) - - Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _BT878_H_ -#define _BT878_H_ - -#include <linux/interrupt.h> -#include <linux/pci.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <linux/mutex.h> - -#include "bt848.h" -#include "bttv.h" - -#define BT878_VERSION_CODE 0x000000 - -#define BT878_AINT_STAT 0x100 -#define BT878_ARISCS (0xf<<28) -#define BT878_ARISC_EN (1<<27) -#define BT878_ASCERR (1<<19) -#define BT878_AOCERR (1<<18) -#define BT878_APABORT (1<<17) -#define BT878_ARIPERR (1<<16) -#define BT878_APPERR (1<<15) -#define BT878_AFDSR (1<<14) -#define BT878_AFTRGT (1<<13) -#define BT878_AFBUS (1<<12) -#define BT878_ARISCI (1<<11) -#define BT878_AOFLOW (1<<3) - -#define BT878_AINT_MASK 0x104 - -#define BT878_AGPIO_DMA_CTL 0x10c -#define BT878_A_GAIN (0xf<<28) -#define BT878_A_G2X (1<<27) -#define BT878_A_PWRDN (1<<26) -#define BT878_A_SEL (3<<24) -#define BT878_DA_SCE (1<<23) -#define BT878_DA_LRI (1<<22) -#define BT878_DA_MLB (1<<21) -#define BT878_DA_LRD (0x1f<<16) -#define BT878_DA_DPM (1<<15) -#define BT878_DA_SBR (1<<14) -#define BT878_DA_ES2 (1<<13) -#define BT878_DA_LMT (1<<12) -#define BT878_DA_SDR (0xf<<8) -#define BT878_DA_IOM (3<<6) -#define BT878_DA_APP (1<<5) -#define BT878_ACAP_EN (1<<4) -#define BT878_PKTP (3<<2) -#define BT878_RISC_EN (1<<1) -#define BT878_FIFO_EN 1 - -#define BT878_APACK_LEN 0x110 -#define BT878_AFP_LEN (0xff<<16) -#define BT878_ALP_LEN 0xfff - -#define BT878_ARISC_START 0x114 - -#define BT878_ARISC_PC 0x120 - -/* BT878 FUNCTION 0 REGISTERS */ -#define BT878_GPIO_DMA_CTL 0x10c - -/* Interrupt register */ -#define BT878_INT_STAT 0x100 -#define BT878_INT_MASK 0x104 -#define BT878_I2CRACK (1<<25) -#define BT878_I2CDONE (1<<8) - -#define BT878_MAX 4 - -#define BT878_RISC_SYNC_MASK (1 << 15) - - -#define BTTV_BOARD_UNKNOWN 0x00 -#define BTTV_BOARD_PINNACLESAT 0x5e -#define BTTV_BOARD_NEBULA_DIGITV 0x68 -#define BTTV_BOARD_PC_HDTV 0x70 -#define BTTV_BOARD_TWINHAN_DST 0x71 -#define BTTV_BOARD_AVDVBT_771 0x7b -#define BTTV_BOARD_AVDVBT_761 0x7c -#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 -#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 - -extern int bt878_num; - -struct bt878 { - struct mutex gpio_lock; - unsigned int nr; - unsigned int bttv_nr; - struct i2c_adapter *adapter; - struct pci_dev *dev; - unsigned int id; - unsigned int TS_Size; - unsigned char revision; - unsigned int irq; - unsigned long bt878_adr; - volatile void __iomem *bt878_mem; /* function 1 */ - - volatile u32 finished_block; - volatile u32 last_block; - u32 block_count; - u32 block_bytes; - u32 line_bytes; - u32 line_count; - - u32 buf_size; - u8 *buf_cpu; - dma_addr_t buf_dma; - - u32 risc_size; - __le32 *risc_cpu; - dma_addr_t risc_dma; - u32 risc_pos; - - struct tasklet_struct tasklet; - int shutdown; -}; - -extern struct bt878 bt878[BT878_MAX]; - -void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, - u32 irq_err_ignore); -void bt878_stop(struct bt878 *bt); - -#if defined(__powerpc__) /* big-endian */ -static inline void io_st_le32(volatile unsigned __iomem *addr, unsigned val) -{ - st_le32(addr, val); - eieio(); -} - -#define bmtwrite(dat,adr) io_st_le32((adr),(dat)) -#define bmtread(adr) ld_le32((adr)) -#else -#define bmtwrite(dat,adr) writel((dat), (adr)) -#define bmtread(adr) readl(adr) -#endif - -#endif diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c deleted file mode 100644 index 29e8f1546ab..00000000000 --- a/drivers/media/dvb/bt8xx/dst.c +++ /dev/null @@ -1,1863 +0,0 @@ -/* - Frontend/Card driver for TwinHan DST Frontend - Copyright (C) 2003 Jamie Honan - Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/delay.h> -#include <asm/div64.h> -#include "dvb_frontend.h" -#include "dst_priv.h" -#include "dst_common.h" - -static unsigned int verbose = 1; -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); - -static unsigned int dst_addons; -module_param(dst_addons, int, 0644); -MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); - -static unsigned int dst_algo; -module_param(dst_algo, int, 0644); -MODULE_PARM_DESC(dst_algo, "tuning algo: default is 0=(SW), 1=(HW)"); - -#define HAS_LOCK 1 -#define ATTEMPT_TUNE 2 -#define HAS_POWER 4 - -#define DST_ERROR 0 -#define DST_NOTICE 1 -#define DST_INFO 2 -#define DST_DEBUG 3 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((x > DST_ERROR) && (x > y)) \ - printk(KERN_ERR "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_INFO) && (x > y)) \ - printk(KERN_INFO "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - else if ((x > DST_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "dst(%d) %s: " format "\n", \ - state->bt->nr, __func__ , ##arg); \ - } else { \ - if (x > y) \ - printk(format, ##arg); \ - } \ -} while(0) - -static int dst_command(struct dst_state *state, u8 *data, u8 len); - -static void dst_packsize(struct dst_state *state, int psize) -{ - union dst_gpio_packet bits; - - bits.psize = psize; - bt878_device_control(state->bt, DST_IG_TS, &bits); -} - -static int dst_gpio_outb(struct dst_state *state, u32 mask, u32 enbb, - u32 outhigh, int delay) -{ - union dst_gpio_packet enb; - union dst_gpio_packet bits; - int err; - - enb.enb.mask = mask; - enb.enb.enable = enbb; - - dprintk(verbose, DST_INFO, 1, "mask=[%04x], enbb=[%04x], outhigh=[%04x]", mask, enbb, outhigh); - if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { - dprintk(verbose, DST_INFO, 1, "dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)", err, mask, enbb); - return -EREMOTEIO; - } - udelay(1000); - /* because complete disabling means no output, no need to do output packet */ - if (enbb == 0) - return 0; - if (delay) - msleep(10); - bits.outp.mask = enbb; - bits.outp.highvals = outhigh; - if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { - dprintk(verbose, DST_INFO, 1, "dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)", err, enbb, outhigh); - return -EREMOTEIO; - } - - return 0; -} - -static int dst_gpio_inb(struct dst_state *state, u8 *result) -{ - union dst_gpio_packet rd_packet; - int err; - - *result = 0; - if ((err = bt878_device_control(state->bt, DST_IG_READ, &rd_packet)) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb error (err == %i)", err); - return -EREMOTEIO; - } - *result = (u8) rd_packet.rd.value; - - return 0; -} - -int rdc_reset_state(struct dst_state *state) -{ - dprintk(verbose, DST_INFO, 1, "Resetting state machine"); - if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); - return -1; - } - msleep(10); - if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); - msleep(10); - return -1; - } - - return 0; -} -EXPORT_SYMBOL(rdc_reset_state); - -static int rdc_8820_reset(struct dst_state *state) -{ - dprintk(verbose, DST_DEBUG, 1, "Resetting DST"); - if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); - return -1; - } - udelay(1000); - if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); - return -1; - } - - return 0; -} - -static int dst_pio_enable(struct dst_state *state) -{ - if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); - return -1; - } - udelay(1000); - - return 0; -} - -int dst_pio_disable(struct dst_state *state) -{ - if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_outb ERROR !"); - return -1; - } - if (state->type_flags & DST_TYPE_HAS_FW_1) - udelay(1000); - - return 0; -} -EXPORT_SYMBOL(dst_pio_disable); - -int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode) -{ - u8 reply; - int i; - - for (i = 0; i < 200; i++) { - if (dst_gpio_inb(state, &reply) < 0) { - dprintk(verbose, DST_ERROR, 1, "dst_gpio_inb ERROR !"); - return -1; - } - if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { - dprintk(verbose, DST_INFO, 1, "dst wait ready after %d", i); - return 1; - } - msleep(10); - } - dprintk(verbose, DST_NOTICE, 1, "dst wait NOT ready after %d", i); - - return 0; -} -EXPORT_SYMBOL(dst_wait_dst_ready); - -int dst_error_recovery(struct dst_state *state) -{ - dprintk(verbose, DST_NOTICE, 1, "Trying to return from previous errors."); - dst_pio_disable(state); - msleep(10); - dst_pio_enable(state); - msleep(10); - - return 0; -} -EXPORT_SYMBOL(dst_error_recovery); - -int dst_error_bailout(struct dst_state *state) -{ - dprintk(verbose, DST_INFO, 1, "Trying to bailout from previous error."); - rdc_8820_reset(state); - dst_pio_disable(state); - msleep(10); - - return 0; -} -EXPORT_SYMBOL(dst_error_bailout); - -int dst_comm_init(struct dst_state *state) -{ - dprintk(verbose, DST_INFO, 1, "Initializing DST."); - if ((dst_pio_enable(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "PIO Enable Failed"); - return -1; - } - if ((rdc_reset_state(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "RDC 8820 State RESET Failed."); - return -1; - } - if (state->type_flags & DST_TYPE_HAS_FW_1) - msleep(100); - else - msleep(5); - - return 0; -} -EXPORT_SYMBOL(dst_comm_init); - -int write_dst(struct dst_state *state, u8 *data, u8 len) -{ - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = data, - .len = len - }; - - int err; - u8 cnt, i; - - dprintk(verbose, DST_NOTICE, 0, "writing [ "); - for (i = 0; i < len; i++) - dprintk(verbose, DST_NOTICE, 0, "%02x ", data[i]); - dprintk(verbose, DST_NOTICE, 0, "]\n"); - - for (cnt = 0; cnt < 2; cnt++) { - if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { - dprintk(verbose, DST_INFO, 1, "_write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, data[0]); - dst_error_recovery(state); - continue; - } else - break; - } - if (cnt >= 2) { - dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET"); - dst_error_bailout(state); - - return -1; - } - - return 0; -} -EXPORT_SYMBOL(write_dst); - -int read_dst(struct dst_state *state, u8 *ret, u8 len) -{ - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = ret, - .len = len - }; - - int err; - int cnt; - - for (cnt = 0; cnt < 2; cnt++) { - if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { - dprintk(verbose, DST_INFO, 1, "read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)", err, len, ret[0]); - dst_error_recovery(state); - continue; - } else - break; - } - if (cnt >= 2) { - dprintk(verbose, DST_INFO, 1, "RDC 8820 RESET"); - dst_error_bailout(state); - - return -1; - } - dprintk(verbose, DST_DEBUG, 1, "reply is 0x%x", ret[0]); - for (err = 1; err < len; err++) - dprintk(verbose, DST_DEBUG, 0, " 0x%x", ret[err]); - if (err > 1) - dprintk(verbose, DST_DEBUG, 0, "\n"); - - return 0; -} -EXPORT_SYMBOL(read_dst); - -static int dst_set_polarization(struct dst_state *state) -{ - switch (state->voltage) { - case SEC_VOLTAGE_13: /* Vertical */ - dprintk(verbose, DST_INFO, 1, "Polarization=[Vertical]"); - state->tx_tuna[8] &= ~0x40; - break; - case SEC_VOLTAGE_18: /* Horizontal */ - dprintk(verbose, DST_INFO, 1, "Polarization=[Horizontal]"); - state->tx_tuna[8] |= 0x40; - break; - case SEC_VOLTAGE_OFF: - break; - } - - return 0; -} - -static int dst_set_freq(struct dst_state *state, u32 freq) -{ - state->frequency = freq; - dprintk(verbose, DST_INFO, 1, "set Frequency %u", freq); - - if (state->dst_type == DST_TYPE_IS_SAT) { - freq = freq / 1000; - if (freq < 950 || freq > 2150) - return -EINVAL; - state->tx_tuna[2] = (freq >> 8); - state->tx_tuna[3] = (u8) freq; - state->tx_tuna[4] = 0x01; - state->tx_tuna[8] &= ~0x04; - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { - if (freq < 1531) - state->tx_tuna[8] |= 0x04; - } - } else if (state->dst_type == DST_TYPE_IS_TERR) { - freq = freq / 1000; - if (freq < 137000 || freq > 858000) - return -EINVAL; - state->tx_tuna[2] = (freq >> 16) & 0xff; - state->tx_tuna[3] = (freq >> 8) & 0xff; - state->tx_tuna[4] = (u8) freq; - } else if (state->dst_type == DST_TYPE_IS_CABLE) { - freq = freq / 1000; - state->tx_tuna[2] = (freq >> 16) & 0xff; - state->tx_tuna[3] = (freq >> 8) & 0xff; - state->tx_tuna[4] = (u8) freq; - } else if (state->dst_type == DST_TYPE_IS_ATSC) { - freq = freq / 1000; - if (freq < 51000 || freq > 858000) - return -EINVAL; - state->tx_tuna[2] = (freq >> 16) & 0xff; - state->tx_tuna[3] = (freq >> 8) & 0xff; - state->tx_tuna[4] = (u8) freq; - state->tx_tuna[5] = 0x00; /* ATSC */ - state->tx_tuna[6] = 0x00; - if (state->dst_hw_cap & DST_TYPE_HAS_ANALOG) - state->tx_tuna[7] = 0x00; /* Digital */ - } else - return -EINVAL; - - return 0; -} - -static int dst_set_bandwidth(struct dst_state *state, fe_bandwidth_t bandwidth) -{ - state->bandwidth = bandwidth; - - if (state->dst_type != DST_TYPE_IS_TERR) - return -EOPNOTSUPP; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - if (state->dst_hw_cap & DST_TYPE_HAS_CA) - state->tx_tuna[7] = 0x06; - else { - state->tx_tuna[6] = 0x06; - state->tx_tuna[7] = 0x00; - } - break; - case BANDWIDTH_7_MHZ: - if (state->dst_hw_cap & DST_TYPE_HAS_CA) - state->tx_tuna[7] = 0x07; - else { - state->tx_tuna[6] = 0x07; - state->tx_tuna[7] = 0x00; - } - break; - case BANDWIDTH_8_MHZ: - if (state->dst_hw_cap & DST_TYPE_HAS_CA) - state->tx_tuna[7] = 0x08; - else { - state->tx_tuna[6] = 0x08; - state->tx_tuna[7] = 0x00; - } - break; - default: - return -EINVAL; - } - - return 0; -} - -static int dst_set_inversion(struct dst_state *state, fe_spectral_inversion_t inversion) -{ - state->inversion = inversion; - switch (inversion) { - case INVERSION_OFF: /* Inversion = Normal */ - state->tx_tuna[8] &= ~0x80; - break; - case INVERSION_ON: - state->tx_tuna[8] |= 0x80; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int dst_set_fec(struct dst_state *state, fe_code_rate_t fec) -{ - state->fec = fec; - return 0; -} - -static fe_code_rate_t dst_get_fec(struct dst_state *state) -{ - return state->fec; -} - -static int dst_set_symbolrate(struct dst_state *state, u32 srate) -{ - u32 symcalc; - u64 sval; - - state->symbol_rate = srate; - if (state->dst_type == DST_TYPE_IS_TERR) { - return -EOPNOTSUPP; - } - dprintk(verbose, DST_INFO, 1, "set symrate %u", srate); - srate /= 1000; - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_SYMDIV) { - sval = srate; - sval <<= 20; - do_div(sval, 88000); - symcalc = (u32) sval; - dprintk(verbose, DST_INFO, 1, "set symcalc %u", symcalc); - state->tx_tuna[5] = (u8) (symcalc >> 12); - state->tx_tuna[6] = (u8) (symcalc >> 4); - state->tx_tuna[7] = (u8) (symcalc << 4); - } else { - state->tx_tuna[5] = (u8) (srate >> 16) & 0x7f; - state->tx_tuna[6] = (u8) (srate >> 8); - state->tx_tuna[7] = (u8) srate; - } - state->tx_tuna[8] &= ~0x20; - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) { - if (srate > 8000) - state->tx_tuna[8] |= 0x20; - } - } else if (state->dst_type == DST_TYPE_IS_CABLE) { - dprintk(verbose, DST_DEBUG, 1, "%s", state->fw_name); - if (!strncmp(state->fw_name, "DCTNEW", 6)) { - state->tx_tuna[5] = (u8) (srate >> 8); - state->tx_tuna[6] = (u8) srate; - state->tx_tuna[7] = 0x00; - } else if (!strncmp(state->fw_name, "DCT-CI", 6)) { - state->tx_tuna[5] = 0x00; - state->tx_tuna[6] = (u8) (srate >> 8); - state->tx_tuna[7] = (u8) srate; - } - } - return 0; -} - -static int dst_set_modulation(struct dst_state *state, fe_modulation_t modulation) -{ - if (state->dst_type != DST_TYPE_IS_CABLE) - return -EOPNOTSUPP; - - state->modulation = modulation; - switch (modulation) { - case QAM_16: - state->tx_tuna[8] = 0x10; - break; - case QAM_32: - state->tx_tuna[8] = 0x20; - break; - case QAM_64: - state->tx_tuna[8] = 0x40; - break; - case QAM_128: - state->tx_tuna[8] = 0x80; - break; - case QAM_256: - if (!strncmp(state->fw_name, "DCTNEW", 6)) - state->tx_tuna[8] = 0xff; - else if (!strncmp(state->fw_name, "DCT-CI", 6)) - state->tx_tuna[8] = 0x00; - break; - case QPSK: - case QAM_AUTO: - case VSB_8: - case VSB_16: - default: - return -EINVAL; - - } - - return 0; -} - -static fe_modulation_t dst_get_modulation(struct dst_state *state) -{ - return state->modulation; -} - - -u8 dst_check_sum(u8 *buf, u32 len) -{ - u32 i; - u8 val = 0; - if (!len) - return 0; - for (i = 0; i < len; i++) { - val += buf[i]; - } - return ((~val) + 1); -} -EXPORT_SYMBOL(dst_check_sum); - -static void dst_type_flags_print(struct dst_state *state) -{ - u32 type_flags = state->type_flags; - - dprintk(verbose, DST_ERROR, 0, "DST type flags :"); - if (type_flags & DST_TYPE_HAS_TS188) - dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner", DST_TYPE_HAS_TS188); - if (type_flags & DST_TYPE_HAS_NEWTUNE_2) - dprintk(verbose, DST_ERROR, 0, " 0x%x newtuner 2", DST_TYPE_HAS_NEWTUNE_2); - if (type_flags & DST_TYPE_HAS_TS204) - dprintk(verbose, DST_ERROR, 0, " 0x%x ts204", DST_TYPE_HAS_TS204); - if (type_flags & DST_TYPE_HAS_VLF) - dprintk(verbose, DST_ERROR, 0, " 0x%x VLF", DST_TYPE_HAS_VLF); - if (type_flags & DST_TYPE_HAS_SYMDIV) - dprintk(verbose, DST_ERROR, 0, " 0x%x symdiv", DST_TYPE_HAS_SYMDIV); - if (type_flags & DST_TYPE_HAS_FW_1) - dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 1", DST_TYPE_HAS_FW_1); - if (type_flags & DST_TYPE_HAS_FW_2) - dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 2", DST_TYPE_HAS_FW_2); - if (type_flags & DST_TYPE_HAS_FW_3) - dprintk(verbose, DST_ERROR, 0, " 0x%x firmware version = 3", DST_TYPE_HAS_FW_3); - dprintk(verbose, DST_ERROR, 0, "\n"); -} - - -static int dst_type_print(struct dst_state *state, u8 type) -{ - char *otype; - switch (type) { - case DST_TYPE_IS_SAT: - otype = "satellite"; - break; - - case DST_TYPE_IS_TERR: - otype = "terrestrial"; - break; - - case DST_TYPE_IS_CABLE: - otype = "cable"; - break; - - case DST_TYPE_IS_ATSC: - otype = "atsc"; - break; - - default: - dprintk(verbose, DST_INFO, 1, "invalid dst type %d", type); - return -EINVAL; - } - dprintk(verbose, DST_INFO, 1, "DST type: %s", otype); - - return 0; -} - -static struct tuner_types tuner_list[] = { - { - .tuner_type = TUNER_TYPE_L64724, - .tuner_name = "L 64724", - .board_name = "UNKNOWN", - .fw_name = "UNKNOWN" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1020", - .fw_name = "DST-MOT" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1020", - .fw_name = "DST-03T" - }, - - { - .tuner_type = TUNER_TYPE_MB86A15, - .tuner_name = "MB 86A15", - .board_name = "VP1022", - .fw_name = "DST-03T" - }, - - { - .tuner_type = TUNER_TYPE_MB86A15, - .tuner_name = "MB 86A15", - .board_name = "VP1025", - .fw_name = "DST-03T" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1030", - .fw_name = "DST-CI" - }, - - { - .tuner_type = TUNER_TYPE_STV0299, - .tuner_name = "STV 0299", - .board_name = "VP1030", - .fw_name = "DSTMCI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2021", - .fw_name = "DCTNEW" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2030", - .fw_name = "DCT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2031", - .fw_name = "DCT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP2040", - .fw_name = "DCT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP3020", - .fw_name = "DTTFTA" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP3021", - .fw_name = "DTTFTA" - }, - - { - .tuner_type = TUNER_TYPE_TDA10046, - .tuner_name = "TDA10046", - .board_name = "VP3040", - .fw_name = "DTT-CI" - }, - - { - .tuner_type = TUNER_TYPE_UNKNOWN, - .tuner_name = "UNKNOWN", - .board_name = "VP3051", - .fw_name = "DTTNXT" - }, - - { - .tuner_type = TUNER_TYPE_NXT200x, - .tuner_name = "NXT200x", - .board_name = "VP3220", - .fw_name = "ATSCDI" - }, - - { - .tuner_type = TUNER_TYPE_NXT200x, - .tuner_name = "NXT200x", - .board_name = "VP3250", - .fw_name = "ATSCAD" - }, -}; - -/* - Known cards list - Satellite - ------------------- - 200103A - VP-1020 DST-MOT LG(old), TS=188 - - VP-1020 DST-03T LG(new), TS=204 - VP-1022 DST-03T LG(new), TS=204 - VP-1025 DST-03T LG(new), TS=204 - - VP-1030 DSTMCI, LG(new), TS=188 - VP-1032 DSTMCI, LG(new), TS=188 - - Cable - ------------------- - VP-2030 DCT-CI, Samsung, TS=204 - VP-2021 DCT-CI, Unknown, TS=204 - VP-2031 DCT-CI, Philips, TS=188 - VP-2040 DCT-CI, Philips, TS=188, with CA daughter board - VP-2040 DCT-CI, Philips, TS=204, without CA daughter board - - Terrestrial - ------------------- - VP-3050 DTTNXT TS=188 - VP-3040 DTT-CI, Philips, TS=188 - VP-3040 DTT-CI, Philips, TS=204 - - ATSC - ------------------- - VP-3220 ATSCDI, TS=188 - VP-3250 ATSCAD, TS=188 - -*/ - -static struct dst_types dst_tlist[] = { - { - .device_id = "200103A", - .offset = 0, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_OBS_REGS, - .dst_feature = 0, - .tuner_type = 0 - }, /* obsolete */ - - { - .device_id = "DST-020", - .offset = 0, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 - }, /* obsolete */ - - { - .device_id = "DST-030", - .offset = 0, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 - }, /* obsolete */ - - { - .device_id = "DST-03T", - .offset = 0, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, - .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 - | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO, - .tuner_type = TUNER_TYPE_MULTI - }, - - { - .device_id = "DST-MOT", - .offset = 0, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 - }, /* obsolete */ - - { - .device_id = "DST-CI", - .offset = 1, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_1, - .dst_feature = DST_TYPE_HAS_CA, - .tuner_type = 0 - }, /* An OEM board */ - - { - .device_id = "DSTMCI", - .offset = 1, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_INC_COUNT | DST_TYPE_HAS_VLF, - .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 - | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC, - .tuner_type = TUNER_TYPE_MULTI - }, - - { - .device_id = "DSTFCI", - .offset = 1, - .dst_type = DST_TYPE_IS_SAT, - .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_1, - .dst_feature = 0, - .tuner_type = 0 - }, /* unknown to vendor */ - - { - .device_id = "DCT-CI", - .offset = 1, - .dst_type = DST_TYPE_IS_CABLE, - .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_1 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_VLF, - .dst_feature = DST_TYPE_HAS_CA, - .tuner_type = 0 - }, - - { - .device_id = "DCTNEW", - .offset = 1, - .dst_type = DST_TYPE_IS_CABLE, - .type_flags = DST_TYPE_HAS_TS188 | DST_TYPE_HAS_FW_3 | DST_TYPE_HAS_FW_BUILD | DST_TYPE_HAS_MULTI_FE, - .dst_feature = 0, - .tuner_type = 0 - }, - - { - .device_id = "DTT-CI", - .offset = 1, - .dst_type = DST_TYPE_IS_TERR, - .type_flags = DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_VLF, - .dst_feature = DST_TYPE_HAS_CA, - .tuner_type = 0 - }, - - { - .device_id = "DTTDIG", - .offset = 1, - .dst_type = DST_TYPE_IS_TERR, - .type_flags = DST_TYPE_HAS_FW_2, - .dst_feature = 0, - .tuner_type = 0 - }, - - { - .device_id = "DTTNXT", - .offset = 1, - .dst_type = DST_TYPE_IS_TERR, - .type_flags = DST_TYPE_HAS_FW_2, - .dst_feature = DST_TYPE_HAS_ANALOG, - .tuner_type = 0 - }, - - { - .device_id = "ATSCDI", - .offset = 1, - .dst_type = DST_TYPE_IS_ATSC, - .type_flags = DST_TYPE_HAS_FW_2, - .dst_feature = 0, - .tuner_type = 0 - }, - - { - .device_id = "ATSCAD", - .offset = 1, - .dst_type = DST_TYPE_IS_ATSC, - .type_flags = DST_TYPE_HAS_MULTI_FE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, - .dst_feature = DST_TYPE_HAS_MAC | DST_TYPE_HAS_ANALOG, - .tuner_type = 0 - }, - - { } - -}; - -static int dst_get_mac(struct dst_state *state) -{ - u8 get_mac[] = { 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - get_mac[7] = dst_check_sum(get_mac, 7); - if (dst_command(state, get_mac, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); - return -1; - } - memset(&state->mac_address, '\0', 8); - memcpy(&state->mac_address, &state->rxbuffer, 6); - dprintk(verbose, DST_ERROR, 1, "MAC Address=[%pM]", state->mac_address); - - return 0; -} - -static int dst_fw_ver(struct dst_state *state) -{ - u8 get_ver[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - get_ver[7] = dst_check_sum(get_ver, 7); - if (dst_command(state, get_ver, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); - return -1; - } - memset(&state->fw_version, '\0', 8); - memcpy(&state->fw_version, &state->rxbuffer, 8); - dprintk(verbose, DST_ERROR, 1, "Firmware Ver = %x.%x Build = %02x, on %x:%x, %x-%x-20%02x", - state->fw_version[0] >> 4, state->fw_version[0] & 0x0f, - state->fw_version[1], - state->fw_version[5], state->fw_version[6], - state->fw_version[4], state->fw_version[3], state->fw_version[2]); - - return 0; -} - -static int dst_card_type(struct dst_state *state) -{ - int j; - struct tuner_types *p_tuner_list = NULL; - - u8 get_type[] = { 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - get_type[7] = dst_check_sum(get_type, 7); - if (dst_command(state, get_type, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); - return -1; - } - memset(&state->card_info, '\0', 8); - memcpy(&state->card_info, &state->rxbuffer, 7); - dprintk(verbose, DST_ERROR, 1, "Device Model=[%s]", &state->card_info[0]); - - for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { - if (!strcmp(&state->card_info[0], p_tuner_list->board_name)) { - state->tuner_type = p_tuner_list->tuner_type; - dprintk(verbose, DST_ERROR, 1, "DST has [%s] tuner, tuner type=[%d]", - p_tuner_list->tuner_name, p_tuner_list->tuner_type); - } - } - - return 0; -} - -static int dst_get_vendor(struct dst_state *state) -{ - u8 get_vendor[] = { 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - get_vendor[7] = dst_check_sum(get_vendor, 7); - if (dst_command(state, get_vendor, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Unsupported Command"); - return -1; - } - memset(&state->vendor, '\0', 8); - memcpy(&state->vendor, &state->rxbuffer, 7); - dprintk(verbose, DST_ERROR, 1, "Vendor=[%s]", &state->vendor[0]); - - return 0; -} - -static void debug_dst_buffer(struct dst_state *state) -{ - int i; - - if (verbose > 2) { - printk("%s: [", __func__); - for (i = 0; i < 8; i++) - printk(" %02x", state->rxbuffer[i]); - printk("]\n"); - } -} - -static int dst_check_stv0299(struct dst_state *state) -{ - u8 check_stv0299[] = { 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - check_stv0299[7] = dst_check_sum(check_stv0299, 7); - if (dst_command(state, check_stv0299, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Cmd=[0x04] failed"); - return -1; - } - debug_dst_buffer(state); - - if (memcmp(&check_stv0299, &state->rxbuffer, 8)) { - dprintk(verbose, DST_ERROR, 1, "Found a STV0299 NIM"); - state->tuner_type = TUNER_TYPE_STV0299; - return 0; - } - - return -1; -} - -static int dst_check_mb86a15(struct dst_state *state) -{ - u8 check_mb86a15[] = { 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - check_mb86a15[7] = dst_check_sum(check_mb86a15, 7); - if (dst_command(state, check_mb86a15, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Cmd=[0x10], failed"); - return -1; - } - debug_dst_buffer(state); - - if (memcmp(&check_mb86a15, &state->rxbuffer, 8) < 0) { - dprintk(verbose, DST_ERROR, 1, "Found a MB86A15 NIM"); - state->tuner_type = TUNER_TYPE_MB86A15; - return 0; - } - - return -1; -} - -static int dst_get_tuner_info(struct dst_state *state) -{ - u8 get_tuner_1[] = { 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - u8 get_tuner_2[] = { 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - get_tuner_1[7] = dst_check_sum(get_tuner_1, 7); - get_tuner_2[7] = dst_check_sum(get_tuner_2, 7); - dprintk(verbose, DST_ERROR, 1, "DST TYpe = MULTI FE"); - if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { - if (dst_command(state, get_tuner_1, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Cmd=[0x13], Unsupported"); - goto force; - } - } else { - if (dst_command(state, get_tuner_2, 8) < 0) { - dprintk(verbose, DST_INFO, 1, "Cmd=[0xb], Unsupported"); - goto force; - } - } - memset(&state->board_info, '\0', 8); - memcpy(&state->board_info, &state->rxbuffer, 8); - if (state->type_flags & DST_TYPE_HAS_MULTI_FE) { - dprintk(verbose, DST_ERROR, 1, "DST type has TS=188"); - } - if (state->board_info[0] == 0xbc) { - if (state->type_flags != DST_TYPE_IS_ATSC) - state->type_flags |= DST_TYPE_HAS_TS188; - else - state->type_flags |= DST_TYPE_HAS_NEWTUNE_2; - - if (state->board_info[1] == 0x01) { - state->dst_hw_cap |= DST_TYPE_HAS_DBOARD; - dprintk(verbose, DST_ERROR, 1, "DST has Daughterboard"); - } - } - - return 0; -force: - if (!strncmp(state->fw_name, "DCT-CI", 6)) { - state->type_flags |= DST_TYPE_HAS_TS204; - dprintk(verbose, DST_ERROR, 1, "Forcing [%s] to TS188", state->fw_name); - } - - return -1; -} - -static int dst_get_device_id(struct dst_state *state) -{ - u8 reply; - - int i, j; - struct dst_types *p_dst_type = NULL; - struct tuner_types *p_tuner_list = NULL; - - u8 use_dst_type = 0; - u32 use_type_flags = 0; - - static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; - - state->tuner_type = 0; - device_type[7] = dst_check_sum(device_type, 7); - - if (write_dst(state, device_type, FIXED_COMM)) - return -1; /* Write failed */ - if ((dst_pio_disable(state)) < 0) - return -1; - if (read_dst(state, &reply, GET_ACK)) - return -1; /* Read failure */ - if (reply != ACK) { - dprintk(verbose, DST_INFO, 1, "Write not Acknowledged! [Reply=0x%02x]", reply); - return -1; /* Unack'd write */ - } - if (!dst_wait_dst_ready(state, DEVICE_INIT)) - return -1; /* DST not ready yet */ - if (read_dst(state, state->rxbuffer, FIXED_COMM)) - return -1; - - dst_pio_disable(state); - if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { - dprintk(verbose, DST_INFO, 1, "Checksum failure!"); - return -1; /* Checksum failure */ - } - state->rxbuffer[7] = '\0'; - - for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE(dst_tlist); i++, p_dst_type++) { - if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) { - use_type_flags = p_dst_type->type_flags; - use_dst_type = p_dst_type->dst_type; - - /* Card capabilities */ - state->dst_hw_cap = p_dst_type->dst_feature; - dprintk(verbose, DST_ERROR, 1, "Recognise [%s]", p_dst_type->device_id); - strncpy(&state->fw_name[0], p_dst_type->device_id, 6); - /* Multiple tuners */ - if (p_dst_type->tuner_type & TUNER_TYPE_MULTI) { - switch (use_dst_type) { - case DST_TYPE_IS_SAT: - /* STV0299 check */ - if (dst_check_stv0299(state) < 0) { - dprintk(verbose, DST_ERROR, 1, "Unsupported"); - state->tuner_type = TUNER_TYPE_MB86A15; - } - break; - default: - break; - } - if (dst_check_mb86a15(state) < 0) - dprintk(verbose, DST_ERROR, 1, "Unsupported"); - /* Single tuner */ - } else { - state->tuner_type = p_dst_type->tuner_type; - } - for (j = 0, p_tuner_list = tuner_list; j < ARRAY_SIZE(tuner_list); j++, p_tuner_list++) { - if (!(strncmp(p_dst_type->device_id, p_tuner_list->fw_name, 7)) && - p_tuner_list->tuner_type == state->tuner_type) { - dprintk(verbose, DST_ERROR, 1, "[%s] has a [%s]", - p_dst_type->device_id, p_tuner_list->tuner_name); - } - } - break; - } - } - - if (i >= ARRAY_SIZE(dst_tlist)) { - dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]); - dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in"); - use_dst_type = DST_TYPE_IS_SAT; - use_type_flags = DST_TYPE_HAS_SYMDIV; - } - dst_type_print(state, use_dst_type); - state->type_flags = use_type_flags; - state->dst_type = use_dst_type; - dst_type_flags_print(state); - - return 0; -} - -static int dst_probe(struct dst_state *state) -{ - mutex_init(&state->dst_mutex); - if (dst_addons & DST_TYPE_HAS_CA) { - if ((rdc_8820_reset(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "RDC 8820 RESET Failed."); - return -1; - } - msleep(4000); - } else { - msleep(100); - } - if ((dst_comm_init(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "DST Initialization Failed."); - return -1; - } - msleep(100); - if (dst_get_device_id(state) < 0) { - dprintk(verbose, DST_ERROR, 1, "unknown device."); - return -1; - } - if (dst_get_mac(state) < 0) { - dprintk(verbose, DST_INFO, 1, "MAC: Unsupported command"); - } - if ((state->type_flags & DST_TYPE_HAS_MULTI_FE) || (state->type_flags & DST_TYPE_HAS_FW_BUILD)) { - if (dst_get_tuner_info(state) < 0) - dprintk(verbose, DST_INFO, 1, "Tuner: Unsupported command"); - } - if (state->type_flags & DST_TYPE_HAS_TS204) { - dst_packsize(state, 204); - } - if (state->type_flags & DST_TYPE_HAS_FW_BUILD) { - if (dst_fw_ver(state) < 0) { - dprintk(verbose, DST_INFO, 1, "FW: Unsupported command"); - return 0; - } - if (dst_card_type(state) < 0) { - dprintk(verbose, DST_INFO, 1, "Card: Unsupported command"); - return 0; - } - if (dst_get_vendor(state) < 0) { - dprintk(verbose, DST_INFO, 1, "Vendor: Unsupported command"); - return 0; - } - } - - return 0; -} - -static int dst_command(struct dst_state *state, u8 *data, u8 len) -{ - u8 reply; - - mutex_lock(&state->dst_mutex); - if ((dst_comm_init(state)) < 0) { - dprintk(verbose, DST_NOTICE, 1, "DST Communication Initialization Failed."); - goto error; - } - if (write_dst(state, data, len)) { - dprintk(verbose, DST_INFO, 1, "Trying to recover.. "); - if ((dst_error_recovery(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "Recovery Failed."); - goto error; - } - goto error; - } - if ((dst_pio_disable(state)) < 0) { - dprintk(verbose, DST_ERROR, 1, "PIO Disable Failed."); - goto error; - } - if (state->type_flags & DST_TYPE_HAS_FW_1) - mdelay(3); - if (read_dst(state, &reply, GET_ACK)) { - dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); - if ((dst_error_recovery(state)) < 0) { - dprintk(verbose, DST_INFO, 1, "Recovery Failed."); - goto error; - } - goto error; - } - if (reply != ACK) { - dprintk(verbose, DST_INFO, 1, "write not acknowledged 0x%02x ", reply); - goto error; - } - if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) - goto error; - if (state->type_flags & DST_TYPE_HAS_FW_1) - mdelay(3); - else - udelay(2000); - if (!dst_wait_dst_ready(state, NO_DELAY)) - goto error; - if (read_dst(state, state->rxbuffer, FIXED_COMM)) { - dprintk(verbose, DST_DEBUG, 1, "Trying to recover.. "); - if ((dst_error_recovery(state)) < 0) { - dprintk(verbose, DST_INFO, 1, "Recovery failed."); - goto error; - } - goto error; - } - if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { - dprintk(verbose, DST_INFO, 1, "checksum failure"); - goto error; - } - mutex_unlock(&state->dst_mutex); - return 0; - -error: - mutex_unlock(&state->dst_mutex); - return -EIO; - -} - -static int dst_get_signal(struct dst_state *state) -{ - int retval; - u8 get_signal[] = { 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb }; - //dprintk("%s: Getting Signal strength and other parameters\n", __func__); - if ((state->diseq_flags & ATTEMPT_TUNE) == 0) { - state->decode_lock = state->decode_strength = state->decode_snr = 0; - return 0; - } - if (0 == (state->diseq_flags & HAS_LOCK)) { - state->decode_lock = state->decode_strength = state->decode_snr = 0; - return 0; - } - if (time_after_eq(jiffies, state->cur_jiff + (HZ / 5))) { - retval = dst_command(state, get_signal, 8); - if (retval < 0) - return retval; - if (state->dst_type == DST_TYPE_IS_SAT) { - state->decode_lock = ((state->rxbuffer[6] & 0x10) == 0) ? 1 : 0; - state->decode_strength = state->rxbuffer[5] << 8; - state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; - } else if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) { - state->decode_lock = (state->rxbuffer[1]) ? 1 : 0; - state->decode_strength = state->rxbuffer[4] << 8; - state->decode_snr = state->rxbuffer[3] << 8; - } else if (state->dst_type == DST_TYPE_IS_ATSC) { - state->decode_lock = (state->rxbuffer[6] == 0x00) ? 1 : 0; - state->decode_strength = state->rxbuffer[4] << 8; - state->decode_snr = state->rxbuffer[2] << 8 | state->rxbuffer[3]; - } - state->cur_jiff = jiffies; - } - return 0; -} - -static int dst_tone_power_cmd(struct dst_state *state) -{ - u8 paket[8] = { 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 }; - - if (state->dst_type != DST_TYPE_IS_SAT) - return -EOPNOTSUPP; - paket[4] = state->tx_tuna[4]; - paket[2] = state->tx_tuna[2]; - paket[3] = state->tx_tuna[3]; - paket[7] = dst_check_sum (paket, 7); - return dst_command(state, paket, 8); -} - -static int dst_get_tuna(struct dst_state *state) -{ - int retval; - - if ((state->diseq_flags & ATTEMPT_TUNE) == 0) - return 0; - state->diseq_flags &= ~(HAS_LOCK); - if (!dst_wait_dst_ready(state, NO_DELAY)) - return -EIO; - if ((state->type_flags & DST_TYPE_HAS_VLF) && - !(state->dst_type == DST_TYPE_IS_ATSC)) - - retval = read_dst(state, state->rx_tuna, 10); - else - retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); - if (retval < 0) { - dprintk(verbose, DST_DEBUG, 1, "read not successful"); - return retval; - } - if ((state->type_flags & DST_TYPE_HAS_VLF) && - !(state->dst_type == DST_TYPE_IS_CABLE) && - !(state->dst_type == DST_TYPE_IS_ATSC)) { - - if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { - dprintk(verbose, DST_INFO, 1, "checksum failure ? "); - return -EIO; - } - } else { - if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[2], 7)) { - dprintk(verbose, DST_INFO, 1, "checksum failure? "); - return -EIO; - } - } - if (state->rx_tuna[2] == 0 && state->rx_tuna[3] == 0) - return 0; - if (state->dst_type == DST_TYPE_IS_SAT) { - state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 8) + state->rx_tuna[3]; - } else { - state->decode_freq = ((state->rx_tuna[2] & 0x7f) << 16) + (state->rx_tuna[3] << 8) + state->rx_tuna[4]; - } - state->decode_freq = state->decode_freq * 1000; - state->decode_lock = 1; - state->diseq_flags |= HAS_LOCK; - - return 1; -} - -static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage); - -static int dst_write_tuna(struct dvb_frontend *fe) -{ - struct dst_state *state = fe->demodulator_priv; - int retval; - u8 reply; - - dprintk(verbose, DST_INFO, 1, "type_flags 0x%x ", state->type_flags); - state->decode_freq = 0; - state->decode_lock = state->decode_strength = state->decode_snr = 0; - if (state->dst_type == DST_TYPE_IS_SAT) { - if (!(state->diseq_flags & HAS_POWER)) - dst_set_voltage(fe, SEC_VOLTAGE_13); - } - state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); - mutex_lock(&state->dst_mutex); - if ((dst_comm_init(state)) < 0) { - dprintk(verbose, DST_DEBUG, 1, "DST Communication initialization failed."); - goto error; - } -// if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { - if ((state->type_flags & DST_TYPE_HAS_VLF) && - (!(state->dst_type == DST_TYPE_IS_ATSC))) { - - state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); - retval = write_dst(state, &state->tx_tuna[0], 10); - } else { - state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); - retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); - } - if (retval < 0) { - dst_pio_disable(state); - dprintk(verbose, DST_DEBUG, 1, "write not successful"); - goto werr; - } - if ((dst_pio_disable(state)) < 0) { - dprintk(verbose, DST_DEBUG, 1, "DST PIO disable failed !"); - goto error; - } - if ((read_dst(state, &reply, GET_ACK) < 0)) { - dprintk(verbose, DST_DEBUG, 1, "read verify not successful."); - goto error; - } - if (reply != ACK) { - dprintk(verbose, DST_DEBUG, 1, "write not acknowledged 0x%02x ", reply); - goto error; - } - state->diseq_flags |= ATTEMPT_TUNE; - retval = dst_get_tuna(state); -werr: - mutex_unlock(&state->dst_mutex); - return retval; - -error: - mutex_unlock(&state->dst_mutex); - return -EIO; -} - -/* - * line22k0 0x00, 0x09, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00 - * line22k1 0x00, 0x09, 0x01, 0xff, 0x01, 0x00, 0x00, 0x00 - * line22k2 0x00, 0x09, 0x02, 0xff, 0x01, 0x00, 0x00, 0x00 - * tone 0x00, 0x09, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00 - * data 0x00, 0x09, 0xff, 0x01, 0x01, 0x00, 0x00, 0x00 - * power_off 0x00, 0x09, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 - * power_on 0x00, 0x09, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 - * Diseqc 1 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec - * Diseqc 2 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf4, 0xe8 - * Diseqc 3 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf8, 0xe4 - * Diseqc 4 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xfc, 0xe0 - */ - -static int dst_set_diseqc(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) -{ - struct dst_state *state = fe->demodulator_priv; - u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; - - if (state->dst_type != DST_TYPE_IS_SAT) - return -EOPNOTSUPP; - if (cmd->msg_len > 0 && cmd->msg_len < 5) - memcpy(&paket[3], cmd->msg, cmd->msg_len); - else if (cmd->msg_len == 5 && state->dst_hw_cap & DST_TYPE_HAS_DISEQC5) - memcpy(&paket[2], cmd->msg, cmd->msg_len); - else - return -EINVAL; - paket[7] = dst_check_sum(&paket[0], 7); - return dst_command(state, paket, 8); -} - -static int dst_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - int need_cmd, retval = 0; - struct dst_state *state = fe->demodulator_priv; - - state->voltage = voltage; - if (state->dst_type != DST_TYPE_IS_SAT) - return -EOPNOTSUPP; - - need_cmd = 0; - - switch (voltage) { - case SEC_VOLTAGE_13: - case SEC_VOLTAGE_18: - if ((state->diseq_flags & HAS_POWER) == 0) - need_cmd = 1; - state->diseq_flags |= HAS_POWER; - state->tx_tuna[4] = 0x01; - break; - case SEC_VOLTAGE_OFF: - need_cmd = 1; - state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); - state->tx_tuna[4] = 0x00; - break; - default: - return -EINVAL; - } - - if (need_cmd) - retval = dst_tone_power_cmd(state); - - return retval; -} - -static int dst_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct dst_state *state = fe->demodulator_priv; - - state->tone = tone; - if (state->dst_type != DST_TYPE_IS_SAT) - return -EOPNOTSUPP; - - switch (tone) { - case SEC_TONE_OFF: - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) - state->tx_tuna[2] = 0x00; - else - state->tx_tuna[2] = 0xff; - break; - - case SEC_TONE_ON: - state->tx_tuna[2] = 0x02; - break; - default: - return -EINVAL; - } - return dst_tone_power_cmd(state); -} - -static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) -{ - struct dst_state *state = fe->demodulator_priv; - - if (state->dst_type != DST_TYPE_IS_SAT) - return -EOPNOTSUPP; - state->minicmd = minicmd; - switch (minicmd) { - case SEC_MINI_A: - state->tx_tuna[3] = 0x02; - break; - case SEC_MINI_B: - state->tx_tuna[3] = 0xff; - break; - } - return dst_tone_power_cmd(state); -} - - -static int dst_init(struct dvb_frontend *fe) -{ - struct dst_state *state = fe->demodulator_priv; - - static u8 sat_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x00, 0x73, 0x21, 0x00, 0x00 }; - static u8 sat_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x55, 0xbd, 0x50, 0x00, 0x00 }; - static u8 ter_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static u8 ter_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static u8 cab_tuna_188[] = { 0x09, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static u8 cab_tuna_204[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - static u8 atsc_tuner[] = { 0x00, 0x00, 0x03, 0xb6, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00 }; - - state->inversion = INVERSION_OFF; - state->voltage = SEC_VOLTAGE_13; - state->tone = SEC_TONE_OFF; - state->diseq_flags = 0; - state->k22 = 0x02; - state->bandwidth = BANDWIDTH_7_MHZ; - state->cur_jiff = jiffies; - if (state->dst_type == DST_TYPE_IS_SAT) - memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? sat_tuna_188 : sat_tuna_204), sizeof (sat_tuna_204)); - else if (state->dst_type == DST_TYPE_IS_TERR) - memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? ter_tuna_188 : ter_tuna_204), sizeof (ter_tuna_204)); - else if (state->dst_type == DST_TYPE_IS_CABLE) - memcpy(state->tx_tuna, ((state->type_flags & DST_TYPE_HAS_VLF) ? cab_tuna_188 : cab_tuna_204), sizeof (cab_tuna_204)); - else if (state->dst_type == DST_TYPE_IS_ATSC) - memcpy(state->tx_tuna, atsc_tuner, sizeof (atsc_tuner)); - - return 0; -} - -static int dst_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct dst_state *state = fe->demodulator_priv; - - *status = 0; - if (state->diseq_flags & HAS_LOCK) { -// dst_get_signal(state); // don't require(?) to ask MCU - if (state->decode_lock) - *status |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; - } - - return 0; -} - -static int dst_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dst_state *state = fe->demodulator_priv; - - int retval = dst_get_signal(state); - *strength = state->decode_strength; - - return retval; -} - -static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct dst_state *state = fe->demodulator_priv; - - int retval = dst_get_signal(state); - *snr = state->decode_snr; - - return retval; -} - -static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - int retval = -EINVAL; - struct dst_state *state = fe->demodulator_priv; - - if (p != NULL) { - retval = dst_set_freq(state, p->frequency); - if(retval != 0) - return retval; - dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); - - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) - dst_set_inversion(state, p->inversion); - dst_set_fec(state, p->u.qpsk.fec_inner); - dst_set_symbolrate(state, p->u.qpsk.symbol_rate); - dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); - - } else if (state->dst_type == DST_TYPE_IS_TERR) - dst_set_bandwidth(state, p->u.ofdm.bandwidth); - else if (state->dst_type == DST_TYPE_IS_CABLE) { - dst_set_fec(state, p->u.qam.fec_inner); - dst_set_symbolrate(state, p->u.qam.symbol_rate); - dst_set_modulation(state, p->u.qam.modulation); - } - retval = dst_write_tuna(fe); - } - - return retval; -} - -static int dst_tune_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters* p, - unsigned int mode_flags, - unsigned int *delay, - fe_status_t *status) -{ - struct dst_state *state = fe->demodulator_priv; - - if (p != NULL) { - dst_set_freq(state, p->frequency); - dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); - - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) - dst_set_inversion(state, p->inversion); - dst_set_fec(state, p->u.qpsk.fec_inner); - dst_set_symbolrate(state, p->u.qpsk.symbol_rate); - dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); - - } else if (state->dst_type == DST_TYPE_IS_TERR) - dst_set_bandwidth(state, p->u.ofdm.bandwidth); - else if (state->dst_type == DST_TYPE_IS_CABLE) { - dst_set_fec(state, p->u.qam.fec_inner); - dst_set_symbolrate(state, p->u.qam.symbol_rate); - dst_set_modulation(state, p->u.qam.modulation); - } - dst_write_tuna(fe); - } - - if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) - dst_read_status(fe, status); - - *delay = HZ/10; - return 0; -} - -static int dst_get_tuning_algo(struct dvb_frontend *fe) -{ - return dst_algo; -} - -static int dst_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct dst_state *state = fe->demodulator_priv; - - p->frequency = state->decode_freq; - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) - p->inversion = state->inversion; - p->u.qpsk.symbol_rate = state->symbol_rate; - p->u.qpsk.fec_inner = dst_get_fec(state); - } else if (state->dst_type == DST_TYPE_IS_TERR) { - p->u.ofdm.bandwidth = state->bandwidth; - } else if (state->dst_type == DST_TYPE_IS_CABLE) { - p->u.qam.symbol_rate = state->symbol_rate; - p->u.qam.fec_inner = dst_get_fec(state); - p->u.qam.modulation = dst_get_modulation(state); - } - - return 0; -} - -static void dst_release(struct dvb_frontend *fe) -{ - struct dst_state *state = fe->demodulator_priv; - if (state->dst_ca) { - dvb_unregister_device(state->dst_ca); -#ifdef CONFIG_MEDIA_ATTACH - symbol_put(dst_ca_attach); -#endif - } - kfree(state); -} - -static struct dvb_frontend_ops dst_dvbt_ops; -static struct dvb_frontend_ops dst_dvbs_ops; -static struct dvb_frontend_ops dst_dvbc_ops; -static struct dvb_frontend_ops dst_atsc_ops; - -struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) -{ - /* check if the ASIC is there */ - if (dst_probe(state) < 0) { - kfree(state); - return NULL; - } - /* determine settings based on type */ - /* create dvb_frontend */ - switch (state->dst_type) { - case DST_TYPE_IS_TERR: - memcpy(&state->frontend.ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); - break; - case DST_TYPE_IS_CABLE: - memcpy(&state->frontend.ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); - break; - case DST_TYPE_IS_SAT: - memcpy(&state->frontend.ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); - break; - case DST_TYPE_IS_ATSC: - memcpy(&state->frontend.ops, &dst_atsc_ops, sizeof(struct dvb_frontend_ops)); - break; - default: - dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist."); - kfree(state); - return NULL; - } - state->frontend.demodulator_priv = state; - - return state; /* Manu (DST is a card not a frontend) */ -} - -EXPORT_SYMBOL(dst_attach); - -static struct dvb_frontend_ops dst_dvbt_ops = { - - .info = { - .name = "DST DVB-T", - .type = FE_OFDM, - .frequency_min = 137000000, - .frequency_max = 858000000, - .frequency_stepsize = 166667, - .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO - }, - - .release = dst_release, - .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, - .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, - .read_status = dst_read_status, - .read_signal_strength = dst_read_signal_strength, - .read_snr = dst_read_snr, -}; - -static struct dvb_frontend_ops dst_dvbs_ops = { - - .info = { - .name = "DST DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1000, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - /* . symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_FEC_AUTO | FE_CAN_QPSK - }, - - .release = dst_release, - .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, - .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, - .read_status = dst_read_status, - .read_signal_strength = dst_read_signal_strength, - .read_snr = dst_read_snr, - .diseqc_send_burst = dst_send_burst, - .diseqc_send_master_cmd = dst_set_diseqc, - .set_voltage = dst_set_voltage, - .set_tone = dst_set_tone, -}; - -static struct dvb_frontend_ops dst_dvbc_ops = { - - .info = { - .name = "DST DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 51000000, - .frequency_max = 858000000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - /* . symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO - }, - - .release = dst_release, - .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, - .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, - .read_status = dst_read_status, - .read_signal_strength = dst_read_signal_strength, - .read_snr = dst_read_snr, -}; - -static struct dvb_frontend_ops dst_atsc_ops = { - .info = { - .name = "DST ATSC", - .type = FE_ATSC, - .frequency_stepsize = 62500, - .frequency_min = 510000000, - .frequency_max = 858000000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_FEC_AUTO | FE_CAN_QAM_AUTO | FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .release = dst_release, - .init = dst_init, - .tune = dst_tune_frontend, - .set_frontend = dst_set_frontend, - .get_frontend = dst_get_frontend, - .get_frontend_algo = dst_get_tuning_algo, - .read_status = dst_read_status, - .read_signal_strength = dst_read_signal_strength, - .read_snr = dst_read_snr, -}; - -MODULE_DESCRIPTION("DST DVB-S/T/C/ATSC Combo Frontend driver"); -MODULE_AUTHOR("Jamie Honan, Manu Abraham"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c deleted file mode 100644 index 0258451423a..00000000000 --- a/drivers/media/dvb/bt8xx/dst_ca.c +++ /dev/null @@ -1,719 +0,0 @@ -/* - CA-driver for TwinHan DST Frontend/Card - - Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/dvb/ca.h> -#include "dvbdev.h" -#include "dvb_frontend.h" -#include "dst_ca.h" -#include "dst_common.h" - -#define DST_CA_ERROR 0 -#define DST_CA_NOTICE 1 -#define DST_CA_INFO 2 -#define DST_CA_DEBUG 3 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((x > DST_CA_ERROR) && (x > y)) \ - printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ - else if ((x > DST_CA_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ - else if ((x > DST_CA_INFO) && (x > y)) \ - printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ - else if ((x > DST_CA_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ - } else { \ - if (x > y) \ - printk(format, ## arg); \ - } \ -} while(0) - - -static unsigned int verbose = 5; -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); - -/* Need some more work */ -static int ca_set_slot_descr(void) -{ - /* We could make this more graceful ? */ - return -EOPNOTSUPP; -} - -/* Need some more work */ -static int ca_set_pid(void) -{ - /* We could make this more graceful ? */ - return -EOPNOTSUPP; -} - -static void put_command_and_length(u8 *data, int command, int length) -{ - data[0] = (command >> 16) & 0xff; - data[1] = (command >> 8) & 0xff; - data[2] = command & 0xff; - data[3] = length; -} - -static void put_checksum(u8 *check_string, int length) -{ - dprintk(verbose, DST_CA_DEBUG, 1, " Computing string checksum."); - dprintk(verbose, DST_CA_DEBUG, 1, " -> string length : 0x%02x", length); - check_string[length] = dst_check_sum (check_string, length); - dprintk(verbose, DST_CA_DEBUG, 1, " -> checksum : 0x%02x", check_string[length]); -} - -static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) -{ - u8 reply; - - mutex_lock(&state->dst_mutex); - dst_comm_init(state); - msleep(65); - - if (write_dst(state, data, len)) { - dprintk(verbose, DST_CA_INFO, 1, " Write not successful, trying to recover"); - dst_error_recovery(state); - goto error; - } - if ((dst_pio_disable(state)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " DST PIO disable failed."); - goto error; - } - if (read_dst(state, &reply, GET_ACK) < 0) { - dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); - dst_error_recovery(state); - goto error; - } - if (read) { - if (! dst_wait_dst_ready(state, LONG_DELAY)) { - dprintk(verbose, DST_CA_NOTICE, 1, " 8820 not ready"); - goto error; - } - if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ - dprintk(verbose, DST_CA_INFO, 1, " Read not successful, trying to recover"); - dst_error_recovery(state); - goto error; - } - } - mutex_unlock(&state->dst_mutex); - return 0; - -error: - mutex_unlock(&state->dst_mutex); - return -EIO; -} - - -static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read) -{ - u8 dst_ca_comm_err = 0; - - while (dst_ca_comm_err < RETRIES) { - dprintk(verbose, DST_CA_NOTICE, 1, " Put Command"); - if (dst_ci_command(state, data, ca_string, len, read)) { // If error - dst_error_recovery(state); - dst_ca_comm_err++; // work required here. - } else { - break; - } - } - - if(dst_ca_comm_err == RETRIES) - return -1; - - return 0; -} - - - -static int ca_get_app_info(struct dst_state *state) -{ - int length, str_length; - static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; - - put_checksum(&command[0], command[0]); - if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; - } - dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); - dprintk(verbose, DST_CA_INFO, 1, " ================================ CI Module Application Info ======================================"); - dprintk(verbose, DST_CA_INFO, 1, " Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]", - state->messages[7], (state->messages[8] << 8) | state->messages[9], - (state->messages[10] << 8) | state->messages[11], __func__, (char *)(&state->messages[12])); - dprintk(verbose, DST_CA_INFO, 1, " =================================================================================================="); - - // Transform dst message to correct application_info message - length = state->messages[5]; - str_length = length - 6; - if (str_length < 0) { - str_length = 0; - dprintk(verbose, DST_CA_ERROR, 1, "Invalid string length returned in ca_get_app_info(). Recovering."); - } - - // First, the command and length fields - put_command_and_length(&state->messages[0], CA_APP_INFO, length); - - // Copy application_type, application_manufacturer and manufacturer_code - memcpy(&state->messages[4], &state->messages[7], 5); - - // Set string length and copy string - state->messages[9] = str_length; - memcpy(&state->messages[10], &state->messages[12], str_length); - - return 0; -} - -static int ca_get_ca_info(struct dst_state *state) -{ - int srcPtr, dstPtr, i, num_ids; - static u8 slot_command[8] = {0x07, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0xff}; - const int in_system_id_pos = 8, out_system_id_pos = 4, in_num_ids_pos = 7; - - put_checksum(&slot_command[0], slot_command[0]); - if ((dst_put_ci(state, slot_command, sizeof (slot_command), state->messages, GET_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; - } - dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); - - // Print raw data - dprintk(verbose, DST_CA_INFO, 0, " DST data = ["); - for (i = 0; i < state->messages[0] + 1; i++) { - dprintk(verbose, DST_CA_INFO, 0, " 0x%02x", state->messages[i]); - } - dprintk(verbose, DST_CA_INFO, 0, "]\n"); - - // Set the command and length of the output - num_ids = state->messages[in_num_ids_pos]; - if (num_ids >= 100) { - num_ids = 100; - dprintk(verbose, DST_CA_ERROR, 1, "Invalid number of ids (>100). Recovering."); - } - put_command_and_length(&state->messages[0], CA_INFO, num_ids * 2); - - dprintk(verbose, DST_CA_INFO, 0, " CA_INFO = ["); - srcPtr = in_system_id_pos; - dstPtr = out_system_id_pos; - for(i = 0; i < num_ids; i++) { - dprintk(verbose, DST_CA_INFO, 0, " 0x%02x%02x", state->messages[srcPtr + 0], state->messages[srcPtr + 1]); - // Append to output - state->messages[dstPtr + 0] = state->messages[srcPtr + 0]; - state->messages[dstPtr + 1] = state->messages[srcPtr + 1]; - srcPtr += 2; - dstPtr += 2; - } - dprintk(verbose, DST_CA_INFO, 0, "]\n"); - - return 0; -} - -static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void __user *arg) -{ - int i; - u8 slot_cap[256]; - static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff}; - - put_checksum(&slot_command[0], slot_command[0]); - if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; - } - dprintk(verbose, DST_CA_NOTICE, 1, " -->dst_put_ci SUCCESS !"); - - /* Will implement the rest soon */ - - dprintk(verbose, DST_CA_INFO, 1, " Slot cap = [%d]", slot_cap[7]); - dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); - for (i = 0; i < slot_cap[0] + 1; i++) - dprintk(verbose, DST_CA_INFO, 0, " %d", slot_cap[i]); - dprintk(verbose, DST_CA_INFO, 0, "\n"); - - p_ca_caps->slot_num = 1; - p_ca_caps->slot_type = 1; - p_ca_caps->descr_num = slot_cap[7]; - p_ca_caps->descr_type = 1; - - if (copy_to_user(arg, p_ca_caps, sizeof (struct ca_caps))) - return -EFAULT; - - return 0; -} - -/* Need some more work */ -static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) -{ - return -EOPNOTSUPP; -} - - -static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void __user *arg) -{ - int i; - static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; - - u8 *slot_info = state->messages; - - put_checksum(&slot_command[0], 7); - if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->dst_put_ci FAILED !"); - return -1; - } - dprintk(verbose, DST_CA_INFO, 1, " -->dst_put_ci SUCCESS !"); - - /* Will implement the rest soon */ - - dprintk(verbose, DST_CA_INFO, 1, " Slot info = [%d]", slot_info[3]); - dprintk(verbose, DST_CA_INFO, 0, "===================================\n"); - for (i = 0; i < 8; i++) - dprintk(verbose, DST_CA_INFO, 0, " %d", slot_info[i]); - dprintk(verbose, DST_CA_INFO, 0, "\n"); - - if (slot_info[4] & 0x80) { - p_ca_slot_info->flags = CA_CI_MODULE_PRESENT; - p_ca_slot_info->num = 1; - p_ca_slot_info->type = CA_CI; - } else if (slot_info[4] & 0x40) { - p_ca_slot_info->flags = CA_CI_MODULE_READY; - p_ca_slot_info->num = 1; - p_ca_slot_info->type = CA_CI; - } else - p_ca_slot_info->flags = 0; - - if (copy_to_user(arg, p_ca_slot_info, sizeof (struct ca_slot_info))) - return -EFAULT; - - return 0; -} - - -static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) -{ - u8 i = 0; - u32 command = 0; - - if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) - return -EFAULT; - - if (p_ca_message->msg) { - dprintk(verbose, DST_CA_NOTICE, 1, " Message = [%02x %02x %02x]", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]); - - for (i = 0; i < 3; i++) { - command = command | p_ca_message->msg[i]; - if (i < 2) - command = command << 8; - } - dprintk(verbose, DST_CA_NOTICE, 1, " Command=[0x%x]", command); - - switch (command) { - case CA_APP_INFO: - memcpy(p_ca_message->msg, state->messages, 128); - if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) - return -EFAULT; - break; - case CA_INFO: - memcpy(p_ca_message->msg, state->messages, 128); - if (copy_to_user(arg, p_ca_message, sizeof (struct ca_msg)) ) - return -EFAULT; - break; - } - } - - return 0; -} - -static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u32 length) -{ - if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) { - hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ - hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ - } else { - if (length > 247) { - dprintk(verbose, DST_CA_ERROR, 1, " Message too long ! *** Bailing Out *** !"); - return -1; - } - hw_buffer->msg[0] = (length & 0xff) + 7; - hw_buffer->msg[1] = 0x40; - hw_buffer->msg[2] = 0x03; - hw_buffer->msg[3] = 0x00; - hw_buffer->msg[4] = 0x03; - hw_buffer->msg[5] = length & 0xff; - hw_buffer->msg[6] = 0x00; - - /* - * Need to compute length for EN50221 section 8.3.2, for the time being - * assuming 8.3.2 is not applicable - */ - memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); - } - - return 0; -} - -static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) -{ - if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " DST-CI Command failed."); - dprintk(verbose, DST_CA_NOTICE, 1, " Resetting DST."); - rdc_reset_state(state); - return -1; - } - dprintk(verbose, DST_CA_NOTICE, 1, " DST-CI Command success."); - - return 0; -} - -static u32 asn_1_decode(u8 *asn_1_array) -{ - u8 length_field = 0, word_count = 0, count = 0; - u32 length = 0; - - length_field = asn_1_array[0]; - dprintk(verbose, DST_CA_DEBUG, 1, " Length field=[%02x]", length_field); - if (length_field < 0x80) { - length = length_field & 0x7f; - dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%02x]\n", length); - } else { - word_count = length_field & 0x7f; - for (count = 0; count < word_count; count++) { - length = length << 8; - length += asn_1_array[count + 1]; - dprintk(verbose, DST_CA_DEBUG, 1, " Length=[%04x]", length); - } - } - return length; -} - -static int debug_string(u8 *msg, u32 length, u32 offset) -{ - u32 i; - - dprintk(verbose, DST_CA_DEBUG, 0, " String=[ "); - for (i = offset; i < length; i++) - dprintk(verbose, DST_CA_DEBUG, 0, "%02x ", msg[i]); - dprintk(verbose, DST_CA_DEBUG, 0, "]\n"); - - return 0; -} - - -static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) -{ - u32 length = 0; - u8 tag_length = 8; - - length = asn_1_decode(&p_ca_message->msg[3]); - dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length); - debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */ - - memset(hw_buffer->msg, '\0', length); - handle_dst_tag(state, p_ca_message, hw_buffer, length); - put_checksum(hw_buffer->msg, hw_buffer->msg[0]); - - debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */ - write_to_8820(state, hw_buffer, (length + tag_length), reply); - - return 0; -} - - -/* Board supports CA PMT reply ? */ -static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) -{ - int ca_pmt_reply_test = 0; - - /* Do test board */ - /* Not there yet but soon */ - - /* CA PMT Reply capable */ - if (ca_pmt_reply_test) { - if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !"); - return -1; - } - - /* Process CA PMT Reply */ - /* will implement soon */ - dprintk(verbose, DST_CA_ERROR, 1, " Not there yet"); - } - /* CA PMT Reply not capable */ - if (!ca_pmt_reply_test) { - if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " ca_set_pmt.. failed !"); - return -1; - } - dprintk(verbose, DST_CA_NOTICE, 1, " ca_set_pmt.. success !"); - /* put a dummy message */ - - } - return 0; -} - -static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void __user *arg) -{ - int i = 0; - unsigned int ca_message_header_len; - - u32 command = 0; - struct ca_msg *hw_buffer; - int result = 0; - - if ((hw_buffer = kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { - dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); - return -ENOMEM; - } - dprintk(verbose, DST_CA_DEBUG, 1, " "); - - if (copy_from_user(p_ca_message, arg, sizeof (struct ca_msg))) { - result = -EFAULT; - goto free_mem_and_exit; - } - - - if (p_ca_message->msg) { - ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ - /* EN50221 tag */ - command = 0; - - for (i = 0; i < 3; i++) { - command = command | p_ca_message->msg[i]; - if (i < 2) - command = command << 8; - } - dprintk(verbose, DST_CA_DEBUG, 1, " Command=[0x%x]\n", command); - - switch (command) { - case CA_PMT: - dprintk(verbose, DST_CA_DEBUG, 1, "Command = SEND_CA_PMT"); - if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { // code simplification started - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT Success !"); - break; - case CA_PMT_REPLY: - dprintk(verbose, DST_CA_INFO, 1, "Command = CA_PMT_REPLY"); - /* Have to handle the 2 basic types of cards here */ - if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_PMT_REPLY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_PMT_REPLY Success !"); - break; - case CA_APP_INFO_ENQUIRY: // only for debugging - dprintk(verbose, DST_CA_INFO, 1, " Getting Cam Application information"); - - if ((ca_get_app_info(state)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_APP_INFO_ENQUIRY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_APP_INFO_ENQUIRY Success !"); - break; - case CA_INFO_ENQUIRY: - dprintk(verbose, DST_CA_INFO, 1, " Getting CA Information"); - - if ((ca_get_ca_info(state)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_INFO_ENQUIRY Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_INFO_ENQUIRY Success !"); - break; - } - } -free_mem_and_exit: - kfree (hw_buffer); - - return result; -} - -static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg) -{ - struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; - struct dst_state* state = (struct dst_state*) dvbdev->priv; - struct ca_slot_info *p_ca_slot_info; - struct ca_caps *p_ca_caps; - struct ca_msg *p_ca_message; - void __user *arg = (void __user *)ioctl_arg; - int result = 0; - - p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); - p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); - p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); - if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) { - dprintk(verbose, DST_CA_ERROR, 1, " Memory allocation failure"); - result = -ENOMEM; - goto free_mem_and_exit; - } - - /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ - switch (cmd) { - case CA_SEND_MSG: - dprintk(verbose, DST_CA_INFO, 1, " Sending message"); - if ((ca_send_message(state, p_ca_message, arg)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SEND_MSG Failed !"); - result = -1; - goto free_mem_and_exit; - } - break; - case CA_GET_MSG: - dprintk(verbose, DST_CA_INFO, 1, " Getting message"); - if ((ca_get_message(state, p_ca_message, arg)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_MSG Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_MSG Success !"); - break; - case CA_RESET: - dprintk(verbose, DST_CA_ERROR, 1, " Resetting DST"); - dst_error_bailout(state); - msleep(4000); - break; - case CA_GET_SLOT_INFO: - dprintk(verbose, DST_CA_INFO, 1, " Getting Slot info"); - if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_SLOT_INFO Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_SLOT_INFO Success !"); - break; - case CA_GET_CAP: - dprintk(verbose, DST_CA_INFO, 1, " Getting Slot capabilities"); - if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_CAP Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_CAP Success !"); - break; - case CA_GET_DESCR_INFO: - dprintk(verbose, DST_CA_INFO, 1, " Getting descrambler description"); - if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_GET_DESCR_INFO Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_GET_DESCR_INFO Success !"); - break; - case CA_SET_DESCR: - dprintk(verbose, DST_CA_INFO, 1, " Setting descrambler"); - if ((ca_set_slot_descr()) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_DESCR Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_DESCR Success !"); - break; - case CA_SET_PID: - dprintk(verbose, DST_CA_INFO, 1, " Setting PID"); - if ((ca_set_pid()) < 0) { - dprintk(verbose, DST_CA_ERROR, 1, " -->CA_SET_PID Failed !"); - result = -1; - goto free_mem_and_exit; - } - dprintk(verbose, DST_CA_INFO, 1, " -->CA_SET_PID Success !"); - default: - result = -EOPNOTSUPP; - }; - free_mem_and_exit: - kfree (p_ca_message); - kfree (p_ca_slot_info); - kfree (p_ca_caps); - - return result; -} - -static int dst_ca_open(struct inode *inode, struct file *file) -{ - dprintk(verbose, DST_CA_DEBUG, 1, " Device opened [%p] ", file); - try_module_get(THIS_MODULE); - - return 0; -} - -static int dst_ca_release(struct inode *inode, struct file *file) -{ - dprintk(verbose, DST_CA_DEBUG, 1, " Device closed."); - module_put(THIS_MODULE); - - return 0; -} - -static ssize_t dst_ca_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) -{ - ssize_t bytes_read = 0; - - dprintk(verbose, DST_CA_DEBUG, 1, " Device read."); - - return bytes_read; -} - -static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) -{ - dprintk(verbose, DST_CA_DEBUG, 1, " Device write."); - - return 0; -} - -static struct file_operations dst_ca_fops = { - .owner = THIS_MODULE, - .ioctl = dst_ca_ioctl, - .open = dst_ca_open, - .release = dst_ca_release, - .read = dst_ca_read, - .write = dst_ca_write -}; - -static struct dvb_device dvbdev_ca = { - .priv = NULL, - .users = 1, - .readers = 1, - .writers = 1, - .fops = &dst_ca_fops -}; - -struct dvb_device *dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter) -{ - struct dvb_device *dvbdev; - - dprintk(verbose, DST_CA_ERROR, 1, "registering DST-CA device"); - if (dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA) == 0) { - dst->dst_ca = dvbdev; - return dst->dst_ca; - } - - return NULL; -} - -EXPORT_SYMBOL(dst_ca_attach); - -MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); -MODULE_AUTHOR("Manu Abraham"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/dvb/bt8xx/dst_ca.h deleted file mode 100644 index 59cd0ddd6d8..00000000000 --- a/drivers/media/dvb/bt8xx/dst_ca.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - CA-driver for TwinHan DST Frontend/Card - - Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef _DST_CA_H_ -#define _DST_CA_H_ - -#define RETRIES 5 - - -#define CA_APP_INFO_ENQUIRY 0x9f8020 -#define CA_APP_INFO 0x9f8021 -#define CA_ENTER_MENU 0x9f8022 -#define CA_INFO_ENQUIRY 0x9f8030 -#define CA_INFO 0x9f8031 -#define CA_PMT 0x9f8032 -#define CA_PMT_REPLY 0x9f8033 - -#define CA_CLOSE_MMI 0x9f8800 -#define CA_DISPLAY_CONTROL 0x9f8801 -#define CA_DISPLAY_REPLY 0x9f8802 -#define CA_TEXT_LAST 0x9f8803 -#define CA_TEXT_MORE 0x9f8804 -#define CA_KEYPAD_CONTROL 0x9f8805 -#define CA_KEYPRESS 0x9f8806 - -#define CA_ENQUIRY 0x9f8807 -#define CA_ANSWER 0x9f8808 -#define CA_MENU_LAST 0x9f8809 -#define CA_MENU_MORE 0x9f880a -#define CA_MENU_ANSWER 0x9f880b -#define CA_LIST_LAST 0x9f880c -#define CA_LIST_MORE 0x9f880d - - -struct dst_ca_private { - struct dst_state *dst; - struct dvb_device *dvbdev; -}; - - -#endif diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h deleted file mode 100644 index d88cf2add82..00000000000 --- a/drivers/media/dvb/bt8xx/dst_common.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - Frontend-driver for TwinHan DST Frontend - - Copyright (C) 2003 Jamie Honan - Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef DST_COMMON_H -#define DST_COMMON_H - -#include <linux/dvb/frontend.h> -#include <linux/device.h> -#include <linux/mutex.h> -#include "bt878.h" - -#include "dst_ca.h" - - -#define NO_DELAY 0 -#define LONG_DELAY 1 -#define DEVICE_INIT 2 - -#define DELAY 1 - -#define DST_TYPE_IS_SAT 0 -#define DST_TYPE_IS_TERR 1 -#define DST_TYPE_IS_CABLE 2 -#define DST_TYPE_IS_ATSC 3 - -#define DST_TYPE_HAS_TS188 1 -#define DST_TYPE_HAS_TS204 2 -#define DST_TYPE_HAS_SYMDIV 4 -#define DST_TYPE_HAS_FW_1 8 -#define DST_TYPE_HAS_FW_2 16 -#define DST_TYPE_HAS_FW_3 32 -#define DST_TYPE_HAS_FW_BUILD 64 -#define DST_TYPE_HAS_OBS_REGS 128 -#define DST_TYPE_HAS_INC_COUNT 256 -#define DST_TYPE_HAS_MULTI_FE 512 -#define DST_TYPE_HAS_NEWTUNE_2 1024 -#define DST_TYPE_HAS_DBOARD 2048 -#define DST_TYPE_HAS_VLF 4096 - -/* Card capability list */ - -#define DST_TYPE_HAS_MAC 1 -#define DST_TYPE_HAS_DISEQC3 2 -#define DST_TYPE_HAS_DISEQC4 4 -#define DST_TYPE_HAS_DISEQC5 8 -#define DST_TYPE_HAS_MOTO 16 -#define DST_TYPE_HAS_CA 32 -#define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ -#define DST_TYPE_HAS_SESSION 128 - -#define TUNER_TYPE_MULTI 1 -#define TUNER_TYPE_UNKNOWN 2 -/* DVB-S */ -#define TUNER_TYPE_L64724 4 -#define TUNER_TYPE_STV0299 8 -#define TUNER_TYPE_MB86A15 16 - -/* DVB-T */ -#define TUNER_TYPE_TDA10046 32 - -/* ATSC */ -#define TUNER_TYPE_NXT200x 64 - - -#define RDC_8820_PIO_0_DISABLE 0 -#define RDC_8820_PIO_0_ENABLE 1 -#define RDC_8820_INT 2 -#define RDC_8820_RESET 4 - -/* DST Communication */ -#define GET_REPLY 1 -#define NO_REPLY 0 - -#define GET_ACK 1 -#define FIXED_COMM 8 - -#define ACK 0xff - -struct dst_state { - - struct i2c_adapter* i2c; - - struct bt878* bt; - - /* configuration settings */ - const struct dst_config* config; - - struct dvb_frontend frontend; - - /* private ASIC data */ - u8 tx_tuna[10]; - u8 rx_tuna[10]; - u8 rxbuffer[10]; - u8 diseq_flags; - u8 dst_type; - u32 type_flags; - u32 frequency; /* intermediate frequency in kHz for QPSK */ - fe_spectral_inversion_t inversion; - u32 symbol_rate; /* symbol rate in Symbols per second */ - fe_code_rate_t fec; - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone; - u32 decode_freq; - u8 decode_lock; - u16 decode_strength; - u16 decode_snr; - unsigned long cur_jiff; - u8 k22; - fe_bandwidth_t bandwidth; - u32 dst_hw_cap; - u8 dst_fw_version; - fe_sec_mini_cmd_t minicmd; - fe_modulation_t modulation; - u8 messages[256]; - u8 mac_address[8]; - u8 fw_version[8]; - u8 card_info[8]; - u8 vendor[8]; - u8 board_info[8]; - u32 tuner_type; - char *tuner_name; - struct mutex dst_mutex; - u8 fw_name[8]; - struct dvb_device *dst_ca; -}; - -struct tuner_types { - u32 tuner_type; - char *tuner_name; - char *board_name; - char *fw_name; -}; - -struct dst_types { - char *device_id; - int offset; - u8 dst_type; - u32 type_flags; - u32 dst_feature; - u32 tuner_type; -}; - -struct dst_config -{ - /* the ASIC i2c address */ - u8 demod_address; -}; - -int rdc_reset_state(struct dst_state *state); - -int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode); -int dst_pio_disable(struct dst_state *state); -int dst_error_recovery(struct dst_state* state); -int dst_error_bailout(struct dst_state *state); -int dst_comm_init(struct dst_state* state); - -int write_dst(struct dst_state *state, u8 * data, u8 len); -int read_dst(struct dst_state *state, u8 * ret, u8 len); -u8 dst_check_sum(u8 * buf, u32 len); -struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter); -struct dvb_device *dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter); - - -#endif // DST_COMMON_H diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h deleted file mode 100644 index 3974a4c6ebe..00000000000 --- a/drivers/media/dvb/bt8xx/dst_priv.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * dst-bt878.h: part of the DST driver for the TwinHan DST Frontend - * - * Copyright (C) 2003 Jamie Honan - */ - -struct dst_gpio_enable { - u32 mask; - u32 enable; -}; - -struct dst_gpio_output { - u32 mask; - u32 highvals; -}; - -struct dst_gpio_read { - unsigned long value; -}; - -union dst_gpio_packet { - struct dst_gpio_enable enb; - struct dst_gpio_output outp; - struct dst_gpio_read rd; - int psize; -}; - -#define DST_IG_ENABLE 0 -#define DST_IG_WRITE 1 -#define DST_IG_READ 2 -#define DST_IG_TS 3 - -struct bt878; - -int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c deleted file mode 100644 index 48762a2b9e4..00000000000 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ /dev/null @@ -1,970 +0,0 @@ -/* - * Bt8xx based DVB adapter driver - * - * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/bitops.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/i2c.h> - -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dvb-bt8xx.h" -#include "bt878.h" - -static int debug; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define dprintk( args... ) \ - do { \ - if (debug) printk(KERN_DEBUG args); \ - } while (0) - -#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ - -static void dvb_bt8xx_task(unsigned long data) -{ - struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data; - - //printk("%d ", card->bt->finished_block); - - while (card->bt->last_block != card->bt->finished_block) { - (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) - (&card->demux, - &card->bt->buf_cpu[card->bt->last_block * - card->bt->block_bytes], - card->bt->block_bytes); - card->bt->last_block = (card->bt->last_block + 1) % - card->bt->block_count; - } -} - -static int dvb_bt8xx_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux*dvbdmx = dvbdmxfeed->demux; - struct dvb_bt8xx_card *card = dvbdmx->priv; - int rc; - - dprintk("dvb_bt8xx: start_feed\n"); - - if (!dvbdmx->dmx.frontend) - return -EINVAL; - - mutex_lock(&card->lock); - card->nfeeds++; - rc = card->nfeeds; - if (card->nfeeds == 1) - bt878_start(card->bt, card->gpio_mode, - card->op_sync_orin, card->irq_err_ignore); - mutex_unlock(&card->lock); - return rc; -} - -static int dvb_bt8xx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - struct dvb_bt8xx_card *card = dvbdmx->priv; - - dprintk("dvb_bt8xx: stop_feed\n"); - - if (!dvbdmx->dmx.frontend) - return -EINVAL; - - mutex_lock(&card->lock); - card->nfeeds--; - if (card->nfeeds == 0) - bt878_stop(card->bt); - mutex_unlock(&card->lock); - - return 0; -} - -static int is_pci_slot_eq(struct pci_dev* adev, struct pci_dev* bdev) -{ - if ((adev->subsystem_vendor == bdev->subsystem_vendor) && - (adev->subsystem_device == bdev->subsystem_device) && - (adev->bus->number == bdev->bus->number) && - (PCI_SLOT(adev->devfn) == PCI_SLOT(bdev->devfn))) - return 1; - return 0; -} - -static struct bt878 __devinit *dvb_bt8xx_878_match(unsigned int bttv_nr, struct pci_dev* bttv_pci_dev) -{ - unsigned int card_nr; - - /* Hmm, n squared. Hope n is small */ - for (card_nr = 0; card_nr < bt878_num; card_nr++) - if (is_pci_slot_eq(bt878[card_nr].dev, bttv_pci_dev)) - return &bt878[card_nr]; - return NULL; -} - -static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) -{ - static u8 mt352_clock_config [] = { 0x89, 0x38, 0x38 }; - static u8 mt352_reset [] = { 0x50, 0x80 }; - static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 }; - static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 }; - static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; - - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - udelay(2000); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - - mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); - mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); - mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); - - return 0; -} - -static int thomson_dtt7579_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) -{ - u32 div; - unsigned char bs = 0; - unsigned char cp = 0; - - if (buf_len < 5) - return -EINVAL; - - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - - if (params->frequency < 542000000) - cp = 0xb4; - else if (params->frequency < 771000000) - cp = 0xbc; - else - cp = 0xf4; - - if (params->frequency == 0) - bs = 0x03; - else if (params->frequency < 443250000) - bs = 0x02; - else - bs = 0x08; - - pllbuf[0] = 0x60; - pllbuf[1] = div >> 8; - pllbuf[2] = div & 0xff; - pllbuf[3] = cp; - pllbuf[4] = bs; - - return 5; -} - -static struct mt352_config thomson_dtt7579_config = { - .demod_address = 0x0f, - .demod_init = thomson_dtt7579_demod_init, -}; - -static struct zl10353_config thomson_dtt7579_zl10353_config = { - .demod_address = 0x0f, -}; - -static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - u32 freq = params->frequency; - - int i, a, n, pump; - u32 band, pll; - - u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, - 1576000,1718000,1856000,2036000,2150000}; - u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, - 0x00102000,0x00104000,0x00108000,0x00110000, - 0x00120000,0x00140000}; - - #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ - printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); - - /* This is really the bit driving the tuner chip cx24108 */ - - if (freq<950000) - freq = 950000; /* kHz */ - else if (freq>2150000) - freq = 2150000; /* satellite IF is 950..2150MHz */ - - /* decide which VCO to use for the input frequency */ - for(i = 1; (i < ARRAY_SIZE(osci)) && (osci[i] < freq); i++); - printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); - band=bandsel[i]; - /* the gain values must be set by SetSymbolrate */ - /* compute the pll divider needed, from Conexant data sheet, - resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, - depending on the divider bit. It is set to /4 on the 2 lowest - bands */ - n=((i<=2?2:1)*freq*10L)/(XTAL/100); - a=n%32; n/=32; if(a==0) n--; - pump=(freq<(osci[i-1]+osci[i])/2); - pll=0xf8000000| - ((pump?1:2)<<(14+11))| - ((n&0x1ff)<<(5+11))| - ((a&0x1f)<<11); - /* everything is shifted left 11 bits to left-align the bits in the - 32bit word. Output to the tuner goes MSB-aligned, after all */ - printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); - cx24110_pll_write(fe,band); - /* set vga and vca to their widest-band settings, as a precaution. - SetSymbolrate might not be called to set this up */ - cx24110_pll_write(fe,0x500c0000); - cx24110_pll_write(fe,0x83f1f800); - cx24110_pll_write(fe,pll); - //writereg(client,0x56,0x7f); - - return 0; -} - -static int pinnsat_tuner_init(struct dvb_frontend* fe) -{ - struct dvb_bt8xx_card *card = fe->dvb->priv; - - bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ - bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ - - return 0; -} - -static int pinnsat_tuner_sleep(struct dvb_frontend* fe) -{ - struct dvb_bt8xx_card *card = fe->dvb->priv; - - bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ - - return 0; -} - -static struct cx24110_config pctvsat_config = { - .demod_address = 0x55, -}; - -static int microtune_mt7202dtf_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; - u8 cfg, cpump, band_select; - u8 data[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (36000000 + params->frequency + 83333) / 166666; - cfg = 0x88; - - if (params->frequency < 175000000) - cpump = 2; - else if (params->frequency < 390000000) - cpump = 1; - else if (params->frequency < 470000000) - cpump = 2; - else if (params->frequency < 750000000) - cpump = 2; - else - cpump = 3; - - if (params->frequency < 175000000) - band_select = 0x0e; - else if (params->frequency < 470000000) - band_select = 0x05; - else - band_select = 0x03; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = ((div >> 10) & 0x60) | cfg; - data[3] = (cpump << 6) | band_select; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(card->i2c_adapter, &msg, 1); - return (div * 166666 - 36000000); -} - -static int microtune_mt7202dtf_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) -{ - struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv; - - return request_firmware(fw, name, &bt->bt->dev->dev); -} - -static struct sp887x_config microtune_mt7202dtf_config = { - .demod_address = 0x70, - .request_firmware = microtune_mt7202dtf_request_firmware, -}; - -static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) -{ - static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; - static u8 mt352_reset [] = { 0x50, 0x80 }; - static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, - 0x00, 0xFF, 0x00, 0x40, 0x40 }; - static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; - static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; - - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - udelay(2000); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - - mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg)); - udelay(2000); - mt352_write(fe, mt352_av771_extra,sizeof(mt352_av771_extra)); - mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); - - return 0; -} - -static int advbt771_samsung_tdtc9251dh0_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) -{ - u32 div; - unsigned char bs = 0; - unsigned char cp = 0; - - if (buf_len < 5) return -EINVAL; - - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - - if (params->frequency < 150000000) - cp = 0xB4; - else if (params->frequency < 173000000) - cp = 0xBC; - else if (params->frequency < 250000000) - cp = 0xB4; - else if (params->frequency < 400000000) - cp = 0xBC; - else if (params->frequency < 420000000) - cp = 0xF4; - else if (params->frequency < 470000000) - cp = 0xFC; - else if (params->frequency < 600000000) - cp = 0xBC; - else if (params->frequency < 730000000) - cp = 0xF4; - else - cp = 0xFC; - - if (params->frequency < 150000000) - bs = 0x01; - else if (params->frequency < 173000000) - bs = 0x01; - else if (params->frequency < 250000000) - bs = 0x02; - else if (params->frequency < 400000000) - bs = 0x02; - else if (params->frequency < 420000000) - bs = 0x02; - else if (params->frequency < 470000000) - bs = 0x02; - else if (params->frequency < 600000000) - bs = 0x08; - else if (params->frequency < 730000000) - bs = 0x08; - else - bs = 0x08; - - pllbuf[0] = 0x61; - pllbuf[1] = div >> 8; - pllbuf[2] = div & 0xff; - pllbuf[3] = cp; - pllbuf[4] = bs; - - return 5; -} - -static struct mt352_config advbt771_samsung_tdtc9251dh0_config = { - .demod_address = 0x0f, - .demod_init = advbt771_samsung_tdtc9251dh0_demod_init, -}; - -static struct dst_config dst_config = { - .demod_address = 0x55, -}; - -static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) -{ - struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv; - - return request_firmware(fw, name, &bt->bt->dev->dev); -} - -static void or51211_setmode(struct dvb_frontend * fe, int mode) -{ - struct dvb_bt8xx_card *bt = fe->dvb->priv; - bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */ - msleep(20); -} - -static void or51211_reset(struct dvb_frontend * fe) -{ - struct dvb_bt8xx_card *bt = fe->dvb->priv; - - /* RESET DEVICE - * reset is controled by GPIO-0 - * when set to 0 causes reset and when to 1 for normal op - * must remain reset for 128 clock cycles on a 50Mhz clock - * also PRM1 PRM2 & PRM4 are controled by GPIO-1,GPIO-2 & GPIO-4 - * We assume that the reset has be held low long enough or we - * have been reset by a power on. When the driver is unloaded - * reset set to 0 so if reloaded we have been reset. - */ - /* reset & PRM1,2&4 are outputs */ - int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F); - if (ret != 0) - printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR (%i)\n", ret); - bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */ - msleep(20); - /* Now set for normal operation */ - bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001); - /* wait for operation to begin */ - msleep(500); -} - -static void or51211_sleep(struct dvb_frontend * fe) -{ - struct dvb_bt8xx_card *bt = fe->dvb->priv; - bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000); -} - -static struct or51211_config or51211_config = { - .demod_address = 0x15, - .request_firmware = or51211_request_firmware, - .setmode = or51211_setmode, - .reset = or51211_reset, - .sleep = or51211_sleep, -}; - -static int vp3021_alps_tded4_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv; - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf) }; - - div = (params->frequency + 36166667) / 166667; - - buf[0] = (div >> 8) & 0x7F; - buf[1] = div & 0xFF; - buf[2] = 0x85; - if ((params->frequency >= 47000000) && (params->frequency < 153000000)) - buf[3] = 0x01; - else if ((params->frequency >= 153000000) && (params->frequency < 430000000)) - buf[3] = 0x02; - else if ((params->frequency >= 430000000) && (params->frequency < 824000000)) - buf[3] = 0x0C; - else if ((params->frequency >= 824000000) && (params->frequency < 863000000)) - buf[3] = 0x8C; - else - return -EINVAL; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(card->i2c_adapter, &msg, 1); - return 0; -} - -static struct nxt6000_config vp3021_alps_tded4_config = { - .demod_address = 0x0a, - .clock_inversion = 1, -}; - -static int digitv_alps_tded4_demod_init(struct dvb_frontend* fe) -{ - static u8 mt352_clock_config [] = { 0x89, 0x38, 0x2d }; - static u8 mt352_reset [] = { 0x50, 0x80 }; - static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg [] = { 0x67, 0x20, 0xa0 }; - static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; - - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - udelay(2000); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - mt352_write(fe, mt352_agc_cfg,sizeof(mt352_agc_cfg)); - mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); - - return 0; -} - -static int digitv_alps_tded4_tuner_calc_regs(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf, int buf_len) -{ - u32 div; - struct dvb_ofdm_parameters *op = ¶ms->u.ofdm; - - if (buf_len < 5) - return -EINVAL; - - div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; - - pllbuf[0] = 0x61; - pllbuf[1] = (div >> 8) & 0x7F; - pllbuf[2] = div & 0xFF; - pllbuf[3] = 0x85; - - dprintk("frequency %u, div %u\n", params->frequency, div); - - if (params->frequency < 470000000) - pllbuf[4] = 0x02; - else if (params->frequency > 823000000) - pllbuf[4] = 0x88; - else - pllbuf[4] = 0x08; - - if (op->bandwidth == 8) - pllbuf[4] |= 0x04; - - return 5; -} - -static void digitv_alps_tded4_reset(struct dvb_bt8xx_card *bt) -{ - /* - * Reset the frontend, must be called before trying - * to initialise the MT352 or mt352_attach - * will fail. Same goes for the nxt6000 frontend. - * - */ - - int ret = bttv_gpio_enable(bt->bttv_nr, 0x08, 0x08); - if (ret != 0) - printk(KERN_WARNING "digitv_alps_tded4: Init Error - Can't Reset DVR (%i)\n", ret); - - /* Pulse the reset line */ - bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ - bttv_write_gpio(bt->bttv_nr, 0x08, 0x00); /* Low */ - msleep(100); - - bttv_write_gpio(bt->bttv_nr, 0x08, 0x08); /* High */ -} - -static struct mt352_config digitv_alps_tded4_config = { - .demod_address = 0x0a, - .demod_init = digitv_alps_tded4_demod_init, -}; - -static struct lgdt330x_config tdvs_tua6034_config = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, - .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ -}; - -static void lgdt330x_reset(struct dvb_bt8xx_card *bt) -{ - /* Set pin 27 of the lgdt3303 chip high to reset the frontend */ - - /* Pulse the reset line */ - bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ - bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000000); /* Low */ - msleep(100); - - bttv_write_gpio(bt->bttv_nr, 0x00e00007, 0x00000001); /* High */ - msleep(100); -} - -static void frontend_init(struct dvb_bt8xx_card *card, u32 type) -{ - struct dst_state* state = NULL; - - switch(type) { - case BTTV_BOARD_DVICO_DVBT_LITE: - card->fe = dvb_attach(mt352_attach, &thomson_dtt7579_config, card->i2c_adapter); - - if (card->fe == NULL) - card->fe = dvb_attach(zl10353_attach, &thomson_dtt7579_zl10353_config, - card->i2c_adapter); - - if (card->fe != NULL) { - card->fe->ops.tuner_ops.calc_regs = thomson_dtt7579_tuner_calc_regs; - card->fe->ops.info.frequency_min = 174000000; - card->fe->ops.info.frequency_max = 862000000; - } - break; - - case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: - lgdt330x_reset(card); - card->fe = dvb_attach(lgdt330x_attach, &tdvs_tua6034_config, card->i2c_adapter); - if (card->fe != NULL) { - dvb_attach(simple_tuner_attach, card->fe, - card->i2c_adapter, 0x61, - TUNER_LG_TDVS_H06XF); - dprintk ("dvb_bt8xx: lgdt330x detected\n"); - } - break; - - case BTTV_BOARD_NEBULA_DIGITV: - /* - * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); - * this would be a cleaner solution than trying each frontend in turn. - */ - - /* Old Nebula (marked (c)2003 on high profile pci card) has nxt6000 demod */ - digitv_alps_tded4_reset(card); - card->fe = dvb_attach(nxt6000_attach, &vp3021_alps_tded4_config, card->i2c_adapter); - if (card->fe != NULL) { - card->fe->ops.tuner_ops.set_params = vp3021_alps_tded4_tuner_set_params; - dprintk ("dvb_bt8xx: an nxt6000 was detected on your digitv card\n"); - break; - } - - /* New Nebula (marked (c)2005 on low profile pci card) has mt352 demod */ - digitv_alps_tded4_reset(card); - card->fe = dvb_attach(mt352_attach, &digitv_alps_tded4_config, card->i2c_adapter); - - if (card->fe != NULL) { - card->fe->ops.tuner_ops.calc_regs = digitv_alps_tded4_tuner_calc_regs; - dprintk ("dvb_bt8xx: an mt352 was detected on your digitv card\n"); - } - break; - - case BTTV_BOARD_AVDVBT_761: - card->fe = dvb_attach(sp887x_attach, µtune_mt7202dtf_config, card->i2c_adapter); - if (card->fe) { - card->fe->ops.tuner_ops.set_params = microtune_mt7202dtf_tuner_set_params; - } - break; - - case BTTV_BOARD_AVDVBT_771: - card->fe = dvb_attach(mt352_attach, &advbt771_samsung_tdtc9251dh0_config, card->i2c_adapter); - if (card->fe != NULL) { - card->fe->ops.tuner_ops.calc_regs = advbt771_samsung_tdtc9251dh0_tuner_calc_regs; - card->fe->ops.info.frequency_min = 174000000; - card->fe->ops.info.frequency_max = 862000000; - } - break; - - case BTTV_BOARD_TWINHAN_DST: - /* DST is not a frontend driver !!! */ - state = kmalloc(sizeof (struct dst_state), GFP_KERNEL); - if (!state) { - printk("dvb_bt8xx: No memory\n"); - break; - } - /* Setup the Card */ - state->config = &dst_config; - state->i2c = card->i2c_adapter; - state->bt = card->bt; - state->dst_ca = NULL; - /* DST is not a frontend, attaching the ASIC */ - if (dvb_attach(dst_attach, state, &card->dvb_adapter) == NULL) { - printk("%s: Could not find a Twinhan DST.\n", __func__); - break; - } - /* Attach other DST peripherals if any */ - /* Conditional Access device */ - card->fe = &state->frontend; - if (state->dst_hw_cap & DST_TYPE_HAS_CA) - dvb_attach(dst_ca_attach, state, &card->dvb_adapter); - break; - - case BTTV_BOARD_PINNACLESAT: - card->fe = dvb_attach(cx24110_attach, &pctvsat_config, card->i2c_adapter); - if (card->fe) { - card->fe->ops.tuner_ops.init = pinnsat_tuner_init; - card->fe->ops.tuner_ops.sleep = pinnsat_tuner_sleep; - card->fe->ops.tuner_ops.set_params = cx24108_tuner_set_params; - } - break; - - case BTTV_BOARD_PC_HDTV: - card->fe = dvb_attach(or51211_attach, &or51211_config, card->i2c_adapter); - if (card->fe != NULL) - dvb_attach(simple_tuner_attach, card->fe, - card->i2c_adapter, 0x61, - TUNER_PHILIPS_FCV1236D); - break; - } - - if (card->fe == NULL) - printk("dvb-bt8xx: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - card->bt->dev->vendor, - card->bt->dev->device, - card->bt->dev->subsystem_vendor, - card->bt->dev->subsystem_device); - else - if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { - printk("dvb-bt8xx: Frontend registration failed!\n"); - dvb_frontend_detach(card->fe); - card->fe = NULL; - } -} - -static int __devinit dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) -{ - int result; - - result = dvb_register_adapter(&card->dvb_adapter, card->card_name, - THIS_MODULE, &card->bt->dev->dev, - adapter_nr); - if (result < 0) { - printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); - return result; - } - card->dvb_adapter.priv = card; - - card->bt->adapter = card->i2c_adapter; - - memset(&card->demux, 0, sizeof(struct dvb_demux)); - - card->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; - - card->demux.priv = card; - card->demux.filternum = 256; - card->demux.feednum = 256; - card->demux.start_feed = dvb_bt8xx_start_feed; - card->demux.stop_feed = dvb_bt8xx_stop_feed; - card->demux.write_to_decoder = NULL; - - if ((result = dvb_dmx_init(&card->demux)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - dvb_unregister_adapter(&card->dvb_adapter); - return result; - } - - card->dmxdev.filternum = 256; - card->dmxdev.demux = &card->demux.dmx; - card->dmxdev.capabilities = 0; - - if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) { - printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); - - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; - } - - card->fe_hw.source = DMX_FRONTEND_0; - - if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; - } - - card->fe_mem.source = DMX_MEMORY_FE; - - if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; - } - - if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); - - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - dvb_unregister_adapter(&card->dvb_adapter); - return result; - } - - dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx); - - tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card); - - frontend_init(card, type); - - return 0; -} - -static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) -{ - struct dvb_bt8xx_card *card; - struct pci_dev* bttv_pci_dev; - int ret; - - if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) - return -ENOMEM; - - mutex_init(&card->lock); - card->bttv_nr = sub->core->nr; - strncpy(card->card_name, sub->core->name, sizeof(sub->core->name)); - card->i2c_adapter = &sub->core->i2c_adap; - - switch(sub->core->type) { - case BTTV_BOARD_PINNACLESAT: - card->gpio_mode = 0x0400c060; - /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, - BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; - break; - - case BTTV_BOARD_DVICO_DVBT_LITE: - card->gpio_mode = 0x0400C060; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; - /* 26, 15, 14, 6, 5 - * A_PWRDN DA_DPM DA_SBR DA_IOM_DA - * DA_APP(parallel) */ - break; - - case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: - card->gpio_mode = 0x0400c060; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; - break; - - case BTTV_BOARD_NEBULA_DIGITV: - case BTTV_BOARD_AVDVBT_761: - card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; - /* A_PWRDN DA_SBR DA_APP (high speed serial) */ - break; - - case BTTV_BOARD_AVDVBT_771: //case 0x07711461: - card->gpio_mode = 0x0400402B; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; - /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ - break; - - case BTTV_BOARD_TWINHAN_DST: - card->gpio_mode = 0x2204f2c; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | - BT878_APPERR | BT878_AFBUS; - /* 25,21,14,11,10,9,8,3,2 then - * 0x33 = 5,4,1,0 - * A_SEL=SML, DA_MLB, DA_SBR, - * DA_SDR=f, fifo trigger = 32 DWORDS - * IOM = 0 == audio A/D - * DPM = 0 == digital audio mode - * == async data parallel port - * then 0x33 (13 is set by start_capture) - * DA_APP = async data parallel port, - * ACAP_EN = 1, - * RISC+FIFO ENABLE */ - break; - - case BTTV_BOARD_PC_HDTV: - card->gpio_mode = 0x0100EC7B; - card->op_sync_orin = BT878_RISC_SYNC_MASK; - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; - break; - - default: - printk(KERN_WARNING "dvb_bt8xx: Unknown bttv card type: %d.\n", - sub->core->type); - kfree(card); - return -ENODEV; - } - - dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name); - - 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; - } - - if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) { - printk("dvb_bt8xx: unable to determine DMA core of card %d,\n", - card->bttv_nr); - printk("dvb_bt8xx: if you have the ALSA bt87x audio driver " - "installed, try removing it.\n"); - - kfree(card); - return -EFAULT; - } - - mutex_init(&card->bt->gpio_lock); - card->bt->bttv_nr = sub->core->nr; - - if ( (ret = dvb_bt8xx_load_card(card, sub->core->type)) ) { - kfree(card); - return ret; - } - - dev_set_drvdata(&sub->dev, card); - return 0; -} - -static void dvb_bt8xx_remove(struct bttv_sub_device *sub) -{ - struct dvb_bt8xx_card *card = dev_get_drvdata(&sub->dev); - - dprintk("dvb_bt8xx: unloading card%d\n", card->bttv_nr); - - bt878_stop(card->bt); - tasklet_kill(&card->bt->tasklet); - dvb_net_release(&card->dvbnet); - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); - card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); - dvb_dmxdev_release(&card->dmxdev); - dvb_dmx_release(&card->demux); - if (card->fe) { - dvb_unregister_frontend(card->fe); - dvb_frontend_detach(card->fe); - } - dvb_unregister_adapter(&card->dvb_adapter); - - kfree(card); -} - -static struct bttv_sub_driver driver = { - .drv = { - .name = "dvb-bt8xx", - }, - .probe = dvb_bt8xx_probe, - .remove = dvb_bt8xx_remove, - /* FIXME: - * .shutdown = dvb_bt8xx_shutdown, - * .suspend = dvb_bt8xx_suspend, - * .resume = dvb_bt8xx_resume, - */ -}; - -static int __init dvb_bt8xx_init(void) -{ - return bttv_sub_register(&driver, "dvb"); -} - -static void __exit dvb_bt8xx_exit(void) -{ - bttv_sub_unregister(&driver); -} - -module_init(dvb_bt8xx_init); -module_exit(dvb_bt8xx_exit); - -MODULE_DESCRIPTION("Bt8xx based DVB adapter driver"); -MODULE_AUTHOR("Florian Schirmer <jolt@tuxbox.org>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h deleted file mode 100644 index 4499ed2ac0e..00000000000 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Bt8xx based DVB adapter driver - * - * Copyright (C) 2002,2003 Florian Schirmer <jolt@tuxbox.org> - * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> - * Copyright (C) 1999-2001 Ralph Metzler & Marcus Metzler for convergence integrated media GmbH - * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef DVB_BT8XX_H -#define DVB_BT8XX_H - -#include <linux/i2c.h> -#include <linux/mutex.h> -#include "dvbdev.h" -#include "dvb_net.h" -#include "bttv.h" -#include "mt352.h" -#include "sp887x.h" -#include "dst_common.h" -#include "nxt6000.h" -#include "cx24110.h" -#include "or51211.h" -#include "lgdt330x.h" -#include "zl10353.h" -#include "tuner-simple.h" - -struct dvb_bt8xx_card { - struct mutex lock; - int nfeeds; - char card_name[32]; - struct dvb_adapter dvb_adapter; - struct bt878 *bt; - unsigned int bttv_nr; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dmx_frontend fe_hw; - struct dmx_frontend fe_mem; - u32 gpio_mode; - u32 op_sync_orin; - u32 irq_err_ignore; - struct i2c_adapter *i2c_adapter; - struct dvb_net dvbnet; - - struct dvb_frontend* fe; -}; - -#endif /* DVB_BT8XX_H */ diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig deleted file mode 100644 index 43f4d44edca..00000000000 --- a/drivers/media/dvb/dm1105/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -config DVB_DM1105 - tristate "SDMC DM1105 based PCI cards" - depends on DVB_CORE && PCI && I2C - depends on INPUT - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_STV0288 if !DVB_FE_CUSTOMISE - select DVB_STB6000 if !DVB_FE_CUSTOMISE - select DVB_CX24116 if !DVB_FE_CUSTOMISE - select DVB_SI21XX if !DVB_FE_CUSTOMISE - help - Support for cards based on the SDMC DM1105 PCI chip like - DvbWorld 2002 - - Since these cards have no MPEG decoder onboard, they transmit - only compressed MPEG data over the PCI bus, so you need - an external software decoder to watch TV on your computer. - - Say Y or M if you own such a device and want to use it. diff --git a/drivers/media/dvb/dm1105/Makefile b/drivers/media/dvb/dm1105/Makefile deleted file mode 100644 index 8ac28b0546a..00000000000 --- a/drivers/media/dvb/dm1105/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_DVB_DM1105) += dm1105.o - -EXTRA_CFLAGS += -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 deleted file mode 100644 index f48f73aff19..00000000000 --- a/drivers/media/dvb/dm1105/dm1105.c +++ /dev/null @@ -1,921 +0,0 @@ -/* - * dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip - * - * Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/i2c.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/proc_fs.h> -#include <linux/pci.h> -#include <linux/dma-mapping.h> -#include <linux/input.h> -#include <media/ir-common.h> - -#include "demux.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dvb_net.h" -#include "dvbdev.h" -#include "dvb-pll.h" - -#include "stv0299.h" -#include "stv0288.h" -#include "stb6000.h" -#include "si21xx.h" -#include "cx24116.h" -#include "z0194a.h" - -/* ----------------------------------------------- */ -/* - * PCI ID's - */ -#ifndef PCI_VENDOR_ID_TRIGEM -#define PCI_VENDOR_ID_TRIGEM 0x109f -#endif -#ifndef PCI_DEVICE_ID_DM1105 -#define PCI_DEVICE_ID_DM1105 0x036f -#endif -#ifndef PCI_DEVICE_ID_DW2002 -#define PCI_DEVICE_ID_DW2002 0x2002 -#endif -#ifndef PCI_DEVICE_ID_DW2004 -#define PCI_DEVICE_ID_DW2004 0x2004 -#endif -/* ----------------------------------------------- */ -/* sdmc dm1105 registers */ - -/* TS Control */ -#define DM1105_TSCTR 0x00 -#define DM1105_DTALENTH 0x04 - -/* GPIO Interface */ -#define DM1105_GPIOVAL 0x08 -#define DM1105_GPIOCTR 0x0c - -/* PID serial number */ -#define DM1105_PIDN 0x10 - -/* Odd-even secret key select */ -#define DM1105_CWSEL 0x14 - -/* Host Command Interface */ -#define DM1105_HOST_CTR 0x18 -#define DM1105_HOST_AD 0x1c - -/* PCI Interface */ -#define DM1105_CR 0x30 -#define DM1105_RST 0x34 -#define DM1105_STADR 0x38 -#define DM1105_RLEN 0x3c -#define DM1105_WRP 0x40 -#define DM1105_INTCNT 0x44 -#define DM1105_INTMAK 0x48 -#define DM1105_INTSTS 0x4c - -/* CW Value */ -#define DM1105_ODD 0x50 -#define DM1105_EVEN 0x58 - -/* PID Value */ -#define DM1105_PID 0x60 - -/* IR Control */ -#define DM1105_IRCTR 0x64 -#define DM1105_IRMODE 0x68 -#define DM1105_SYSTEMCODE 0x6c -#define DM1105_IRCODE 0x70 - -/* Unknown Values */ -#define DM1105_ENCRYPT 0x74 -#define DM1105_VER 0x7c - -/* I2C Interface */ -#define DM1105_I2CCTR 0x80 -#define DM1105_I2CSTS 0x81 -#define DM1105_I2CDAT 0x82 -#define DM1105_I2C_RA 0x83 -/* ----------------------------------------------- */ -/* Interrupt Mask Bits */ - -#define INTMAK_TSIRQM 0x01 -#define INTMAK_HIRQM 0x04 -#define INTMAK_IRM 0x08 -#define INTMAK_ALLMASK (INTMAK_TSIRQM | \ - INTMAK_HIRQM | \ - INTMAK_IRM) -#define INTMAK_NONEMASK 0x00 - -/* Interrupt Status Bits */ -#define INTSTS_TSIRQ 0x01 -#define INTSTS_HIRQ 0x04 -#define INTSTS_IR 0x08 - -/* IR Control Bits */ -#define DM1105_IR_EN 0x01 -#define DM1105_SYS_CHK 0x02 -#define DM1105_REP_FLG 0x08 - -/* EEPROM addr */ -#define IIC_24C01_addr 0xa0 -/* Max board count */ -#define DM1105_MAX 0x04 - -#define DRIVER_NAME "dm1105" - -#define DM1105_DMA_PACKETS 47 -#define DM1105_DMA_PACKET_LENGTH (128*4) -#define DM1105_DMA_BYTES (128 * 4 * DM1105_DMA_PACKETS) - -/* GPIO's for LNB power control */ -#define DM1105_LNB_MASK 0x00000000 -#define DM1105_LNB_13V 0x00010100 -#define DM1105_LNB_18V 0x00000100 - -static int ir_debug; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static u16 ir_codes_dm1105_nec[128] = { - [0x0a] = KEY_Q, /*power*/ - [0x0c] = KEY_M, /*mute*/ - [0x11] = KEY_1, - [0x12] = KEY_2, - [0x13] = KEY_3, - [0x14] = KEY_4, - [0x15] = KEY_5, - [0x16] = KEY_6, - [0x17] = KEY_7, - [0x18] = KEY_8, - [0x19] = KEY_9, - [0x10] = KEY_0, - [0x1c] = KEY_PAGEUP, /*ch+*/ - [0x0f] = KEY_PAGEDOWN, /*ch-*/ - [0x1a] = KEY_O, /*vol+*/ - [0x0e] = KEY_Z, /*vol-*/ - [0x04] = KEY_R, /*rec*/ - [0x09] = KEY_D, /*fav*/ - [0x08] = KEY_BACKSPACE, /*rewind*/ - [0x07] = KEY_A, /*fast*/ - [0x0b] = KEY_P, /*pause*/ - [0x02] = KEY_ESC, /*cancel*/ - [0x03] = KEY_G, /*tab*/ - [0x00] = KEY_UP, /*up*/ - [0x1f] = KEY_ENTER, /*ok*/ - [0x01] = KEY_DOWN, /*down*/ - [0x05] = KEY_C, /*cap*/ - [0x06] = KEY_S, /*stop*/ - [0x40] = KEY_F, /*full*/ - [0x1e] = KEY_W, /*tvmode*/ - [0x1b] = KEY_B, /*recall*/ -}; - -/* infrared remote control */ -struct infrared { - u16 key_map[128]; - struct input_dev *input_dev; - char input_phys[32]; - struct tasklet_struct ir_tasklet; - u32 ir_command; -}; - -struct dm1105dvb { - /* pci */ - struct pci_dev *pdev; - u8 __iomem *io_mem; - - /* ir */ - struct infrared ir; - - /* dvb */ - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - struct dmxdev dmxdev; - struct dvb_adapter dvb_adapter; - struct dvb_demux demux; - struct dvb_frontend *fe; - struct dvb_net dvbnet; - unsigned int full_ts_users; - - /* i2c */ - struct i2c_adapter i2c_adap; - - /* dma */ - dma_addr_t dma_addr; - unsigned char *ts_buf; - u32 wrp; - u32 buffer_size; - unsigned int PacketErrorCount; - unsigned int dmarst; - spinlock_t lock; - -}; - -#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg])) - -static struct dm1105dvb *dm1105dvb_local; - -static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct dm1105dvb *dm1105dvb ; - - int addr, rc, i, j, k, len, byte, data; - u8 status; - - dm1105dvb = i2c_adap->algo_data; - for (i = 0; i < num; i++) { - outb(0x00, dm_io_mem(DM1105_I2CCTR)); - if (msgs[i].flags & I2C_M_RD) { - /* read bytes */ - addr = msgs[i].addr << 1; - addr |= 1; - outb(addr, dm_io_mem(DM1105_I2CDAT)); - for (byte = 0; byte < msgs[i].len; byte++) - outb(0, dm_io_mem(DM1105_I2CDAT + byte + 1)); - - outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); - for (j = 0; j < 55; j++) { - mdelay(10); - status = inb(dm_io_mem(DM1105_I2CSTS)); - if ((status & 0xc0) == 0x40) - break; - } - if (j >= 55) - return -1; - - for (byte = 0; byte < msgs[i].len; byte++) { - rc = inb(dm_io_mem(DM1105_I2CDAT + byte + 1)); - if (rc < 0) - goto err; - msgs[i].buf[byte] = rc; - } - } else { - if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) { - /* prepaired for cx24116 firmware */ - /* Write in small blocks */ - len = msgs[i].len - 1; - k = 1; - do { - outb(msgs[i].addr << 1, dm_io_mem(DM1105_I2CDAT)); - outb(0xf7, dm_io_mem(DM1105_I2CDAT + 1)); - for (byte = 0; byte < (len > 48 ? 48 : len); byte++) { - data = msgs[i].buf[k+byte]; - outb(data, dm_io_mem(DM1105_I2CDAT + byte + 2)); - } - outb(0x82 + (len > 48 ? 48 : len), dm_io_mem(DM1105_I2CCTR)); - for (j = 0; j < 25; j++) { - mdelay(10); - status = inb(dm_io_mem(DM1105_I2CSTS)); - if ((status & 0xc0) == 0x40) - break; - } - - if (j >= 25) - return -1; - - k += 48; - len -= 48; - } while (len > 0); - } else { - /* write bytes */ - outb(msgs[i].addr<<1, dm_io_mem(DM1105_I2CDAT)); - for (byte = 0; byte < msgs[i].len; byte++) { - data = msgs[i].buf[byte]; - outb(data, dm_io_mem(DM1105_I2CDAT + byte + 1)); - } - outb(0x81 + msgs[i].len, dm_io_mem(DM1105_I2CCTR)); - for (j = 0; j < 25; j++) { - mdelay(10); - status = inb(dm_io_mem(DM1105_I2CSTS)); - if ((status & 0xc0) == 0x40) - break; - } - - if (j >= 25) - return -1; - } - } - } - return num; - err: - return rc; -} - -static u32 functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm dm1105_algo = { - .master_xfer = dm1105_i2c_xfer, - .functionality = functionality, -}; - -static inline struct dm1105dvb *feed_to_dm1105dvb(struct dvb_demux_feed *feed) -{ - return container_of(feed->demux, struct dm1105dvb, demux); -} - -static inline struct dm1105dvb *frontend_to_dm1105dvb(struct dvb_frontend *fe) -{ - return container_of(fe->dvb, struct dm1105dvb, dvb_adapter); -} - -static int dm1105dvb_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct dm1105dvb *dm1105dvb = frontend_to_dm1105dvb(fe); - - if (voltage == SEC_VOLTAGE_18) { - outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); - outl(DM1105_LNB_18V, dm_io_mem(DM1105_GPIOVAL)); - } else { - /*LNB ON-13V by default!*/ - outl(DM1105_LNB_MASK, dm_io_mem(DM1105_GPIOCTR)); - outl(DM1105_LNB_13V, dm_io_mem(DM1105_GPIOVAL)); - } - - return 0; -} - -static void dm1105dvb_set_dma_addr(struct dm1105dvb *dm1105dvb) -{ - outl(cpu_to_le32(dm1105dvb->dma_addr), dm_io_mem(DM1105_STADR)); -} - -static int __devinit dm1105dvb_dma_map(struct dm1105dvb *dm1105dvb) -{ - dm1105dvb->ts_buf = pci_alloc_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, &dm1105dvb->dma_addr); - - return !dm1105dvb->ts_buf; -} - -static void dm1105dvb_dma_unmap(struct dm1105dvb *dm1105dvb) -{ - pci_free_consistent(dm1105dvb->pdev, 6*DM1105_DMA_BYTES, dm1105dvb->ts_buf, dm1105dvb->dma_addr); -} - -static void dm1105dvb_enable_irqs(struct dm1105dvb *dm1105dvb) -{ - outb(INTMAK_ALLMASK, dm_io_mem(DM1105_INTMAK)); - outb(1, dm_io_mem(DM1105_CR)); -} - -static void dm1105dvb_disable_irqs(struct dm1105dvb *dm1105dvb) -{ - outb(INTMAK_IRM, dm_io_mem(DM1105_INTMAK)); - outb(0, dm_io_mem(DM1105_CR)); -} - -static int dm1105dvb_start_feed(struct dvb_demux_feed *f) -{ - struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); - - if (dm1105dvb->full_ts_users++ == 0) - dm1105dvb_enable_irqs(dm1105dvb); - - return 0; -} - -static int dm1105dvb_stop_feed(struct dvb_demux_feed *f) -{ - struct dm1105dvb *dm1105dvb = feed_to_dm1105dvb(f); - - if (--dm1105dvb->full_ts_users == 0) - dm1105dvb_disable_irqs(dm1105dvb); - - return 0; -} - -/* ir tasklet */ -static void dm1105_emit_key(unsigned long parm) -{ - struct infrared *ir = (struct infrared *) parm; - u32 ircom = ir->ir_command; - u8 data; - u16 keycode; - - data = (ircom >> 8) & 0x7f; - - input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data); - input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); - keycode = ir->key_map[data]; - - if (!keycode) - return; - - input_event(ir->input_dev, EV_KEY, keycode, 1); - input_sync(ir->input_dev); - input_event(ir->input_dev, EV_KEY, keycode, 0); - input_sync(ir->input_dev); - -} - -static irqreturn_t dm1105dvb_irq(int irq, void *dev_id) -{ - struct dm1105dvb *dm1105dvb = dev_id; - unsigned int piece; - unsigned int nbpackets; - u32 command; - u32 nextwrp; - u32 oldwrp; - - /* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */ - unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS)); - outb(intsts, dm_io_mem(DM1105_INTSTS)); - - switch (intsts) { - case INTSTS_TSIRQ: - case (INTSTS_TSIRQ | INTSTS_IR): - nextwrp = inl(dm_io_mem(DM1105_WRP)) - - inl(dm_io_mem(DM1105_STADR)) ; - oldwrp = dm1105dvb->wrp; - spin_lock(&dm1105dvb->lock); - if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) && - (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) { - dm1105dvb->PacketErrorCount++; - /* bad packet found */ - if ((dm1105dvb->PacketErrorCount >= 2) && - (dm1105dvb->dmarst == 0)) { - outb(1, dm_io_mem(DM1105_RST)); - dm1105dvb->wrp = 0; - dm1105dvb->PacketErrorCount = 0; - dm1105dvb->dmarst = 0; - spin_unlock(&dm1105dvb->lock); - return IRQ_HANDLED; - } - } - if (nextwrp < oldwrp) { - piece = dm1105dvb->buffer_size - oldwrp; - memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp); - nbpackets = (piece + nextwrp)/188; - } else { - nbpackets = (nextwrp - oldwrp)/188; - } - dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets); - dm1105dvb->wrp = nextwrp; - spin_unlock(&dm1105dvb->lock); - break; - case INTSTS_IR: - command = inl(dm_io_mem(DM1105_IRCODE)); - if (ir_debug) - printk("dm1105: received byte 0x%04x\n", command); - - dm1105dvb->ir.ir_command = command; - tasklet_schedule(&dm1105dvb->ir.ir_tasklet); - break; - } - return IRQ_HANDLED; - - -} - -/* register with input layer */ -static void input_register_keys(struct infrared *ir) -{ - int i; - - memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); - - for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) - set_bit(ir->key_map[i], ir->input_dev->keybit); - - ir->input_dev->keycode = ir->key_map; - ir->input_dev->keycodesize = sizeof(ir->key_map[0]); - ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); -} - -int __devinit dm1105_ir_init(struct dm1105dvb *dm1105) -{ - struct input_dev *input_dev; - int err; - - dm1105dvb_local = dm1105; - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - dm1105->ir.input_dev = input_dev; - snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys), - "pci-%s/ir0", pci_name(dm1105->pdev)); - - input_dev->evbit[0] = BIT(EV_KEY); - input_dev->name = "DVB on-card IR receiver"; - - input_dev->phys = dm1105->ir.input_phys; - input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 2; - if (dm1105->pdev->subsystem_vendor) { - input_dev->id.vendor = dm1105->pdev->subsystem_vendor; - input_dev->id.product = dm1105->pdev->subsystem_device; - } else { - input_dev->id.vendor = dm1105->pdev->vendor; - input_dev->id.product = dm1105->pdev->device; - } - input_dev->dev.parent = &dm1105->pdev->dev; - /* initial keymap */ - memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map); - input_register_keys(&dm1105->ir); - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; - } - - tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir); - - return 0; -} - - -void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105) -{ - tasklet_kill(&dm1105->ir.ir_tasklet); - input_unregister_device(dm1105->ir.input_dev); - -} - -static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb) -{ - dm1105dvb_disable_irqs(dm1105dvb); - - outb(0, dm_io_mem(DM1105_HOST_CTR)); - - /*DATALEN 188,*/ - outb(188, dm_io_mem(DM1105_DTALENTH)); - /*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/ - outw(0xc10a, dm_io_mem(DM1105_TSCTR)); - - /* map DMA and set address */ - dm1105dvb_dma_map(dm1105dvb); - dm1105dvb_set_dma_addr(dm1105dvb); - /* big buffer */ - outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN)); - outb(47, dm_io_mem(DM1105_INTCNT)); - - /* IR NEC mode enable */ - outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR)); - outb(0, dm_io_mem(DM1105_IRMODE)); - outw(0, dm_io_mem(DM1105_SYSTEMCODE)); - - return 0; -} - -static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb) -{ - dm1105dvb_disable_irqs(dm1105dvb); - - /* IR disable */ - outb(0, dm_io_mem(DM1105_IRCTR)); - outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK)); - - dm1105dvb_dma_unmap(dm1105dvb); -} - -static struct stv0299_config sharp_z0194a_config = { - .demod_address = 0x68, - .inittab = sharp_z0194a_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a_set_symbol_rate, -}; - -static struct stv0288_config earda_config = { - .demod_address = 0x68, - .min_delay_ms = 100, -}; - -static struct si21xx_config serit_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - -}; - -static struct cx24116_config serit_sp2633_config = { - .demod_address = 0x55, -}; - -static int __devinit frontend_init(struct dm1105dvb *dm1105dvb) -{ - int ret; - - switch (dm1105dvb->pdev->subsystem_device) { - case PCI_DEVICE_ID_DW2002: - dm1105dvb->fe = dvb_attach( - stv0299_attach, &sharp_z0194a_config, - &dm1105dvb->i2c_adap); - - if (dm1105dvb->fe) { - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60, - &dm1105dvb->i2c_adap, DVB_PLL_OPERA1); - } - - if (!dm1105dvb->fe) { - dm1105dvb->fe = dvb_attach( - stv0288_attach, &earda_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) { - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61, - &dm1105dvb->i2c_adap); - } - } - - if (!dm1105dvb->fe) { - dm1105dvb->fe = dvb_attach( - si21xx_attach, &serit_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) - dm1105dvb->fe->ops.set_voltage = - dm1105dvb_set_voltage; - } - break; - case PCI_DEVICE_ID_DW2004: - dm1105dvb->fe = dvb_attach( - cx24116_attach, &serit_sp2633_config, - &dm1105dvb->i2c_adap); - if (dm1105dvb->fe) - dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage; - break; - } - - if (!dm1105dvb->fe) { - dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n"); - return -ENODEV; - } - - ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe); - if (ret < 0) { - if (dm1105dvb->fe->ops.release) - dm1105dvb->fe->ops.release(dm1105dvb->fe); - dm1105dvb->fe = NULL; - return ret; - } - - return 0; -} - -static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac) -{ - static u8 command[1] = { 0x28 }; - - struct i2c_msg msg[] = { - { .addr = IIC_24C01_addr >> 1, .flags = 0, - .buf = command, .len = 1 }, - { .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD, - .buf = mac, .len = 6 }, - }; - - dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2); - dev_info(&dm1105dvb->pdev->dev, "MAC %pM\n", mac); -} - -static int __devinit dm1105_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct dm1105dvb *dm1105dvb; - struct dvb_adapter *dvb_adapter; - struct dvb_demux *dvbdemux; - struct dmx_demux *dmx; - int ret = -ENOMEM; - - dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL); - if (!dm1105dvb) - goto out; - - dm1105dvb->pdev = pdev; - dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES; - dm1105dvb->PacketErrorCount = 0; - dm1105dvb->dmarst = 0; - - ret = pci_enable_device(pdev); - if (ret < 0) - goto err_kfree; - - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (ret < 0) - goto err_pci_disable_device; - - pci_set_master(pdev); - - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret < 0) - goto err_pci_disable_device; - - dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); - if (!dm1105dvb->io_mem) { - ret = -EIO; - goto err_pci_release_regions; - } - - spin_lock_init(&dm1105dvb->lock); - pci_set_drvdata(pdev, dm1105dvb); - - ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb); - if (ret < 0) - goto err_pci_iounmap; - - ret = dm1105dvb_hw_init(dm1105dvb); - if (ret < 0) - goto err_free_irq; - - /* i2c */ - i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb); - strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME); - dm1105dvb->i2c_adap.owner = THIS_MODULE; - dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - dm1105dvb->i2c_adap.dev.parent = &pdev->dev; - dm1105dvb->i2c_adap.algo = &dm1105_algo; - dm1105dvb->i2c_adap.algo_data = dm1105dvb; - ret = i2c_add_adapter(&dm1105dvb->i2c_adap); - - if (ret < 0) - goto err_dm1105dvb_hw_exit; - - /* dvb */ - ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME, - THIS_MODULE, &pdev->dev, adapter_nr); - if (ret < 0) - goto err_i2c_del_adapter; - - dvb_adapter = &dm1105dvb->dvb_adapter; - - dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac); - - dvbdemux = &dm1105dvb->demux; - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = dm1105dvb_start_feed; - dvbdemux->stop_feed = dm1105dvb_stop_feed; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); - ret = dvb_dmx_init(dvbdemux); - if (ret < 0) - goto err_dvb_unregister_adapter; - - dmx = &dvbdemux->dmx; - dm1105dvb->dmxdev.filternum = 256; - dm1105dvb->dmxdev.demux = dmx; - dm1105dvb->dmxdev.capabilities = 0; - - ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter); - if (ret < 0) - goto err_dvb_dmx_release; - - dm1105dvb->hw_frontend.source = DMX_FRONTEND_0; - - ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend); - if (ret < 0) - goto err_dvb_dmxdev_release; - - dm1105dvb->mem_frontend.source = DMX_MEMORY_FE; - - ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend); - if (ret < 0) - goto err_remove_hw_frontend; - - ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend); - if (ret < 0) - goto err_remove_mem_frontend; - - ret = frontend_init(dm1105dvb); - if (ret < 0) - goto err_disconnect_frontend; - - dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx); - dm1105_ir_init(dm1105dvb); -out: - return ret; - -err_disconnect_frontend: - dmx->disconnect_frontend(dmx); -err_remove_mem_frontend: - dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); -err_remove_hw_frontend: - dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); -err_dvb_dmxdev_release: - dvb_dmxdev_release(&dm1105dvb->dmxdev); -err_dvb_dmx_release: - dvb_dmx_release(dvbdemux); -err_dvb_unregister_adapter: - dvb_unregister_adapter(dvb_adapter); -err_i2c_del_adapter: - i2c_del_adapter(&dm1105dvb->i2c_adap); -err_dm1105dvb_hw_exit: - dm1105dvb_hw_exit(dm1105dvb); -err_free_irq: - free_irq(pdev->irq, dm1105dvb); -err_pci_iounmap: - pci_iounmap(pdev, dm1105dvb->io_mem); -err_pci_release_regions: - pci_release_regions(pdev); -err_pci_disable_device: - pci_disable_device(pdev); -err_kfree: - pci_set_drvdata(pdev, NULL); - kfree(dm1105dvb); - goto out; -} - -static void __devexit dm1105_remove(struct pci_dev *pdev) -{ - struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev); - struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter; - struct dvb_demux *dvbdemux = &dm1105dvb->demux; - struct dmx_demux *dmx = &dvbdemux->dmx; - - dm1105_ir_exit(dm1105dvb); - dmx->close(dmx); - dvb_net_release(&dm1105dvb->dvbnet); - if (dm1105dvb->fe) - dvb_unregister_frontend(dm1105dvb->fe); - - dmx->disconnect_frontend(dmx); - dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend); - dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend); - dvb_dmxdev_release(&dm1105dvb->dmxdev); - dvb_dmx_release(dvbdemux); - dvb_unregister_adapter(dvb_adapter); - if (&dm1105dvb->i2c_adap) - i2c_del_adapter(&dm1105dvb->i2c_adap); - - dm1105dvb_hw_exit(dm1105dvb); - synchronize_irq(pdev->irq); - free_irq(pdev->irq, dm1105dvb); - pci_iounmap(pdev, dm1105dvb->io_mem); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - kfree(dm1105dvb); -} - -static struct pci_device_id dm1105_id_table[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_TRIGEM, - .device = PCI_DEVICE_ID_DM1105, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_DEVICE_ID_DW2002, - }, { - .vendor = PCI_VENDOR_ID_TRIGEM, - .device = PCI_DEVICE_ID_DM1105, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_DEVICE_ID_DW2004, - }, { - /* empty */ - }, -}; - -MODULE_DEVICE_TABLE(pci, dm1105_id_table); - -static struct pci_driver dm1105_driver = { - .name = DRIVER_NAME, - .id_table = dm1105_id_table, - .probe = dm1105_probe, - .remove = __devexit_p(dm1105_remove), -}; - -static int __init dm1105_init(void) -{ - return pci_register_driver(&dm1105_driver); -} - -static void __exit dm1105_exit(void) -{ - pci_unregister_driver(&dm1105_driver); -} - -module_init(dm1105_init); -module_exit(dm1105_exit); - -MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>"); -MODULE_DESCRIPTION("SDMC DM1105 DVB driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile deleted file mode 100644 index 0b5182835cc..00000000000 --- a/drivers/media/dvb/dvb-core/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# Makefile for the kernel DVB device drivers. -# - -dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_ca_en50221.o dvb_frontend.o \ - dvb_net.o dvb_ringbuffer.o dvb_math.o - -obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h deleted file mode 100644 index eb91fd808c1..00000000000 --- a/drivers/media/dvb/dvb-core/demux.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * demux.h - * - * Copyright (c) 2002 Convergence GmbH - * - * based on code: - * Copyright (c) 2000 Nokia Research Center - * Tampere, FINLAND - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef __DEMUX_H -#define __DEMUX_H - -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/list.h> -#include <linux/time.h> -#include <linux/dvb/dmx.h> - -/*--------------------------------------------------------------------------*/ -/* Common definitions */ -/*--------------------------------------------------------------------------*/ - -/* - * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter. - */ - -#ifndef DMX_MAX_FILTER_SIZE -#define DMX_MAX_FILTER_SIZE 18 -#endif - -/* - * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. - */ - -#ifndef DMX_MAX_SECTION_SIZE -#define DMX_MAX_SECTION_SIZE 4096 -#endif -#ifndef DMX_MAX_SECFEED_SIZE -#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188) -#endif - - -/* - * enum dmx_success: Success codes for the Demux Callback API. - */ - -enum dmx_success { - DMX_OK = 0, /* Received Ok */ - DMX_LENGTH_ERROR, /* Incorrect length */ - DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ - DMX_CRC_ERROR, /* Incorrect CRC */ - DMX_FRAME_ERROR, /* Frame alignment error */ - DMX_FIFO_ERROR, /* Receiver FIFO overrun */ - DMX_MISSED_ERROR /* Receiver missed packet */ -} ; - -/*--------------------------------------------------------------------------*/ -/* TS packet reception */ -/*--------------------------------------------------------------------------*/ - -/* TS filter type for set() */ - -#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */ -#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS - payload (<=184 bytes per packet) to callback */ -#define TS_DECODER 4 /* send stream to built-in decoder (if present) */ -#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to - the demux device, not to the dvr device */ - -/* PES type for filters which write to built-in decoder */ -/* these should be kept identical to the types in dmx.h */ - -enum dmx_ts_pes -{ /* also send packets to decoder (if it exists) */ - DMX_TS_PES_AUDIO0, - DMX_TS_PES_VIDEO0, - DMX_TS_PES_TELETEXT0, - DMX_TS_PES_SUBTITLE0, - DMX_TS_PES_PCR0, - - DMX_TS_PES_AUDIO1, - DMX_TS_PES_VIDEO1, - DMX_TS_PES_TELETEXT1, - DMX_TS_PES_SUBTITLE1, - DMX_TS_PES_PCR1, - - DMX_TS_PES_AUDIO2, - DMX_TS_PES_VIDEO2, - DMX_TS_PES_TELETEXT2, - DMX_TS_PES_SUBTITLE2, - DMX_TS_PES_PCR2, - - DMX_TS_PES_AUDIO3, - DMX_TS_PES_VIDEO3, - DMX_TS_PES_TELETEXT3, - DMX_TS_PES_SUBTITLE3, - DMX_TS_PES_PCR3, - - DMX_TS_PES_OTHER -}; - -#define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0 -#define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0 -#define DMX_TS_PES_TELETEXT DMX_TS_PES_TELETEXT0 -#define DMX_TS_PES_SUBTITLE DMX_TS_PES_SUBTITLE0 -#define DMX_TS_PES_PCR DMX_TS_PES_PCR0 - - -struct dmx_ts_feed { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux *parent; /* Back-pointer */ - void *priv; /* Pointer to private data of the API client */ - int (*set) (struct dmx_ts_feed *feed, - u16 pid, - int type, - enum dmx_ts_pes pes_type, - size_t circular_buffer_size, - struct timespec timeout); - int (*start_filtering) (struct dmx_ts_feed* feed); - int (*stop_filtering) (struct dmx_ts_feed* feed); -}; - -/*--------------------------------------------------------------------------*/ -/* Section reception */ -/*--------------------------------------------------------------------------*/ - -struct dmx_section_filter { - u8 filter_value [DMX_MAX_FILTER_SIZE]; - u8 filter_mask [DMX_MAX_FILTER_SIZE]; - u8 filter_mode [DMX_MAX_FILTER_SIZE]; - struct dmx_section_feed* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ -}; - -struct dmx_section_feed { - int is_filtering; /* Set to non-zero when filtering in progress */ - struct dmx_demux* parent; /* Back-pointer */ - void* priv; /* Pointer to private data of the API client */ - - int check_crc; - u32 crc_val; - - u8 *secbuf; - u8 secbuf_base[DMX_MAX_SECFEED_SIZE]; - u16 secbufp, seclen, tsfeedp; - - int (*set) (struct dmx_section_feed* feed, - u16 pid, - size_t circular_buffer_size, - int check_crc); - int (*allocate_filter) (struct dmx_section_feed* feed, - struct dmx_section_filter** filter); - int (*release_filter) (struct dmx_section_feed* feed, - struct dmx_section_filter* filter); - int (*start_filtering) (struct dmx_section_feed* feed); - int (*stop_filtering) (struct dmx_section_feed* feed); -}; - -/*--------------------------------------------------------------------------*/ -/* Callback functions */ -/*--------------------------------------------------------------------------*/ - -typedef int (*dmx_ts_cb) ( const u8 * buffer1, - size_t buffer1_length, - const u8 * buffer2, - size_t buffer2_length, - struct dmx_ts_feed* source, - enum dmx_success success); - -typedef int (*dmx_section_cb) ( const u8 * buffer1, - size_t buffer1_len, - const u8 * buffer2, - size_t buffer2_len, - struct dmx_section_filter * source, - enum dmx_success success); - -/*--------------------------------------------------------------------------*/ -/* DVB Front-End */ -/*--------------------------------------------------------------------------*/ - -enum dmx_frontend_source { - DMX_MEMORY_FE, - DMX_FRONTEND_0, - DMX_FRONTEND_1, - DMX_FRONTEND_2, - DMX_FRONTEND_3, - DMX_STREAM_0, /* external stream input, e.g. LVDS */ - DMX_STREAM_1, - DMX_STREAM_2, - DMX_STREAM_3 -}; - -struct dmx_frontend { - struct list_head connectivity_list; /* List of front-ends that can - be connected to a particular - demux */ - enum dmx_frontend_source source; -}; - -/*--------------------------------------------------------------------------*/ -/* MPEG-2 TS Demux */ -/*--------------------------------------------------------------------------*/ - -/* - * Flags OR'ed in the capabilities field of struct dmx_demux. - */ - -#define DMX_TS_FILTERING 1 -#define DMX_PES_FILTERING 2 -#define DMX_SECTION_FILTERING 4 -#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */ -#define DMX_CRC_CHECKING 16 -#define DMX_TS_DESCRAMBLING 32 - -/* - * Demux resource type identifier. -*/ - -/* - * DMX_FE_ENTRY(): Casts elements in the list of registered - * front-ends from the generic type struct list_head - * to the type * struct dmx_frontend - *. -*/ - -#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list) - -struct dmx_demux { - u32 capabilities; /* Bitfield of capability flags */ - struct dmx_frontend* frontend; /* Front-end connected to the demux */ - void* priv; /* Pointer to private data of the API client */ - int (*open) (struct dmx_demux* demux); - int (*close) (struct dmx_demux* demux); - int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count); - int (*allocate_ts_feed) (struct dmx_demux* demux, - struct dmx_ts_feed** feed, - dmx_ts_cb callback); - int (*release_ts_feed) (struct dmx_demux* demux, - struct dmx_ts_feed* feed); - int (*allocate_section_feed) (struct dmx_demux* demux, - struct dmx_section_feed** feed, - dmx_section_cb callback); - int (*release_section_feed) (struct dmx_demux* demux, - struct dmx_section_feed* feed); - int (*add_frontend) (struct dmx_demux* demux, - struct dmx_frontend* frontend); - int (*remove_frontend) (struct dmx_demux* demux, - struct dmx_frontend* frontend); - struct list_head* (*get_frontends) (struct dmx_demux* demux); - int (*connect_frontend) (struct dmx_demux* demux, - struct dmx_frontend* frontend); - int (*disconnect_frontend) (struct dmx_demux* demux); - - int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids); - - int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps); - - int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src); - - int (*get_stc) (struct dmx_demux* demux, unsigned int num, - u64 *stc, unsigned int *base); -}; - -#endif /* #ifndef __DEMUX_H */ diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c deleted file mode 100644 index 0c733c66a44..00000000000 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ /dev/null @@ -1,1166 +0,0 @@ -/* - * dmxdev.c - DVB demultiplexer device - * - * Copyright (C) 2000 Ralph Metzler & Marcus Metzler - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include <linux/spinlock.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/module.h> -#include <linux/poll.h> -#include <linux/ioctl.h> -#include <linux/wait.h> -#include <asm/uaccess.h> -#include <asm/system.h> -#include "dmxdev.h" - -static int debug; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); - -#define dprintk if (debug) printk - -static int dvb_dmxdev_buffer_write(struct dvb_ringbuffer *buf, - const u8 *src, size_t len) -{ - ssize_t free; - - if (!len) - return 0; - if (!buf->data) - return 0; - - free = dvb_ringbuffer_free(buf); - if (len > free) { - dprintk("dmxdev: buffer overflow\n"); - return -EOVERFLOW; - } - - return dvb_ringbuffer_write(buf, src, len); -} - -static ssize_t dvb_dmxdev_buffer_read(struct dvb_ringbuffer *src, - int non_blocking, char __user *buf, - size_t count, loff_t *ppos) -{ - size_t todo; - ssize_t avail; - ssize_t ret = 0; - - if (!src->data) - return 0; - - if (src->error) { - ret = src->error; - dvb_ringbuffer_flush(src); - return ret; - } - - for (todo = count; todo > 0; todo -= ret) { - if (non_blocking && dvb_ringbuffer_empty(src)) { - ret = -EWOULDBLOCK; - break; - } - - ret = wait_event_interruptible(src->queue, - !dvb_ringbuffer_empty(src) || - (src->error != 0)); - if (ret < 0) - break; - - if (src->error) { - ret = src->error; - dvb_ringbuffer_flush(src); - break; - } - - avail = dvb_ringbuffer_avail(src); - if (avail > todo) - avail = todo; - - ret = dvb_ringbuffer_read_user(src, buf, avail); - if (ret < 0) - break; - - buf += ret; - } - - return (count - todo) ? (count - todo) : ret; -} - -static struct dmx_frontend *get_fe(struct dmx_demux *demux, int type) -{ - struct list_head *head, *pos; - - head = demux->get_frontends(demux); - if (!head) - return NULL; - list_for_each(pos, head) - if (DMX_FE_ENTRY(pos)->source == type) - return DMX_FE_ENTRY(pos); - - return NULL; -} - -static int dvb_dvr_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - struct dmx_frontend *front; - - dprintk("function : %s\n", __func__); - - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - if (dmxdev->exit) { - mutex_unlock(&dmxdev->mutex); - return -ENODEV; - } - - if ((file->f_flags & O_ACCMODE) == O_RDWR) { - if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { - mutex_unlock(&dmxdev->mutex); - return -EOPNOTSUPP; - } - } - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - void *mem; - if (!dvbdev->readers) { - mutex_unlock(&dmxdev->mutex); - return -EBUSY; - } - mem = vmalloc(DVR_BUFFER_SIZE); - if (!mem) { - mutex_unlock(&dmxdev->mutex); - return -ENOMEM; - } - dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); - dvbdev->readers--; - } - - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { - dmxdev->dvr_orig_fe = dmxdev->demux->frontend; - - if (!dmxdev->demux->write) { - mutex_unlock(&dmxdev->mutex); - return -EOPNOTSUPP; - } - - front = get_fe(dmxdev->demux, DMX_MEMORY_FE); - - if (!front) { - mutex_unlock(&dmxdev->mutex); - return -EINVAL; - } - dmxdev->demux->disconnect_frontend(dmxdev->demux); - dmxdev->demux->connect_frontend(dmxdev->demux, front); - } - dvbdev->users++; - mutex_unlock(&dmxdev->mutex); - return 0; -} - -static int dvb_dvr_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - - mutex_lock(&dmxdev->mutex); - - if ((file->f_flags & O_ACCMODE) == O_WRONLY) { - dmxdev->demux->disconnect_frontend(dmxdev->demux); - dmxdev->demux->connect_frontend(dmxdev->demux, - dmxdev->dvr_orig_fe); - } - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - dvbdev->readers++; - if (dmxdev->dvr_buffer.data) { - void *mem = dmxdev->dvr_buffer.data; - mb(); - spin_lock_irq(&dmxdev->lock); - dmxdev->dvr_buffer.data = NULL; - spin_unlock_irq(&dmxdev->lock); - vfree(mem); - } - } - /* TODO */ - dvbdev->users--; - if(dvbdev->users==-1 && dmxdev->exit==1) { - fops_put(file->f_op); - file->f_op = NULL; - mutex_unlock(&dmxdev->mutex); - wake_up(&dvbdev->wait_queue); - } else - mutex_unlock(&dmxdev->mutex); - - return 0; -} - -static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - int ret; - - if (!dmxdev->demux->write) - return -EOPNOTSUPP; - if ((file->f_flags & O_ACCMODE) != O_WRONLY) - return -EINVAL; - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - if (dmxdev->exit) { - mutex_unlock(&dmxdev->mutex); - return -ENODEV; - } - ret = dmxdev->demux->write(dmxdev->demux, buf, count); - mutex_unlock(&dmxdev->mutex); - return ret; -} - -static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - int ret; - - if (dmxdev->exit) { - mutex_unlock(&dmxdev->mutex); - return -ENODEV; - } - - //mutex_lock(&dmxdev->mutex); - ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); - //mutex_unlock(&dmxdev->mutex); - return ret; -} - -static int dvb_dvr_set_buffer_size(struct dmxdev *dmxdev, - unsigned long size) -{ - struct dvb_ringbuffer *buf = &dmxdev->dvr_buffer; - void *newmem; - void *oldmem; - - dprintk("function : %s\n", __func__); - - if (buf->size == size) - return 0; - if (!size) - return -EINVAL; - - newmem = vmalloc(size); - if (!newmem) - return -ENOMEM; - - oldmem = buf->data; - - spin_lock_irq(&dmxdev->lock); - buf->data = newmem; - buf->size = size; - - /* reset and not flush in case the buffer shrinks */ - dvb_ringbuffer_reset(buf); - spin_unlock_irq(&dmxdev->lock); - - vfree(oldmem); - - return 0; -} - -static inline void dvb_dmxdev_filter_state_set(struct dmxdev_filter - *dmxdevfilter, int state) -{ - spin_lock_irq(&dmxdevfilter->dev->lock); - dmxdevfilter->state = state; - spin_unlock_irq(&dmxdevfilter->dev->lock); -} - -static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter, - unsigned long size) -{ - struct dvb_ringbuffer *buf = &dmxdevfilter->buffer; - void *newmem; - void *oldmem; - - if (buf->size == size) - return 0; - if (!size) - return -EINVAL; - if (dmxdevfilter->state >= DMXDEV_STATE_GO) - return -EBUSY; - - newmem = vmalloc(size); - if (!newmem) - return -ENOMEM; - - oldmem = buf->data; - - spin_lock_irq(&dmxdevfilter->dev->lock); - buf->data = newmem; - buf->size = size; - - /* reset and not flush in case the buffer shrinks */ - dvb_ringbuffer_reset(buf); - spin_unlock_irq(&dmxdevfilter->dev->lock); - - vfree(oldmem); - - return 0; -} - -static void dvb_dmxdev_filter_timeout(unsigned long data) -{ - struct dmxdev_filter *dmxdevfilter = (struct dmxdev_filter *)data; - - dmxdevfilter->buffer.error = -ETIMEDOUT; - spin_lock_irq(&dmxdevfilter->dev->lock); - dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT; - spin_unlock_irq(&dmxdevfilter->dev->lock); - wake_up(&dmxdevfilter->buffer.queue); -} - -static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) -{ - struct dmx_sct_filter_params *para = &dmxdevfilter->params.sec; - - del_timer(&dmxdevfilter->timer); - if (para->timeout) { - dmxdevfilter->timer.function = dvb_dmxdev_filter_timeout; - dmxdevfilter->timer.data = (unsigned long)dmxdevfilter; - dmxdevfilter->timer.expires = - jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000; - add_timer(&dmxdevfilter->timer); - } -} - -static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *filter, - enum dmx_success success) -{ - struct dmxdev_filter *dmxdevfilter = filter->priv; - unsigned long flags; - int ret; - - if (dmxdevfilter->buffer.error) { - wake_up(&dmxdevfilter->buffer.queue); - return 0; - } - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); - if (dmxdevfilter->state != DMXDEV_STATE_GO) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); - return 0; - } - del_timer(&dmxdevfilter->timer); - dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", - buffer1[0], buffer1[1], - buffer1[2], buffer1[3], buffer1[4], buffer1[5]); - ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer1, - buffer1_len); - if (ret == buffer1_len) { - ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, - buffer2_len); - } - if (ret < 0) { - dvb_ringbuffer_flush(&dmxdevfilter->buffer); - dmxdevfilter->buffer.error = ret; - } - if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) - dmxdevfilter->state = DMXDEV_STATE_DONE; - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); - wake_up(&dmxdevfilter->buffer.queue); - return 0; -} - -static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_ts_feed *feed, - enum dmx_success success) -{ - struct dmxdev_filter *dmxdevfilter = feed->priv; - struct dvb_ringbuffer *buffer; - unsigned long flags; - int ret; - - spin_lock_irqsave(&dmxdevfilter->dev->lock, flags); - if (dmxdevfilter->params.pes.output == DMX_OUT_DECODER) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); - return 0; - } - - if (dmxdevfilter->params.pes.output == DMX_OUT_TAP - || dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) - buffer = &dmxdevfilter->buffer; - else - buffer = &dmxdevfilter->dev->dvr_buffer; - if (buffer->error) { - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); - wake_up(&buffer->queue); - return 0; - } - 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); - buffer->error = ret; - } - spin_unlock_irqrestore(&dmxdevfilter->dev->lock, flags); - wake_up(&buffer->queue); - return 0; -} - -/* stop feed but only mark the specified filter as stopped (state set) */ -static int dvb_dmxdev_feed_stop(struct dmxdev_filter *dmxdevfilter) -{ - dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - - switch (dmxdevfilter->type) { - case DMXDEV_TYPE_SEC: - del_timer(&dmxdevfilter->timer); - dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec); - break; - case DMXDEV_TYPE_PES: - dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts); - break; - default: - return -EINVAL; - } - return 0; -} - -/* start feed associated with the specified filter */ -static int dvb_dmxdev_feed_start(struct dmxdev_filter *filter) -{ - dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO); - - switch (filter->type) { - case DMXDEV_TYPE_SEC: - return filter->feed.sec->start_filtering(filter->feed.sec); - case DMXDEV_TYPE_PES: - return filter->feed.ts->start_filtering(filter->feed.ts); - default: - return -EINVAL; - } - - return 0; -} - -/* restart section feed if it has filters left associated with it, - otherwise release the feed */ -static int dvb_dmxdev_feed_restart(struct dmxdev_filter *filter) -{ - int i; - struct dmxdev *dmxdev = filter->dev; - u16 pid = filter->params.sec.pid; - - for (i = 0; i < dmxdev->filternum; i++) - if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && - dmxdev->filter[i].type == DMXDEV_TYPE_SEC && - dmxdev->filter[i].params.sec.pid == pid) { - dvb_dmxdev_feed_start(&dmxdev->filter[i]); - return 0; - } - - filter->dev->demux->release_section_feed(dmxdev->demux, - filter->feed.sec); - - return 0; -} - -static int dvb_dmxdev_filter_stop(struct dmxdev_filter *dmxdevfilter) -{ - if (dmxdevfilter->state < DMXDEV_STATE_GO) - return 0; - - switch (dmxdevfilter->type) { - case DMXDEV_TYPE_SEC: - if (!dmxdevfilter->feed.sec) - break; - dvb_dmxdev_feed_stop(dmxdevfilter); - if (dmxdevfilter->filter.sec) - dmxdevfilter->feed.sec-> - release_filter(dmxdevfilter->feed.sec, - dmxdevfilter->filter.sec); - dvb_dmxdev_feed_restart(dmxdevfilter); - dmxdevfilter->feed.sec = NULL; - break; - case DMXDEV_TYPE_PES: - if (!dmxdevfilter->feed.ts) - break; - dvb_dmxdev_feed_stop(dmxdevfilter); - dmxdevfilter->dev->demux-> - release_ts_feed(dmxdevfilter->dev->demux, - dmxdevfilter->feed.ts); - dmxdevfilter->feed.ts = NULL; - break; - default: - if (dmxdevfilter->state == DMXDEV_STATE_ALLOCATED) - return 0; - return -EINVAL; - } - - dvb_ringbuffer_flush(&dmxdevfilter->buffer); - return 0; -} - -static inline int dvb_dmxdev_filter_reset(struct dmxdev_filter *dmxdevfilter) -{ - if (dmxdevfilter->state < DMXDEV_STATE_SET) - return 0; - - dmxdevfilter->type = DMXDEV_TYPE_NONE; - dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); - return 0; -} - -static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) -{ - struct dmxdev *dmxdev = filter->dev; - void *mem; - int ret, i; - - if (filter->state < DMXDEV_STATE_SET) - return -EINVAL; - - if (filter->state >= DMXDEV_STATE_GO) - dvb_dmxdev_filter_stop(filter); - - if (!filter->buffer.data) { - mem = vmalloc(filter->buffer.size); - if (!mem) - return -ENOMEM; - spin_lock_irq(&filter->dev->lock); - filter->buffer.data = mem; - spin_unlock_irq(&filter->dev->lock); - } - - dvb_ringbuffer_flush(&filter->buffer); - - switch (filter->type) { - case DMXDEV_TYPE_SEC: - { - struct dmx_sct_filter_params *para = &filter->params.sec; - struct dmx_section_filter **secfilter = &filter->filter.sec; - struct dmx_section_feed **secfeed = &filter->feed.sec; - - *secfilter = NULL; - *secfeed = NULL; - - - /* find active filter/feed with same PID */ - for (i = 0; i < dmxdev->filternum; i++) { - if (dmxdev->filter[i].state >= DMXDEV_STATE_GO && - dmxdev->filter[i].type == DMXDEV_TYPE_SEC && - dmxdev->filter[i].params.sec.pid == para->pid) { - *secfeed = dmxdev->filter[i].feed.sec; - break; - } - } - - /* if no feed found, try to allocate new one */ - if (!*secfeed) { - ret = dmxdev->demux->allocate_section_feed(dmxdev->demux, - secfeed, - dvb_dmxdev_section_callback); - if (ret < 0) { - printk("DVB (%s): could not alloc feed\n", - __func__); - return ret; - } - - ret = (*secfeed)->set(*secfeed, para->pid, 32768, - (para->flags & DMX_CHECK_CRC) ? 1 : 0); - if (ret < 0) { - printk("DVB (%s): could not set feed\n", - __func__); - dvb_dmxdev_feed_restart(filter); - return ret; - } - } else { - dvb_dmxdev_feed_stop(filter); - } - - ret = (*secfeed)->allocate_filter(*secfeed, secfilter); - if (ret < 0) { - dvb_dmxdev_feed_restart(filter); - filter->feed.sec->start_filtering(*secfeed); - dprintk("could not get filter\n"); - return ret; - } - - (*secfilter)->priv = filter; - - memcpy(&((*secfilter)->filter_value[3]), - &(para->filter.filter[1]), DMX_FILTER_SIZE - 1); - memcpy(&(*secfilter)->filter_mask[3], - ¶->filter.mask[1], DMX_FILTER_SIZE - 1); - memcpy(&(*secfilter)->filter_mode[3], - ¶->filter.mode[1], DMX_FILTER_SIZE - 1); - - (*secfilter)->filter_value[0] = para->filter.filter[0]; - (*secfilter)->filter_mask[0] = para->filter.mask[0]; - (*secfilter)->filter_mode[0] = para->filter.mode[0]; - (*secfilter)->filter_mask[1] = 0; - (*secfilter)->filter_mask[2] = 0; - - filter->todo = 0; - - ret = filter->feed.sec->start_filtering(filter->feed.sec); - if (ret < 0) - return ret; - - dvb_dmxdev_filter_timer(filter); - break; - } - case DMXDEV_TYPE_PES: - { - struct timespec timeout = { 0 }; - struct dmx_pes_filter_params *para = &filter->params.pes; - dmx_output_t otype; - int ts_type; - enum dmx_ts_pes ts_pes; - struct dmx_ts_feed **tsfeed = &filter->feed.ts; - - filter->feed.ts = NULL; - otype = para->output; - - ts_pes = (enum dmx_ts_pes)para->pes_type; - - if (ts_pes < DMX_PES_OTHER) - ts_type = TS_DECODER; - else - ts_type = 0; - - if (otype == DMX_OUT_TS_TAP) - ts_type |= TS_PACKET; - else if (otype == DMX_OUT_TSDEMUX_TAP) - ts_type |= TS_PACKET | TS_DEMUX; - else if (otype == DMX_OUT_TAP) - ts_type |= TS_PACKET | TS_DEMUX | TS_PAYLOAD_ONLY; - - ret = dmxdev->demux->allocate_ts_feed(dmxdev->demux, - tsfeed, - dvb_dmxdev_ts_callback); - if (ret < 0) - return ret; - - (*tsfeed)->priv = filter; - - ret = (*tsfeed)->set(*tsfeed, para->pid, ts_type, ts_pes, - 32768, timeout); - if (ret < 0) { - dmxdev->demux->release_ts_feed(dmxdev->demux, - *tsfeed); - return ret; - } - - ret = filter->feed.ts->start_filtering(filter->feed.ts); - if (ret < 0) { - dmxdev->demux->release_ts_feed(dmxdev->demux, - *tsfeed); - return ret; - } - - break; - } - default: - return -EINVAL; - } - - dvb_dmxdev_filter_state_set(filter, DMXDEV_STATE_GO); - return 0; -} - -static int dvb_demux_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - int i; - struct dmxdev_filter *dmxdevfilter; - - if (!dmxdev->filter) - return -EINVAL; - - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - for (i = 0; i < dmxdev->filternum; i++) - if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) - break; - - if (i == dmxdev->filternum) { - mutex_unlock(&dmxdev->mutex); - return -EMFILE; - } - - dmxdevfilter = &dmxdev->filter[i]; - mutex_init(&dmxdevfilter->mutex); - file->private_data = dmxdevfilter; - - dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); - dmxdevfilter->type = DMXDEV_TYPE_NONE; - dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_ALLOCATED); - dmxdevfilter->feed.ts = NULL; - init_timer(&dmxdevfilter->timer); - - dvbdev->users++; - - mutex_unlock(&dmxdev->mutex); - return 0; -} - -static int dvb_dmxdev_filter_free(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter) -{ - mutex_lock(&dmxdev->mutex); - mutex_lock(&dmxdevfilter->mutex); - - dvb_dmxdev_filter_stop(dmxdevfilter); - dvb_dmxdev_filter_reset(dmxdevfilter); - - if (dmxdevfilter->buffer.data) { - void *mem = dmxdevfilter->buffer.data; - - spin_lock_irq(&dmxdev->lock); - dmxdevfilter->buffer.data = NULL; - spin_unlock_irq(&dmxdev->lock); - vfree(mem); - } - - dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_FREE); - wake_up(&dmxdevfilter->buffer.queue); - mutex_unlock(&dmxdevfilter->mutex); - mutex_unlock(&dmxdev->mutex); - return 0; -} - -static inline void invert_mode(dmx_filter_t *filter) -{ - int i; - - for (i = 0; i < DMX_FILTER_SIZE; i++) - filter->mode[i] ^= 0xff; -} - -static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter, - struct dmx_sct_filter_params *params) -{ - dprintk("function : %s\n", __func__); - - dvb_dmxdev_filter_stop(dmxdevfilter); - - dmxdevfilter->type = DMXDEV_TYPE_SEC; - memcpy(&dmxdevfilter->params.sec, - params, sizeof(struct dmx_sct_filter_params)); - invert_mode(&dmxdevfilter->params.sec.filter); - dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - - if (params->flags & DMX_IMMEDIATE_START) - return dvb_dmxdev_filter_start(dmxdevfilter); - - return 0; -} - -static int dvb_dmxdev_pes_filter_set(struct dmxdev *dmxdev, - struct dmxdev_filter *dmxdevfilter, - struct dmx_pes_filter_params *params) -{ - dvb_dmxdev_filter_stop(dmxdevfilter); - - if (params->pes_type > DMX_PES_OTHER || params->pes_type < 0) - return -EINVAL; - - dmxdevfilter->type = DMXDEV_TYPE_PES; - memcpy(&dmxdevfilter->params, params, - sizeof(struct dmx_pes_filter_params)); - - dvb_dmxdev_filter_state_set(dmxdevfilter, DMXDEV_STATE_SET); - - if (params->flags & DMX_IMMEDIATE_START) - return dvb_dmxdev_filter_start(dmxdevfilter); - - return 0; -} - -static ssize_t dvb_dmxdev_read_sec(struct dmxdev_filter *dfil, - struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - int result, hcount; - int done = 0; - - if (dfil->todo <= 0) { - hcount = 3 + dfil->todo; - if (hcount > count) - hcount = count; - result = dvb_dmxdev_buffer_read(&dfil->buffer, - file->f_flags & O_NONBLOCK, - buf, hcount, ppos); - if (result < 0) { - dfil->todo = 0; - return result; - } - if (copy_from_user(dfil->secheader - dfil->todo, buf, result)) - return -EFAULT; - buf += result; - done = result; - count -= result; - dfil->todo -= result; - if (dfil->todo > -3) - return done; - dfil->todo = ((dfil->secheader[1] << 8) | dfil->secheader[2]) & 0xfff; - if (!count) - return done; - } - if (count > dfil->todo) - count = dfil->todo; - result = dvb_dmxdev_buffer_read(&dfil->buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); - if (result < 0) - return result; - dfil->todo -= result; - return (result + done); -} - -static ssize_t -dvb_demux_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - struct dmxdev_filter *dmxdevfilter = file->private_data; - int ret; - - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) - return -ERESTARTSYS; - - if (dmxdevfilter->type == DMXDEV_TYPE_SEC) - ret = dvb_dmxdev_read_sec(dmxdevfilter, file, buf, count, ppos); - else - ret = dvb_dmxdev_buffer_read(&dmxdevfilter->buffer, - file->f_flags & O_NONBLOCK, - buf, count, ppos); - - mutex_unlock(&dmxdevfilter->mutex); - return ret; -} - -static int dvb_demux_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dmxdev_filter *dmxdevfilter = file->private_data; - struct dmxdev *dmxdev = dmxdevfilter->dev; - unsigned long arg = (unsigned long)parg; - int ret = 0; - - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - switch (cmd) { - case DMX_START: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } - if (dmxdevfilter->state < DMXDEV_STATE_SET) - ret = -EINVAL; - else - ret = dvb_dmxdev_filter_start(dmxdevfilter); - mutex_unlock(&dmxdevfilter->mutex); - break; - - case DMX_STOP: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } - ret = dvb_dmxdev_filter_stop(dmxdevfilter); - mutex_unlock(&dmxdevfilter->mutex); - break; - - case DMX_SET_FILTER: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } - ret = dvb_dmxdev_filter_set(dmxdev, dmxdevfilter, parg); - mutex_unlock(&dmxdevfilter->mutex); - break; - - case DMX_SET_PES_FILTER: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } - ret = dvb_dmxdev_pes_filter_set(dmxdev, dmxdevfilter, parg); - mutex_unlock(&dmxdevfilter->mutex); - break; - - case DMX_SET_BUFFER_SIZE: - if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { - mutex_unlock(&dmxdev->mutex); - return -ERESTARTSYS; - } - ret = dvb_dmxdev_set_buffer_size(dmxdevfilter, arg); - mutex_unlock(&dmxdevfilter->mutex); - break; - - case DMX_GET_PES_PIDS: - if (!dmxdev->demux->get_pes_pids) { - ret = -EINVAL; - break; - } - dmxdev->demux->get_pes_pids(dmxdev->demux, parg); - break; - - case DMX_GET_CAPS: - if (!dmxdev->demux->get_caps) { - ret = -EINVAL; - break; - } - ret = dmxdev->demux->get_caps(dmxdev->demux, parg); - break; - - case DMX_SET_SOURCE: - if (!dmxdev->demux->set_source) { - ret = -EINVAL; - break; - } - ret = dmxdev->demux->set_source(dmxdev->demux, parg); - break; - - case DMX_GET_STC: - if (!dmxdev->demux->get_stc) { - ret = -EINVAL; - break; - } - ret = dmxdev->demux->get_stc(dmxdev->demux, - ((struct dmx_stc *)parg)->num, - &((struct dmx_stc *)parg)->stc, - &((struct dmx_stc *)parg)->base); - break; - - default: - ret = -EINVAL; - break; - } - mutex_unlock(&dmxdev->mutex); - return ret; -} - -static int dvb_demux_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return dvb_usercopy(inode, file, cmd, arg, dvb_demux_do_ioctl); -} - -static unsigned int dvb_demux_poll(struct file *file, poll_table *wait) -{ - struct dmxdev_filter *dmxdevfilter = file->private_data; - unsigned int mask = 0; - - if (!dmxdevfilter) - return -EINVAL; - - poll_wait(file, &dmxdevfilter->buffer.queue, wait); - - if (dmxdevfilter->state != DMXDEV_STATE_GO && - dmxdevfilter->state != DMXDEV_STATE_DONE && - dmxdevfilter->state != DMXDEV_STATE_TIMEDOUT) - return 0; - - if (dmxdevfilter->buffer.error) - mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); - - if (!dvb_ringbuffer_empty(&dmxdevfilter->buffer)) - mask |= (POLLIN | POLLRDNORM | POLLPRI); - - return mask; -} - -static int dvb_demux_release(struct inode *inode, struct file *file) -{ - struct dmxdev_filter *dmxdevfilter = file->private_data; - struct dmxdev *dmxdev = dmxdevfilter->dev; - - int ret; - - ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); - - mutex_lock(&dmxdev->mutex); - dmxdev->dvbdev->users--; - if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) { - fops_put(file->f_op); - file->f_op = NULL; - mutex_unlock(&dmxdev->mutex); - wake_up(&dmxdev->dvbdev->wait_queue); - } else - mutex_unlock(&dmxdev->mutex); - - return ret; -} - -static struct file_operations dvb_demux_fops = { - .owner = THIS_MODULE, - .read = dvb_demux_read, - .ioctl = dvb_demux_ioctl, - .open = dvb_demux_open, - .release = dvb_demux_release, - .poll = dvb_demux_poll, -}; - -static struct dvb_device dvbdev_demux = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_demux_fops -}; - -static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - unsigned long arg = (unsigned long)parg; - int ret; - - if (mutex_lock_interruptible(&dmxdev->mutex)) - return -ERESTARTSYS; - - switch (cmd) { - case DMX_SET_BUFFER_SIZE: - ret = dvb_dvr_set_buffer_size(dmxdev, arg); - break; - - default: - ret = -EINVAL; - break; - } - mutex_unlock(&dmxdev->mutex); - return ret; -} - -static int dvb_dvr_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return dvb_usercopy(inode, file, cmd, arg, dvb_dvr_do_ioctl); -} - -static unsigned int dvb_dvr_poll(struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = file->private_data; - struct dmxdev *dmxdev = dvbdev->priv; - unsigned int mask = 0; - - dprintk("function : %s\n", __func__); - - poll_wait(file, &dmxdev->dvr_buffer.queue, wait); - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - if (dmxdev->dvr_buffer.error) - mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); - - if (!dvb_ringbuffer_empty(&dmxdev->dvr_buffer)) - mask |= (POLLIN | POLLRDNORM | POLLPRI); - } else - mask |= (POLLOUT | POLLWRNORM | POLLPRI); - - return mask; -} - -static struct file_operations dvb_dvr_fops = { - .owner = THIS_MODULE, - .read = dvb_dvr_read, - .write = dvb_dvr_write, - .ioctl = dvb_dvr_ioctl, - .open = dvb_dvr_open, - .release = dvb_dvr_release, - .poll = dvb_dvr_poll, -}; - -static struct dvb_device dvbdev_dvr = { - .priv = NULL, - .readers = 1, - .users = 1, - .fops = &dvb_dvr_fops -}; - -int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) -{ - int i; - - if (dmxdev->demux->open(dmxdev->demux) < 0) - return -EUSERS; - - dmxdev->filter = vmalloc(dmxdev->filternum * sizeof(struct dmxdev_filter)); - if (!dmxdev->filter) - return -ENOMEM; - - mutex_init(&dmxdev->mutex); - spin_lock_init(&dmxdev->lock); - for (i = 0; i < dmxdev->filternum; i++) { - dmxdev->filter[i].dev = dmxdev; - dmxdev->filter[i].buffer.data = NULL; - dvb_dmxdev_filter_state_set(&dmxdev->filter[i], - DMXDEV_STATE_FREE); - } - - dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, - DVB_DEVICE_DEMUX); - dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, - dmxdev, DVB_DEVICE_DVR); - - dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); - - return 0; -} - -EXPORT_SYMBOL(dvb_dmxdev_init); - -void dvb_dmxdev_release(struct dmxdev *dmxdev) -{ - dmxdev->exit=1; - if (dmxdev->dvbdev->users > 1) { - wait_event(dmxdev->dvbdev->wait_queue, - dmxdev->dvbdev->users==1); - } - if (dmxdev->dvr_dvbdev->users > 1) { - wait_event(dmxdev->dvr_dvbdev->wait_queue, - dmxdev->dvr_dvbdev->users==1); - } - - dvb_unregister_device(dmxdev->dvbdev); - dvb_unregister_device(dmxdev->dvr_dvbdev); - - vfree(dmxdev->filter); - dmxdev->filter = NULL; - dmxdev->demux->close(dmxdev->demux); -} - -EXPORT_SYMBOL(dvb_dmxdev_release); diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h deleted file mode 100644 index 29746e70d32..00000000000 --- a/drivers/media/dvb/dvb-core/dmxdev.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * dmxdev.h - * - * Copyright (C) 2000 Ralph Metzler & Marcus Metzler - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _DMXDEV_H_ -#define _DMXDEV_H_ - -#include <linux/types.h> -#include <linux/spinlock.h> -#include <linux/kernel.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/fs.h> -#include <linux/string.h> -#include <linux/mutex.h> - -#include <linux/dvb/dmx.h> - -#include "dvbdev.h" -#include "demux.h" -#include "dvb_ringbuffer.h" - -enum dmxdev_type { - DMXDEV_TYPE_NONE, - DMXDEV_TYPE_SEC, - DMXDEV_TYPE_PES, -}; - -enum dmxdev_state { - DMXDEV_STATE_FREE, - DMXDEV_STATE_ALLOCATED, - DMXDEV_STATE_SET, - DMXDEV_STATE_GO, - DMXDEV_STATE_DONE, - DMXDEV_STATE_TIMEDOUT -}; - -struct dmxdev_filter { - union { - struct dmx_section_filter *sec; - } filter; - - union { - struct dmx_ts_feed *ts; - struct dmx_section_feed *sec; - } feed; - - union { - struct dmx_sct_filter_params sec; - struct dmx_pes_filter_params pes; - } params; - - enum dmxdev_type type; - enum dmxdev_state state; - struct dmxdev *dev; - struct dvb_ringbuffer buffer; - - struct mutex mutex; - - /* only for sections */ - struct timer_list timer; - int todo; - u8 secheader[3]; -}; - - -struct dmxdev { - struct dvb_device *dvbdev; - struct dvb_device *dvr_dvbdev; - - struct dmxdev_filter *filter; - struct dmx_demux *demux; - - int filternum; - int capabilities; - - unsigned int exit:1; -#define DMXDEV_CAP_DUPLEX 1 - struct dmx_frontend *dvr_orig_fe; - - struct dvb_ringbuffer dvr_buffer; -#define DVR_BUFFER_SIZE (10*188*1024) - - struct mutex mutex; - spinlock_t lock; -}; - - -int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *); -void dvb_dmxdev_release(struct dmxdev *dmxdev); - -#endif /* _DMXDEV_H_ */ diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c deleted file mode 100644 index 98ee16773ff..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ /dev/null @@ -1,1724 +0,0 @@ -/* - * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces - * - * Copyright (C) 2004 Andrew de Quincey - * - * Parts of this file were based on sources as follows: - * - * Copyright (C) 2003 Ralph Metzler <rjkm@metzlerbros.de> - * - * based on code: - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/vmalloc.h> -#include <linux/delay.h> -#include <linux/spinlock.h> -#include <linux/sched.h> -#include <linux/kthread.h> - -#include "dvb_ca_en50221.h" -#include "dvb_ringbuffer.h" - -static int dvb_ca_en50221_debug; - -module_param_named(cam_debug, dvb_ca_en50221_debug, int, 0644); -MODULE_PARM_DESC(cam_debug, "enable verbose debug messages"); - -#define dprintk if (dvb_ca_en50221_debug) printk - -#define INIT_TIMEOUT_SECS 10 - -#define HOST_LINK_BUF_SIZE 0x200 - -#define RX_BUFFER_SIZE 65535 - -#define MAX_RX_PACKETS_PER_ITERATION 10 - -#define CTRLIF_DATA 0 -#define CTRLIF_COMMAND 1 -#define CTRLIF_STATUS 1 -#define CTRLIF_SIZE_LOW 2 -#define CTRLIF_SIZE_HIGH 3 - -#define CMDREG_HC 1 /* Host control */ -#define CMDREG_SW 2 /* Size write */ -#define CMDREG_SR 4 /* Size read */ -#define CMDREG_RS 8 /* Reset interface */ -#define CMDREG_FRIE 0x40 /* Enable FR interrupt */ -#define CMDREG_DAIE 0x80 /* Enable DA interrupt */ -#define IRQEN (CMDREG_DAIE) - -#define STATUSREG_RE 1 /* read error */ -#define STATUSREG_WE 2 /* write error */ -#define STATUSREG_FR 0x40 /* module free */ -#define STATUSREG_DA 0x80 /* data available */ -#define STATUSREG_TXERR (STATUSREG_RE|STATUSREG_WE) /* general transfer error */ - - -#define DVB_CA_SLOTSTATE_NONE 0 -#define DVB_CA_SLOTSTATE_UNINITIALISED 1 -#define DVB_CA_SLOTSTATE_RUNNING 2 -#define DVB_CA_SLOTSTATE_INVALID 3 -#define DVB_CA_SLOTSTATE_WAITREADY 4 -#define DVB_CA_SLOTSTATE_VALIDATE 5 -#define DVB_CA_SLOTSTATE_WAITFR 6 -#define DVB_CA_SLOTSTATE_LINKINIT 7 - - -/* Information on a CA slot */ -struct dvb_ca_slot { - - /* current state of the CAM */ - int slot_state; - - /* Number of CAMCHANGES that have occurred since last processing */ - atomic_t camchange_count; - - /* Type of last CAMCHANGE */ - int camchange_type; - - /* base address of CAM config */ - u32 config_base; - - /* value to write into Config Control register */ - u8 config_option; - - /* if 1, the CAM supports DA IRQs */ - u8 da_irq_supported:1; - - /* size of the buffer to use when talking to the CAM */ - int link_buf_size; - - /* buffer for incoming packets */ - struct dvb_ringbuffer rx_buffer; - - /* timer used during various states of the slot */ - unsigned long timeout; -}; - -/* Private CA-interface information */ -struct dvb_ca_private { - - /* pointer back to the public data structure */ - struct dvb_ca_en50221 *pub; - - /* the DVB device */ - struct dvb_device *dvbdev; - - /* Flags describing the interface (DVB_CA_FLAG_*) */ - u32 flags; - - /* number of slots supported by this CA interface */ - unsigned int slot_count; - - /* information on each slot */ - struct dvb_ca_slot *slot_info; - - /* wait queues for read() and write() operations */ - wait_queue_head_t wait_queue; - - /* PID of the monitoring thread */ - struct task_struct *thread; - - /* Flag indicating if the CA device is open */ - unsigned int open:1; - - /* Flag indicating the thread should wake up now */ - unsigned int wakeup:1; - - /* Delay the main thread should use */ - unsigned long delay; - - /* Slot to start looking for data to read from in the next user-space read operation */ - int next_read_slot; -}; - -static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca); -static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount); -static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount); - - -/** - * Safely find needle in haystack. - * - * @param haystack Buffer to look in. - * @param hlen Number of bytes in haystack. - * @param needle Buffer to find. - * @param nlen Number of bytes in needle. - * @return Pointer into haystack needle was found at, or NULL if not found. - */ -static char *findstr(char * haystack, int hlen, char * needle, int nlen) -{ - int i; - - if (hlen < nlen) - return NULL; - - for (i = 0; i <= hlen - nlen; i++) { - if (!strncmp(haystack + i, needle, nlen)) - return haystack + i; - } - - return NULL; -} - - - -/* ******************************************************************************** */ -/* EN50221 physical interface functions */ - - -/** - * Check CAM status. - */ -static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) -{ - int slot_status; - int cam_present_now; - int cam_changed; - - /* IRQ mode */ - if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) { - return (atomic_read(&ca->slot_info[slot].camchange_count) != 0); - } - - /* poll mode */ - slot_status = ca->pub->poll_slot_status(ca->pub, slot, ca->open); - - cam_present_now = (slot_status & DVB_CA_EN50221_POLL_CAM_PRESENT) ? 1 : 0; - cam_changed = (slot_status & DVB_CA_EN50221_POLL_CAM_CHANGED) ? 1 : 0; - if (!cam_changed) { - int cam_present_old = (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE); - cam_changed = (cam_present_now != cam_present_old); - } - - if (cam_changed) { - if (!cam_present_now) { - ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; - } else { - ca->slot_info[slot].camchange_type = DVB_CA_EN50221_CAMCHANGE_INSERTED; - } - atomic_set(&ca->slot_info[slot].camchange_count, 1); - } else { - if ((ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) && - (slot_status & DVB_CA_EN50221_POLL_CAM_READY)) { - // move to validate state if reset is completed - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE; - } - } - - return cam_changed; -} - - -/** - * Wait for flags to become set on the STATUS register on a CAM interface, - * checking for errors and timeout. - * - * @param ca CA instance. - * @param slot Slot on interface. - * @param waitfor Flags to wait for. - * @param timeout_ms Timeout in milliseconds. - * - * @return 0 on success, nonzero on error. - */ -static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, - u8 waitfor, int timeout_hz) -{ - unsigned long timeout; - unsigned long start; - - dprintk("%s\n", __func__); - - /* loop until timeout elapsed */ - start = jiffies; - timeout = jiffies + timeout_hz; - while (1) { - /* read the status and check for error */ - int res = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); - if (res < 0) - return -EIO; - - /* if we got the flags, it was successful! */ - if (res & waitfor) { - dprintk("%s succeeded timeout:%lu\n", __func__, jiffies - start); - return 0; - } - - /* check for timeout */ - if (time_after(jiffies, timeout)) { - break; - } - - /* wait for a bit */ - msleep(1); - } - - dprintk("%s failed timeout:%lu\n", __func__, jiffies - start); - - /* if we get here, we've timed out */ - return -ETIMEDOUT; -} - - -/** - * Initialise the link layer connection to a CAM. - * - * @param ca CA instance. - * @param slot Slot id. - * - * @return 0 on success, nonzero on failure. - */ -static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) -{ - int ret; - int buf_size; - u8 buf[2]; - - dprintk("%s\n", __func__); - - /* we'll be determining these during this function */ - ca->slot_info[slot].da_irq_supported = 0; - - /* set the host link buffer size temporarily. it will be overwritten with the - * real negotiated size later. */ - ca->slot_info[slot].link_buf_size = 2; - - /* read the buffer size from the CAM */ - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0) - return ret; - if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0) - return ret; - if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2) - return -EIO; - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0) - return ret; - - /* store it, and choose the minimum of our buffer and the CAM's buffer size */ - buf_size = (buf[0] << 8) | buf[1]; - if (buf_size > HOST_LINK_BUF_SIZE) - buf_size = HOST_LINK_BUF_SIZE; - ca->slot_info[slot].link_buf_size = buf_size; - buf[0] = buf_size >> 8; - buf[1] = buf_size & 0xff; - dprintk("Chosen link buffer size of %i\n", buf_size); - - /* write the buffer size to the CAM */ - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SW)) != 0) - return ret; - if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10)) != 0) - return ret; - if ((ret = dvb_ca_en50221_write_data(ca, slot, buf, 2)) != 2) - return -EIO; - if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN)) != 0) - return ret; - - /* success */ - return 0; -} - -/** - * Read a tuple from attribute memory. - * - * @param ca CA instance. - * @param slot Slot id. - * @param address Address to read from. Updated. - * @param tupleType Tuple id byte. Updated. - * @param tupleLength Tuple length. Updated. - * @param tuple Dest buffer for tuple (must be 256 bytes). Updated. - * - * @return 0 on success, nonzero on error. - */ -static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, - int *address, int *tupleType, int *tupleLength, u8 * tuple) -{ - int i; - int _tupleType; - int _tupleLength; - int _address = *address; - - /* grab the next tuple length and type */ - if ((_tupleType = ca->pub->read_attribute_mem(ca->pub, slot, _address)) < 0) - return _tupleType; - if (_tupleType == 0xff) { - dprintk("END OF CHAIN TUPLE type:0x%x\n", _tupleType); - *address += 2; - *tupleType = _tupleType; - *tupleLength = 0; - return 0; - } - if ((_tupleLength = ca->pub->read_attribute_mem(ca->pub, slot, _address + 2)) < 0) - return _tupleLength; - _address += 4; - - dprintk("TUPLE type:0x%x length:%i\n", _tupleType, _tupleLength); - - /* read in the whole tuple */ - for (i = 0; i < _tupleLength; i++) { - tuple[i] = ca->pub->read_attribute_mem(ca->pub, slot, _address + (i * 2)); - dprintk(" 0x%02x: 0x%02x %c\n", - i, tuple[i] & 0xff, - ((tuple[i] > 31) && (tuple[i] < 127)) ? tuple[i] : '.'); - } - _address += (_tupleLength * 2); - - // success - *tupleType = _tupleType; - *tupleLength = _tupleLength; - *address = _address; - return 0; -} - - -/** - * Parse attribute memory of a CAM module, extracting Config register, and checking - * it is a DVB CAM module. - * - * @param ca CA instance. - * @param slot Slot id. - * - * @return 0 on success, <0 on failure. - */ -static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) -{ - int address = 0; - int tupleLength; - int tupleType; - u8 tuple[257]; - char *dvb_str; - int rasz; - int status; - int got_cftableentry = 0; - int end_chain = 0; - int i; - u16 manfid = 0; - u16 devid = 0; - - - // CISTPL_DEVICE_0A - if ((status = - dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) - return status; - if (tupleType != 0x1D) - return -EINVAL; - - - - // CISTPL_DEVICE_0C - if ((status = - dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) - return status; - if (tupleType != 0x1C) - return -EINVAL; - - - - // CISTPL_VERS_1 - if ((status = - dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, &tupleLength, tuple)) < 0) - return status; - if (tupleType != 0x15) - return -EINVAL; - - - - // CISTPL_MANFID - if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, - &tupleLength, tuple)) < 0) - return status; - if (tupleType != 0x20) - return -EINVAL; - if (tupleLength != 4) - return -EINVAL; - manfid = (tuple[1] << 8) | tuple[0]; - devid = (tuple[3] << 8) | tuple[2]; - - - - // CISTPL_CONFIG - if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, - &tupleLength, tuple)) < 0) - return status; - if (tupleType != 0x1A) - return -EINVAL; - if (tupleLength < 3) - return -EINVAL; - - /* extract the configbase */ - rasz = tuple[0] & 3; - if (tupleLength < (3 + rasz + 14)) - return -EINVAL; - ca->slot_info[slot].config_base = 0; - for (i = 0; i < rasz + 1; i++) { - ca->slot_info[slot].config_base |= (tuple[2 + i] << (8 * i)); - } - - /* check it contains the correct DVB string */ - dvb_str = findstr((char *)tuple, tupleLength, "DVB_CI_V", 8); - if (dvb_str == NULL) - return -EINVAL; - if (tupleLength < ((dvb_str - (char *) tuple) + 12)) - return -EINVAL; - - /* is it a version we support? */ - if (strncmp(dvb_str + 8, "1.00", 4)) { - printk("dvb_ca adapter %d: Unsupported DVB CAM module version %c%c%c%c\n", - ca->dvbdev->adapter->num, dvb_str[8], dvb_str[9], dvb_str[10], dvb_str[11]); - return -EINVAL; - } - - /* process the CFTABLE_ENTRY tuples, and any after those */ - while ((!end_chain) && (address < 0x1000)) { - if ((status = dvb_ca_en50221_read_tuple(ca, slot, &address, &tupleType, - &tupleLength, tuple)) < 0) - return status; - switch (tupleType) { - case 0x1B: // CISTPL_CFTABLE_ENTRY - if (tupleLength < (2 + 11 + 17)) - break; - - /* if we've already parsed one, just use it */ - if (got_cftableentry) - break; - - /* get the config option */ - ca->slot_info[slot].config_option = tuple[0] & 0x3f; - - /* OK, check it contains the correct strings */ - if ((findstr((char *)tuple, tupleLength, "DVB_HOST", 8) == NULL) || - (findstr((char *)tuple, tupleLength, "DVB_CI_MODULE", 13) == NULL)) - break; - - got_cftableentry = 1; - break; - - case 0x14: // CISTPL_NO_LINK - break; - - case 0xFF: // CISTPL_END - end_chain = 1; - break; - - default: /* Unknown tuple type - just skip this tuple and move to the next one */ - dprintk("dvb_ca: Skipping unknown tuple type:0x%x length:0x%x\n", tupleType, - tupleLength); - break; - } - } - - if ((address > 0x1000) || (!got_cftableentry)) - return -EINVAL; - - dprintk("Valid DVB CAM detected MANID:%x DEVID:%x CONFIGBASE:0x%x CONFIGOPTION:0x%x\n", - manfid, devid, ca->slot_info[slot].config_base, ca->slot_info[slot].config_option); - - // success! - return 0; -} - - -/** - * Set CAM's configoption correctly. - * - * @param ca CA instance. - * @param slot Slot containing the CAM. - */ -static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) -{ - int configoption; - - dprintk("%s\n", __func__); - - /* set the config option */ - ca->pub->write_attribute_mem(ca->pub, slot, - ca->slot_info[slot].config_base, - ca->slot_info[slot].config_option); - - /* check it */ - configoption = ca->pub->read_attribute_mem(ca->pub, slot, ca->slot_info[slot].config_base); - dprintk("Set configoption 0x%x, read configoption 0x%x\n", - ca->slot_info[slot].config_option, configoption & 0x3f); - - /* fine! */ - return 0; - -} - - -/** - * This function talks to an EN50221 CAM control interface. It reads a buffer of - * data from the CAM. The data can either be stored in a supplied buffer, or - * automatically be added to the slot's rx_buffer. - * - * @param ca CA instance. - * @param slot Slot to read from. - * @param ebuf If non-NULL, the data will be written to this buffer. If NULL, - * the data will be added into the buffering system as a normal fragment. - * @param ecount Size of ebuf. Ignored if ebuf is NULL. - * - * @return Number of bytes read, or < 0 on error - */ -static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot, u8 * ebuf, int ecount) -{ - int bytes_read; - int status; - u8 buf[HOST_LINK_BUF_SIZE]; - int i; - - dprintk("%s\n", __func__); - - /* check if we have space for a link buf in the rx_buffer */ - if (ebuf == NULL) { - int buf_free; - - if (ca->slot_info[slot].rx_buffer.data == NULL) { - status = -EIO; - goto exit; - } - buf_free = dvb_ringbuffer_free(&ca->slot_info[slot].rx_buffer); - - if (buf_free < (ca->slot_info[slot].link_buf_size + DVB_RINGBUFFER_PKTHDRSIZE)) { - status = -EAGAIN; - goto exit; - } - } - - /* check if there is data available */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) - goto exit; - if (!(status & STATUSREG_DA)) { - /* no data */ - status = 0; - goto exit; - } - - /* read the amount of data */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH)) < 0) - goto exit; - bytes_read = status << 8; - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW)) < 0) - goto exit; - bytes_read |= status; - - /* check it will fit */ - if (ebuf == NULL) { - if (bytes_read > ca->slot_info[slot].link_buf_size) { - printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the link buffer size (%i > %i)!\n", - ca->dvbdev->adapter->num, bytes_read, ca->slot_info[slot].link_buf_size); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; - status = -EIO; - goto exit; - } - if (bytes_read < 2) { - printk("dvb_ca adapter %d: CAM sent a buffer that was less than 2 bytes!\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; - status = -EIO; - goto exit; - } - } else { - if (bytes_read > ecount) { - printk("dvb_ca adapter %d: CAM tried to send a buffer larger than the ecount size!\n", - ca->dvbdev->adapter->num); - status = -EIO; - goto exit; - } - } - - /* fill the buffer */ - for (i = 0; i < bytes_read; i++) { - /* read byte and check */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_DATA)) < 0) - goto exit; - - /* OK, store it in the buffer */ - buf[i] = status; - } - - /* check for read error (RE should now be 0) */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) - goto exit; - if (status & STATUSREG_RE) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; - status = -EIO; - goto exit; - } - - /* OK, add it to the receive buffer, or copy into external buffer if supplied */ - if (ebuf == NULL) { - if (ca->slot_info[slot].rx_buffer.data == NULL) { - status = -EIO; - goto exit; - } - dvb_ringbuffer_pkt_write(&ca->slot_info[slot].rx_buffer, buf, bytes_read); - } else { - memcpy(ebuf, buf, bytes_read); - } - - dprintk("Received CA packet for slot %i connection id 0x%x last_frag:%i size:0x%x\n", slot, - buf[0], (buf[1] & 0x80) == 0, bytes_read); - - /* wake up readers when a last_fragment is received */ - if ((buf[1] & 0x80) == 0x00) { - wake_up_interruptible(&ca->wait_queue); - } - status = bytes_read; - -exit: - return status; -} - - -/** - * This function talks to an EN50221 CAM control interface. It writes a buffer of data - * to a CAM. - * - * @param ca CA instance. - * @param slot Slot to write to. - * @param ebuf The data in this buffer is treated as a complete link-level packet to - * be written. - * @param count Size of ebuf. - * - * @return Number of bytes written, or < 0 on error. - */ -static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * buf, int bytes_write) -{ - int status; - int i; - - dprintk("%s\n", __func__); - - - // sanity check - if (bytes_write > ca->slot_info[slot].link_buf_size) - return -EINVAL; - - /* check if interface is actually waiting for us to read from it, or if a read is in progress */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) - goto exitnowrite; - if (status & (STATUSREG_DA | STATUSREG_RE)) { - status = -EAGAIN; - goto exitnowrite; - } - - /* OK, set HC bit */ - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, - IRQEN | CMDREG_HC)) != 0) - goto exit; - - /* check if interface is still free */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) - goto exit; - if (!(status & STATUSREG_FR)) { - /* it wasn't free => try again later */ - status = -EAGAIN; - goto exit; - } - - /* send the amount of data */ - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0) - goto exit; - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_LOW, - bytes_write & 0xff)) != 0) - goto exit; - - /* send the buffer */ - for (i = 0; i < bytes_write; i++) { - if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_DATA, buf[i])) != 0) - goto exit; - } - - /* check for write error (WE should now be 0) */ - if ((status = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS)) < 0) - goto exit; - if (status & STATUSREG_WE) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; - status = -EIO; - goto exit; - } - status = bytes_write; - - dprintk("Wrote CA packet for slot %i, connection id 0x%x last_frag:%i size:0x%x\n", slot, - buf[0], (buf[1] & 0x80) == 0, bytes_write); - -exit: - ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN); - -exitnowrite: - return status; -} -EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq); - - - -/* ******************************************************************************** */ -/* EN50221 higher level functions */ - - -/** - * A CAM has been removed => shut it down. - * - * @param ca CA instance. - * @param slot Slot to shut down. - */ -static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) -{ - dprintk("%s\n", __func__); - - ca->pub->slot_shutdown(ca->pub, slot); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - - /* need to wake up all processes to check if they're now - trying to write to a defunct CAM */ - wake_up_interruptible(&ca->wait_queue); - - dprintk("Slot %i shutdown\n", slot); - - /* success */ - return 0; -} -EXPORT_SYMBOL(dvb_ca_en50221_camready_irq); - - -/** - * A CAMCHANGE IRQ has occurred. - * - * @param ca CA instance. - * @param slot Slot concerned. - * @param change_type One of the DVB_CA_CAMCHANGE_* values. - */ -void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type) -{ - struct dvb_ca_private *ca = pubca->private; - - dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type); - - switch (change_type) { - case DVB_CA_EN50221_CAMCHANGE_REMOVED: - case DVB_CA_EN50221_CAMCHANGE_INSERTED: - break; - - default: - return; - } - - ca->slot_info[slot].camchange_type = change_type; - atomic_inc(&ca->slot_info[slot].camchange_count); - dvb_ca_en50221_thread_wakeup(ca); -} -EXPORT_SYMBOL(dvb_ca_en50221_frda_irq); - - -/** - * A CAMREADY IRQ has occurred. - * - * @param ca CA instance. - * @param slot Slot concerned. - */ -void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) -{ - struct dvb_ca_private *ca = pubca->private; - - dprintk("CAMREADY IRQ slot:%i\n", slot); - - if (ca->slot_info[slot].slot_state == DVB_CA_SLOTSTATE_WAITREADY) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_VALIDATE; - dvb_ca_en50221_thread_wakeup(ca); - } -} - - -/** - * An FR or DA IRQ has occurred. - * - * @param ca CA instance. - * @param slot Slot concerned. - */ -void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) -{ - struct dvb_ca_private *ca = pubca->private; - int flags; - - dprintk("FR/DA IRQ slot:%i\n", slot); - - switch (ca->slot_info[slot].slot_state) { - case DVB_CA_SLOTSTATE_LINKINIT: - flags = ca->pub->read_cam_control(pubca, slot, CTRLIF_STATUS); - if (flags & STATUSREG_DA) { - dprintk("CAM supports DA IRQ\n"); - ca->slot_info[slot].da_irq_supported = 1; - } - break; - - case DVB_CA_SLOTSTATE_RUNNING: - if (ca->open) - dvb_ca_en50221_thread_wakeup(ca); - break; - } -} - - - -/* ******************************************************************************** */ -/* EN50221 thread functions */ - -/** - * Wake up the DVB CA thread - * - * @param ca CA instance. - */ -static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca) -{ - - dprintk("%s\n", __func__); - - ca->wakeup = 1; - mb(); - wake_up_process(ca->thread); -} - -/** - * Update the delay used by the thread. - * - * @param ca CA instance. - */ -static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) -{ - int delay; - int curdelay = 100000000; - int slot; - - /* Beware of too high polling frequency, because one polling - * call might take several hundred milliseconds until timeout! - */ - for (slot = 0; slot < ca->slot_count; slot++) { - switch (ca->slot_info[slot].slot_state) { - default: - case DVB_CA_SLOTSTATE_NONE: - delay = HZ * 60; /* 60s */ - if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) - delay = HZ * 5; /* 5s */ - break; - case DVB_CA_SLOTSTATE_INVALID: - delay = HZ * 60; /* 60s */ - if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) - delay = HZ / 10; /* 100ms */ - break; - - case DVB_CA_SLOTSTATE_UNINITIALISED: - case DVB_CA_SLOTSTATE_WAITREADY: - case DVB_CA_SLOTSTATE_VALIDATE: - case DVB_CA_SLOTSTATE_WAITFR: - case DVB_CA_SLOTSTATE_LINKINIT: - delay = HZ / 10; /* 100ms */ - break; - - case DVB_CA_SLOTSTATE_RUNNING: - delay = HZ * 60; /* 60s */ - if (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) - delay = HZ / 10; /* 100ms */ - if (ca->open) { - if ((!ca->slot_info[slot].da_irq_supported) || - (!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_DA))) - delay = HZ / 10; /* 100ms */ - } - break; - } - - if (delay < curdelay) - curdelay = delay; - } - - ca->delay = curdelay; -} - - - -/** - * Kernel thread which monitors CA slots for CAM changes, and performs data transfers. - */ -static int dvb_ca_en50221_thread(void *data) -{ - struct dvb_ca_private *ca = data; - int slot; - int flags; - int status; - int pktcount; - void *rxbuf; - - dprintk("%s\n", __func__); - - /* choose the correct initial delay */ - dvb_ca_en50221_thread_update_delay(ca); - - /* main loop */ - while (!kthread_should_stop()) { - /* sleep for a bit */ - if (!ca->wakeup) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(ca->delay); - if (kthread_should_stop()) - return 0; - } - ca->wakeup = 0; - - /* go through all the slots processing them */ - for (slot = 0; slot < ca->slot_count; slot++) { - - // check the cam status + deal with CAMCHANGEs - while (dvb_ca_en50221_check_camstatus(ca, slot)) { - /* clear down an old CI slot if necessary */ - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) - dvb_ca_en50221_slot_shutdown(ca, slot); - - /* if a CAM is NOW present, initialise it */ - if (ca->slot_info[slot].camchange_type == DVB_CA_EN50221_CAMCHANGE_INSERTED) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_UNINITIALISED; - } - - /* we've handled one CAMCHANGE */ - dvb_ca_en50221_thread_update_delay(ca); - atomic_dec(&ca->slot_info[slot].camchange_count); - } - - // CAM state machine - switch (ca->slot_info[slot].slot_state) { - case DVB_CA_SLOTSTATE_NONE: - case DVB_CA_SLOTSTATE_INVALID: - // no action needed - break; - - case DVB_CA_SLOTSTATE_UNINITIALISED: - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITREADY; - ca->pub->slot_reset(ca->pub, slot); - ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ); - break; - - case DVB_CA_SLOTSTATE_WAITREADY: - if (time_after(jiffies, ca->slot_info[slot].timeout)) { - printk("dvb_ca adaptor %d: PC card did not respond :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - // no other action needed; will automatically change state when ready - break; - - case DVB_CA_SLOTSTATE_VALIDATE: - if (dvb_ca_en50221_parse_attributes(ca, slot) != 0) { - /* we need this extra check for annoying interfaces like the budget-av */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && - (ca->pub->poll_slot_status)) { - status = ca->pub->poll_slot_status(ca->pub, slot, 0); - if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } - - printk("dvb_ca adapter %d: Invalid PC card inserted :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - if (dvb_ca_en50221_set_configoption(ca, slot) != 0) { - printk("dvb_ca adapter %d: Unable to initialise CAM :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - if (ca->pub->write_cam_control(ca->pub, slot, - CTRLIF_COMMAND, CMDREG_RS) != 0) { - printk("dvb_ca adapter %d: Unable to reset CAM IF\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - dprintk("DVB CAM validated successfully\n"); - - ca->slot_info[slot].timeout = jiffies + (INIT_TIMEOUT_SECS * HZ); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_WAITFR; - ca->wakeup = 1; - break; - - case DVB_CA_SLOTSTATE_WAITFR: - if (time_after(jiffies, ca->slot_info[slot].timeout)) { - printk("dvb_ca adapter %d: DVB CAM did not respond :(\n", - ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - - flags = ca->pub->read_cam_control(ca->pub, slot, CTRLIF_STATUS); - if (flags & STATUSREG_FR) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_LINKINIT; - ca->wakeup = 1; - } - break; - - case DVB_CA_SLOTSTATE_LINKINIT: - if (dvb_ca_en50221_link_init(ca, slot) != 0) { - /* we need this extra check for annoying interfaces like the budget-av */ - if ((!(ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE)) && - (ca->pub->poll_slot_status)) { - status = ca->pub->poll_slot_status(ca->pub, slot, 0); - if (!(status & DVB_CA_EN50221_POLL_CAM_PRESENT)) { - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_NONE; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - } - - printk("dvb_ca adapter %d: DVB CAM link initialisation failed :(\n", ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - - if (ca->slot_info[slot].rx_buffer.data == NULL) { - rxbuf = vmalloc(RX_BUFFER_SIZE); - if (rxbuf == NULL) { - printk("dvb_ca adapter %d: Unable to allocate CAM rx buffer :(\n", ca->dvbdev->adapter->num); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_INVALID; - dvb_ca_en50221_thread_update_delay(ca); - break; - } - dvb_ringbuffer_init(&ca->slot_info[slot].rx_buffer, rxbuf, RX_BUFFER_SIZE); - } - - ca->pub->slot_ts_enable(ca->pub, slot); - ca->slot_info[slot].slot_state = DVB_CA_SLOTSTATE_RUNNING; - dvb_ca_en50221_thread_update_delay(ca); - printk("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n", ca->dvbdev->adapter->num); - break; - - case DVB_CA_SLOTSTATE_RUNNING: - if (!ca->open) - continue; - - // poll slots for data - pktcount = 0; - while ((status = dvb_ca_en50221_read_data(ca, slot, NULL, 0)) > 0) { - if (!ca->open) - break; - - /* if a CAMCHANGE occurred at some point, do not do any more processing of this slot */ - if (dvb_ca_en50221_check_camstatus(ca, slot)) { - // we dont want to sleep on the next iteration so we can handle the cam change - ca->wakeup = 1; - break; - } - - /* check if we've hit our limit this time */ - if (++pktcount >= MAX_RX_PACKETS_PER_ITERATION) { - // dont sleep; there is likely to be more data to read - ca->wakeup = 1; - break; - } - } - break; - } - } - } - - return 0; -} - - - -/* ******************************************************************************** */ -/* EN50221 IO interface functions */ - -/** - * Real ioctl implementation. - * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them. - * - * @param inode Inode concerned. - * @param file File concerned. - * @param cmd IOCTL command. - * @param arg Associated argument. - * - * @return 0 on success, <0 on error. - */ -static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_ca_private *ca = dvbdev->priv; - int err = 0; - int slot; - - dprintk("%s\n", __func__); - - switch (cmd) { - case CA_RESET: - for (slot = 0; slot < ca->slot_count; slot++) { - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_NONE) { - dvb_ca_en50221_slot_shutdown(ca, slot); - if (ca->flags & DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE) - dvb_ca_en50221_camchange_irq(ca->pub, - slot, - DVB_CA_EN50221_CAMCHANGE_INSERTED); - } - } - ca->next_read_slot = 0; - dvb_ca_en50221_thread_wakeup(ca); - break; - - case CA_GET_CAP: { - struct ca_caps *caps = parg; - - caps->slot_num = ca->slot_count; - caps->slot_type = CA_CI_LINK; - caps->descr_num = 0; - caps->descr_type = 0; - break; - } - - case CA_GET_SLOT_INFO: { - struct ca_slot_info *info = parg; - - if ((info->num > ca->slot_count) || (info->num < 0)) - return -EINVAL; - - info->type = CA_CI_LINK; - info->flags = 0; - if ((ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_NONE) - && (ca->slot_info[info->num].slot_state != DVB_CA_SLOTSTATE_INVALID)) { - info->flags = CA_CI_MODULE_PRESENT; - } - if (ca->slot_info[info->num].slot_state == DVB_CA_SLOTSTATE_RUNNING) { - info->flags |= CA_CI_MODULE_READY; - } - break; - } - - default: - err = -EINVAL; - break; - } - - return err; -} - - -/** - * Wrapper for ioctl implementation. - * - * @param inode Inode concerned. - * @param file File concerned. - * @param cmd IOCTL command. - * @param arg Associated argument. - * - * @return 0 on success, <0 on error. - */ -static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return dvb_usercopy(inode, file, cmd, arg, dvb_ca_en50221_io_do_ioctl); -} - - -/** - * Implementation of write() syscall. - * - * @param file File structure. - * @param buf Source buffer. - * @param count Size of source buffer. - * @param ppos Position in file (ignored). - * - * @return Number of bytes read, or <0 on error. - */ -static ssize_t dvb_ca_en50221_io_write(struct file *file, - const char __user * buf, size_t count, loff_t * ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_ca_private *ca = dvbdev->priv; - u8 slot, connection_id; - int status; - u8 fragbuf[HOST_LINK_BUF_SIZE]; - int fragpos = 0; - int fraglen; - unsigned long timeout; - int written; - - dprintk("%s\n", __func__); - - /* Incoming packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */ - if (count < 2) - return -EINVAL; - - /* extract slot & connection id */ - if (copy_from_user(&slot, buf, 1)) - return -EFAULT; - if (copy_from_user(&connection_id, buf + 1, 1)) - return -EFAULT; - buf += 2; - count -= 2; - - /* check if the slot is actually running */ - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) - return -EINVAL; - - /* fragment the packets & store in the buffer */ - while (fragpos < count) { - fraglen = ca->slot_info[slot].link_buf_size - 2; - if ((count - fragpos) < fraglen) - fraglen = count - fragpos; - - fragbuf[0] = connection_id; - fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00; - if ((status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen)) != 0) - goto exit; - - timeout = jiffies + HZ / 2; - written = 0; - while (!time_after(jiffies, timeout)) { - /* check the CAM hasn't been removed/reset in the meantime */ - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) { - status = -EIO; - goto exit; - } - - status = dvb_ca_en50221_write_data(ca, slot, fragbuf, fraglen + 2); - if (status == (fraglen + 2)) { - written = 1; - break; - } - if (status != -EAGAIN) - goto exit; - - msleep(1); - } - if (!written) { - status = -EIO; - goto exit; - } - - fragpos += fraglen; - } - status = count + 2; - -exit: - return status; -} - - -/** - * Condition for waking up in dvb_ca_en50221_io_read_condition - */ -static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, - int *result, int *_slot) -{ - int slot; - int slot_count = 0; - int idx; - size_t fraglen; - int connection_id = -1; - int found = 0; - u8 hdr[2]; - - slot = ca->next_read_slot; - while ((slot_count < ca->slot_count) && (!found)) { - if (ca->slot_info[slot].slot_state != DVB_CA_SLOTSTATE_RUNNING) - goto nextslot; - - if (ca->slot_info[slot].rx_buffer.data == NULL) { - return 0; - } - - idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); - while (idx != -1) { - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); - if (connection_id == -1) - connection_id = hdr[0]; - if ((hdr[0] == connection_id) && ((hdr[1] & 0x80) == 0)) { - *_slot = slot; - found = 1; - break; - } - - idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen); - } - -nextslot: - slot = (slot + 1) % ca->slot_count; - slot_count++; - } - - ca->next_read_slot = slot; - return found; -} - - -/** - * Implementation of read() syscall. - * - * @param file File structure. - * @param buf Destination buffer. - * @param count Size of destination buffer. - * @param ppos Position in file (ignored). - * - * @return Number of bytes read, or <0 on error. - */ -static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, - size_t count, loff_t * ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_ca_private *ca = dvbdev->priv; - int status; - int result = 0; - u8 hdr[2]; - int slot; - int connection_id = -1; - size_t idx, idx2; - int last_fragment = 0; - size_t fraglen; - int pktlen; - int dispose = 0; - - dprintk("%s\n", __func__); - - /* Outgoing packet has a 2 byte header. hdr[0] = slot_id, hdr[1] = connection_id */ - if (count < 2) - return -EINVAL; - - /* wait for some data */ - if ((status = dvb_ca_en50221_io_read_condition(ca, &result, &slot)) == 0) { - - /* if we're in nonblocking mode, exit immediately */ - if (file->f_flags & O_NONBLOCK) - return -EWOULDBLOCK; - - /* wait for some data */ - status = wait_event_interruptible(ca->wait_queue, - dvb_ca_en50221_io_read_condition - (ca, &result, &slot)); - } - if ((status < 0) || (result < 0)) { - if (result) - return result; - return status; - } - - idx = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, -1, &fraglen); - pktlen = 2; - do { - if (idx == -1) { - printk("dvb_ca adapter %d: BUG: read packet ended before last_fragment encountered\n", ca->dvbdev->adapter->num); - status = -EIO; - goto exit; - } - - dvb_ringbuffer_pkt_read(&ca->slot_info[slot].rx_buffer, idx, 0, hdr, 2); - if (connection_id == -1) - connection_id = hdr[0]; - if (hdr[0] == connection_id) { - if (pktlen < count) { - if ((pktlen + fraglen - 2) > count) { - fraglen = count - pktlen; - } else { - fraglen -= 2; - } - - if ((status = dvb_ringbuffer_pkt_read_user(&ca->slot_info[slot].rx_buffer, idx, 2, - buf + pktlen, fraglen)) < 0) { - goto exit; - } - pktlen += fraglen; - } - - if ((hdr[1] & 0x80) == 0) - last_fragment = 1; - dispose = 1; - } - - idx2 = dvb_ringbuffer_pkt_next(&ca->slot_info[slot].rx_buffer, idx, &fraglen); - if (dispose) - dvb_ringbuffer_pkt_dispose(&ca->slot_info[slot].rx_buffer, idx); - idx = idx2; - dispose = 0; - } while (!last_fragment); - - hdr[0] = slot; - hdr[1] = connection_id; - if ((status = copy_to_user(buf, hdr, 2)) != 0) - goto exit; - status = pktlen; - -exit: - return status; -} - - -/** - * Implementation of file open syscall. - * - * @param inode Inode concerned. - * @param file File concerned. - * - * @return 0 on success, <0 on failure. - */ -static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_ca_private *ca = dvbdev->priv; - int err; - int i; - - dprintk("%s\n", __func__); - - if (!try_module_get(ca->pub->owner)) - return -EIO; - - err = dvb_generic_open(inode, file); - if (err < 0) { - module_put(ca->pub->owner); - return err; - } - - for (i = 0; i < ca->slot_count; i++) { - - if (ca->slot_info[i].slot_state == DVB_CA_SLOTSTATE_RUNNING) { - if (ca->slot_info[i].rx_buffer.data != NULL) { - /* it is safe to call this here without locks because - * ca->open == 0. Data is not read in this case */ - dvb_ringbuffer_flush(&ca->slot_info[i].rx_buffer); - } - } - } - - ca->open = 1; - dvb_ca_en50221_thread_update_delay(ca); - dvb_ca_en50221_thread_wakeup(ca); - - return 0; -} - - -/** - * Implementation of file close syscall. - * - * @param inode Inode concerned. - * @param file File concerned. - * - * @return 0 on success, <0 on failure. - */ -static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_ca_private *ca = dvbdev->priv; - int err; - - dprintk("%s\n", __func__); - - /* mark the CA device as closed */ - ca->open = 0; - dvb_ca_en50221_thread_update_delay(ca); - - err = dvb_generic_release(inode, file); - - module_put(ca->pub->owner); - - return err; -} - - -/** - * Implementation of poll() syscall. - * - * @param file File concerned. - * @param wait poll wait table. - * - * @return Standard poll mask. - */ -static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_ca_private *ca = dvbdev->priv; - unsigned int mask = 0; - int slot; - int result = 0; - - dprintk("%s\n", __func__); - - if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) { - mask |= POLLIN; - } - - /* if there is something, return now */ - if (mask) - return mask; - - /* wait for something to happen */ - poll_wait(file, &ca->wait_queue, wait); - - if (dvb_ca_en50221_io_read_condition(ca, &result, &slot) == 1) { - mask |= POLLIN; - } - - return mask; -} -EXPORT_SYMBOL(dvb_ca_en50221_init); - - -static struct file_operations dvb_ca_fops = { - .owner = THIS_MODULE, - .read = dvb_ca_en50221_io_read, - .write = dvb_ca_en50221_io_write, - .ioctl = dvb_ca_en50221_io_ioctl, - .open = dvb_ca_en50221_io_open, - .release = dvb_ca_en50221_io_release, - .poll = dvb_ca_en50221_io_poll, -}; - -static struct dvb_device dvbdev_ca = { - .priv = NULL, - .users = 1, - .readers = 1, - .writers = 1, - .fops = &dvb_ca_fops, -}; - - -/* ******************************************************************************** */ -/* Initialisation/shutdown functions */ - - -/** - * Initialise a new DVB CA EN50221 interface device. - * - * @param dvb_adapter DVB adapter to attach the new CA device to. - * @param ca The dvb_ca instance. - * @param flags Flags describing the CA device (DVB_CA_FLAG_*). - * @param slot_count Number of slots supported. - * - * @return 0 on success, nonzero on failure - */ -int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, - struct dvb_ca_en50221 *pubca, int flags, int slot_count) -{ - int ret; - struct dvb_ca_private *ca = NULL; - int i; - - dprintk("%s\n", __func__); - - if (slot_count < 1) - return -EINVAL; - - /* initialise the system data */ - if ((ca = kzalloc(sizeof(struct dvb_ca_private), GFP_KERNEL)) == NULL) { - ret = -ENOMEM; - goto error; - } - ca->pub = pubca; - ca->flags = flags; - ca->slot_count = slot_count; - if ((ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), GFP_KERNEL)) == NULL) { - ret = -ENOMEM; - goto error; - } - init_waitqueue_head(&ca->wait_queue); - ca->open = 0; - ca->wakeup = 0; - ca->next_read_slot = 0; - pubca->private = ca; - - /* register the DVB device */ - ret = dvb_register_device(dvb_adapter, &ca->dvbdev, &dvbdev_ca, ca, DVB_DEVICE_CA); - if (ret) - goto error; - - /* now initialise each slot */ - for (i = 0; i < slot_count; i++) { - memset(&ca->slot_info[i], 0, sizeof(struct dvb_ca_slot)); - ca->slot_info[i].slot_state = DVB_CA_SLOTSTATE_NONE; - atomic_set(&ca->slot_info[i].camchange_count, 0); - ca->slot_info[i].camchange_type = DVB_CA_EN50221_CAMCHANGE_REMOVED; - } - - if (signal_pending(current)) { - ret = -EINTR; - goto error; - } - mb(); - - /* create a kthread for monitoring this CA device */ - ca->thread = kthread_run(dvb_ca_en50221_thread, ca, "kdvb-ca-%i:%i", - ca->dvbdev->adapter->num, ca->dvbdev->id); - if (IS_ERR(ca->thread)) { - ret = PTR_ERR(ca->thread); - printk("dvb_ca_init: failed to start kernel_thread (%d)\n", - ret); - goto error; - } - return 0; - -error: - if (ca != NULL) { - if (ca->dvbdev != NULL) - dvb_unregister_device(ca->dvbdev); - kfree(ca->slot_info); - kfree(ca); - } - pubca->private = NULL; - return ret; -} -EXPORT_SYMBOL(dvb_ca_en50221_release); - - - -/** - * Release a DVB CA EN50221 interface device. - * - * @param ca_dev The dvb_device_t instance for the CA device. - * @param ca The associated dvb_ca instance. - */ -void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) -{ - struct dvb_ca_private *ca = pubca->private; - int i; - - dprintk("%s\n", __func__); - - /* shutdown the thread if there was one */ - kthread_stop(ca->thread); - - for (i = 0; i < ca->slot_count; i++) { - dvb_ca_en50221_slot_shutdown(ca, i); - vfree(ca->slot_info[i].rx_buffer.data); - } - kfree(ca->slot_info); - dvb_unregister_device(ca->dvbdev); - kfree(ca); - pubca->private = NULL; -} diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb/dvb-core/dvb_ca_en50221.h deleted file mode 100644 index 8467e63ddc0..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * dvb_ca.h: generic DVB functions for EN50221 CA interfaces - * - * Copyright (C) 2004 Andrew de Quincey - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _DVB_CA_EN50221_H_ -#define _DVB_CA_EN50221_H_ - -#include <linux/list.h> -#include <linux/dvb/ca.h> - -#include "dvbdev.h" - -#define DVB_CA_EN50221_POLL_CAM_PRESENT 1 -#define DVB_CA_EN50221_POLL_CAM_CHANGED 2 -#define DVB_CA_EN50221_POLL_CAM_READY 4 - -#define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE 1 -#define DVB_CA_EN50221_FLAG_IRQ_FR 2 -#define DVB_CA_EN50221_FLAG_IRQ_DA 4 - -#define DVB_CA_EN50221_CAMCHANGE_REMOVED 0 -#define DVB_CA_EN50221_CAMCHANGE_INSERTED 1 - - - -/* Structure describing a CA interface */ -struct dvb_ca_en50221 { - - /* the module owning this structure */ - struct module* owner; - - /* NOTE: the read_*, write_* and poll_slot_status functions must use locks as - * they may be called from several threads at once */ - - /* functions for accessing attribute memory on the CAM */ - int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address); - int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value); - - /* functions for accessing the control interface on the CAM */ - int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address); - int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value); - - /* Functions for controlling slots */ - int (*slot_reset)(struct dvb_ca_en50221* ca, int slot); - int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot); - int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot); - - /* - * Poll slot status. - * Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set - */ - int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open); - - /* private data, used by caller */ - void* data; - - /* Opaque data used by the dvb_ca core. Do not modify! */ - void* private; -}; - - - - -/* ******************************************************************************** */ -/* Functions for reporting IRQ events */ - -/** - * A CAMCHANGE IRQ has occurred. - * - * @param ca CA instance. - * @param slot Slot concerned. - * @param change_type One of the DVB_CA_CAMCHANGE_* values - */ -void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type); - -/** - * A CAMREADY IRQ has occurred. - * - * @param ca CA instance. - * @param slot Slot concerned. - */ -void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot); - -/** - * An FR or a DA IRQ has occurred. - * - * @param ca CA instance. - * @param slot Slot concerned. - */ -void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot); - - - -/* ******************************************************************************** */ -/* Initialisation/shutdown functions */ - -/** - * Initialise a new DVB CA device. - * - * @param dvb_adapter DVB adapter to attach the new CA device to. - * @param ca The dvb_ca instance. - * @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*). - * @param slot_count Number of slots supported. - * - * @return 0 on success, nonzero on failure - */ -extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count); - -/** - * Release a DVB CA device. - * - * @param ca The associated dvb_ca instance. - */ -extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca); - - - -#endif diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c deleted file mode 100644 index a2c1fd5d2f6..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ /dev/null @@ -1,1237 +0,0 @@ -/* - * dvb_demux.c - DVB kernel demux API - * - * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de> - * & Marcus Metzler <marcus@convergence.de> - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include <linux/spinlock.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/module.h> -#include <linux/poll.h> -#include <linux/string.h> -#include <linux/crc32.h> -#include <asm/uaccess.h> - -#include "dvb_demux.h" - -#define NOBUFS -/* -** #define DVB_DEMUX_SECTION_LOSS_LOG to monitor payload loss in the syslog -*/ -// #define DVB_DEMUX_SECTION_LOSS_LOG - -/****************************************************************************** - * static inlined helper functions - ******************************************************************************/ - -static inline u16 section_length(const u8 *buf) -{ - return 3 + ((buf[1] & 0x0f) << 8) + buf[2]; -} - -static inline u16 ts_pid(const u8 *buf) -{ - return ((buf[1] & 0x1f) << 8) + buf[2]; -} - -static inline u8 payload(const u8 *tsp) -{ - if (!(tsp[3] & 0x10)) // no payload? - return 0; - - if (tsp[3] & 0x20) { // adaptation field? - if (tsp[4] > 183) // corrupted data? - return 0; - else - return 184 - 1 - tsp[4]; - } - - return 184; -} - -static u32 dvb_dmx_crc32(struct dvb_demux_feed *f, const u8 *src, size_t len) -{ - return (f->feed.sec.crc_val = crc32_be(f->feed.sec.crc_val, src, len)); -} - -static void dvb_dmx_memcopy(struct dvb_demux_feed *f, u8 *d, const u8 *s, - size_t len) -{ - memcpy(d, s, len); -} - -/****************************************************************************** - * Software filter functions - ******************************************************************************/ - -static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, - const u8 *buf) -{ - int count = payload(buf); - int p; - //int ccok; - //u8 cc; - - if (count == 0) - return -1; - - p = 188 - count; - - /* - cc = buf[3] & 0x0f; - ccok = ((feed->cc + 1) & 0x0f) == cc; - feed->cc = cc; - if (!ccok) - printk("missed packet!\n"); - */ - - if (buf[1] & 0x40) // PUSI ? - feed->peslen = 0xfffa; - - feed->peslen += count; - - return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK); -} - -static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, - struct dvb_demux_filter *f) -{ - u8 neq = 0; - int i; - - for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { - u8 xor = f->filter.filter_value[i] ^ feed->feed.sec.secbuf[i]; - - if (f->maskandmode[i] & xor) - return 0; - - neq |= f->maskandnotmode[i] & xor; - } - - if (f->doneq && !neq) - return 0; - - return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen, - NULL, 0, &f->filter, DMX_OK); -} - -static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct dvb_demux_filter *f = feed->filter; - struct dmx_section_feed *sec = &feed->feed.sec; - int section_syntax_indicator; - - if (!sec->is_filtering) - return 0; - - if (!f) - return 0; - - if (sec->check_crc) { - section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0); - if (section_syntax_indicator && - demux->check_crc32(feed, sec->secbuf, sec->seclen)) - return -1; - } - - do { - if (dvb_dmx_swfilter_sectionfilter(feed, f) < 0) - return -1; - } while ((f = f->next) && sec->is_filtering); - - sec->seclen = 0; - - return 0; -} - -static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) -{ - struct dmx_section_feed *sec = &feed->feed.sec; - -#ifdef DVB_DEMUX_SECTION_LOSS_LOG - if (sec->secbufp < sec->tsfeedp) { - int i, n = sec->tsfeedp - sec->secbufp; - - /* - * Section padding is done with 0xff bytes entirely. - * Due to speed reasons, we won't check all of them - * but just first and last. - */ - if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { - printk("dvb_demux.c section ts padding loss: %d/%d\n", - n, sec->tsfeedp); - printk("dvb_demux.c pad data:"); - for (i = 0; i < n; i++) - printk(" %02x", sec->secbuf[i]); - printk("\n"); - } - } -#endif - - sec->tsfeedp = sec->secbufp = sec->seclen = 0; - sec->secbuf = sec->secbuf_base; -} - -/* - * Losless Section Demux 1.4.1 by Emard - * Valsecchi Patrick: - * - middle of section A (no PUSI) - * - end of section A and start of section B - * (with PUSI pointing to the start of the second section) - * - * In this case, without feed->pusi_seen you'll receive a garbage section - * consisting of the end of section A. Basically because tsfeedp - * is incemented and the use=0 condition is not raised - * when the second packet arrives. - * - * Fix: - * when demux is started, let feed->pusi_seen = 0 to - * prevent initial feeding of garbage from the end of - * previous section. When you for the first time see PUSI=1 - * then set feed->pusi_seen = 1 - */ -static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, - const u8 *buf, u8 len) -{ - struct dvb_demux *demux = feed->demux; - struct dmx_section_feed *sec = &feed->feed.sec; - u16 limit, seclen, n; - - if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE) - return 0; - - if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { -#ifdef DVB_DEMUX_SECTION_LOSS_LOG - printk("dvb_demux.c section buffer full loss: %d/%d\n", - sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, - DMX_MAX_SECFEED_SIZE); -#endif - len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; - } - - if (len <= 0) - return 0; - - demux->memcopy(feed, sec->secbuf_base + sec->tsfeedp, buf, len); - sec->tsfeedp += len; - - /* - * Dump all the sections we can find in the data (Emard) - */ - limit = sec->tsfeedp; - if (limit > DMX_MAX_SECFEED_SIZE) - return -1; /* internal error should never happen */ - - /* to be sure always set secbuf */ - sec->secbuf = sec->secbuf_base + sec->secbufp; - - for (n = 0; sec->secbufp + 2 < limit; n++) { - seclen = section_length(sec->secbuf); - if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE - || seclen + sec->secbufp > limit) - return 0; - sec->seclen = seclen; - sec->crc_val = ~0; - /* dump [secbuf .. secbuf+seclen) */ - if (feed->pusi_seen) - dvb_dmx_swfilter_section_feed(feed); -#ifdef DVB_DEMUX_SECTION_LOSS_LOG - else - printk("dvb_demux.c pusi not seen, discarding section data\n"); -#endif - sec->secbufp += seclen; /* secbufp and secbuf moving together is */ - sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ - } - - return 0; -} - -static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, - const u8 *buf) -{ - u8 p, count; - int ccok, dc_i = 0; - u8 cc; - - count = payload(buf); - - if (count == 0) /* count == 0 if no payload or out of range */ - return -1; - - p = 188 - count; /* payload start */ - - cc = buf[3] & 0x0f; - ccok = ((feed->cc + 1) & 0x0f) == cc; - feed->cc = cc; - - if (buf[3] & 0x20) { - /* adaption field present, check for discontinuity_indicator */ - if ((buf[4] > 0) && (buf[5] & 0x80)) - dc_i = 1; - } - - if (!ccok || dc_i) { -#ifdef DVB_DEMUX_SECTION_LOSS_LOG - printk("dvb_demux.c discontinuity detected %d bytes lost\n", - count); - /* - * those bytes under sume circumstances will again be reported - * in the following dvb_dmx_swfilter_section_new - */ -#endif - /* - * Discontinuity detected. Reset pusi_seen = 0 to - * stop feeding of suspicious data until next PUSI=1 arrives - */ - feed->pusi_seen = 0; - dvb_dmx_swfilter_section_new(feed); - } - - if (buf[1] & 0x40) { - /* PUSI=1 (is set), section boundary is here */ - if (count > 1 && buf[p] < count) { - const u8 *before = &buf[p + 1]; - u8 before_len = buf[p]; - const u8 *after = &before[before_len]; - u8 after_len = count - 1 - before_len; - - dvb_dmx_swfilter_section_copy_dump(feed, before, - before_len); - /* before start of new section, set pusi_seen = 1 */ - feed->pusi_seen = 1; - dvb_dmx_swfilter_section_new(feed); - dvb_dmx_swfilter_section_copy_dump(feed, after, - after_len); - } -#ifdef DVB_DEMUX_SECTION_LOSS_LOG - else if (count > 0) - printk("dvb_demux.c PUSI=1 but %d bytes lost\n", count); -#endif - } else { - /* PUSI=0 (is not set), no section boundary */ - dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count); - } - - return 0; -} - -static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, - const u8 *buf) -{ - switch (feed->type) { - case DMX_TYPE_TS: - if (!feed->feed.ts.is_filtering) - break; - if (feed->ts_type & TS_PACKET) { - if (feed->ts_type & TS_PAYLOAD_ONLY) - dvb_dmx_swfilter_payload(feed, buf); - else - feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, - DMX_OK); - } - if (feed->ts_type & TS_DECODER) - if (feed->demux->write_to_decoder) - feed->demux->write_to_decoder(feed, buf, 188); - break; - - case DMX_TYPE_SEC: - if (!feed->feed.sec.is_filtering) - break; - if (dvb_dmx_swfilter_section_packet(feed, buf) < 0) - feed->feed.sec.seclen = feed->feed.sec.secbufp = 0; - break; - - default: - break; - } -} - -#define DVR_FEED(f) \ - (((f)->type == DMX_TYPE_TS) && \ - ((f)->feed.ts.is_filtering) && \ - (((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET)) - -static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) -{ - struct dvb_demux_feed *feed; - u16 pid = ts_pid(buf); - int dvr_done = 0; - - list_for_each_entry(feed, &demux->feed_list, list_head) { - if ((feed->pid != pid) && (feed->pid != 0x2000)) - continue; - - /* copy each packet only once to the dvr device, even - * if a PID is in multiple filters (e.g. video + PCR) */ - if ((DVR_FEED(feed)) && (dvr_done++)) - continue; - - if (feed->pid == pid) { - dvb_dmx_swfilter_packet_type(feed, buf); - if (DVR_FEED(feed)) - continue; - } - - if (feed->pid == 0x2000) - feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, DMX_OK); - } -} - -void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, - size_t count) -{ - unsigned long flags; - - spin_lock_irqsave(&demux->lock, flags); - - while (count--) { - if (buf[0] == 0x47) - dvb_dmx_swfilter_packet(demux, buf); - buf += 188; - } - - spin_unlock_irqrestore(&demux->lock, flags); -} - -EXPORT_SYMBOL(dvb_dmx_swfilter_packets); - -void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count) -{ - unsigned long flags; - int p = 0, i, j; - - spin_lock_irqsave(&demux->lock, flags); - - if (demux->tsbufp) { - i = demux->tsbufp; - j = 188 - i; - if (count < j) { - memcpy(&demux->tsbuf[i], buf, count); - demux->tsbufp += count; - goto bailout; - } - memcpy(&demux->tsbuf[i], buf, j); - if (demux->tsbuf[0] == 0x47) - dvb_dmx_swfilter_packet(demux, demux->tsbuf); - demux->tsbufp = 0; - p += j; - } - - while (p < count) { - if (buf[p] == 0x47) { - if (count - p >= 188) { - dvb_dmx_swfilter_packet(demux, &buf[p]); - p += 188; - } else { - i = count - p; - memcpy(demux->tsbuf, &buf[p], i); - demux->tsbufp = i; - goto bailout; - } - } else - p++; - } - -bailout: - spin_unlock_irqrestore(&demux->lock, flags); -} - -EXPORT_SYMBOL(dvb_dmx_swfilter); - -void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count) -{ - unsigned long flags; - int p = 0, i, j; - u8 tmppack[188]; - - spin_lock_irqsave(&demux->lock, flags); - - if (demux->tsbufp) { - i = demux->tsbufp; - j = 204 - i; - if (count < j) { - memcpy(&demux->tsbuf[i], buf, count); - demux->tsbufp += count; - goto bailout; - } - memcpy(&demux->tsbuf[i], buf, j); - if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) { - memcpy(tmppack, demux->tsbuf, 188); - if (tmppack[0] == 0xB8) - tmppack[0] = 0x47; - dvb_dmx_swfilter_packet(demux, tmppack); - } - demux->tsbufp = 0; - p += j; - } - - while (p < count) { - if ((buf[p] == 0x47) || (buf[p] == 0xB8)) { - if (count - p >= 204) { - memcpy(tmppack, &buf[p], 188); - if (tmppack[0] == 0xB8) - tmppack[0] = 0x47; - dvb_dmx_swfilter_packet(demux, tmppack); - p += 204; - } else { - i = count - p; - memcpy(demux->tsbuf, &buf[p], i); - demux->tsbufp = i; - goto bailout; - } - } else { - p++; - } - } - -bailout: - spin_unlock_irqrestore(&demux->lock, flags); -} - -EXPORT_SYMBOL(dvb_dmx_swfilter_204); - -static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux) -{ - int i; - - for (i = 0; i < demux->filternum; i++) - if (demux->filter[i].state == DMX_STATE_FREE) - break; - - if (i == demux->filternum) - return NULL; - - demux->filter[i].state = DMX_STATE_ALLOCATED; - - return &demux->filter[i]; -} - -static struct dvb_demux_feed *dvb_dmx_feed_alloc(struct dvb_demux *demux) -{ - int i; - - for (i = 0; i < demux->feednum; i++) - if (demux->feed[i].state == DMX_STATE_FREE) - break; - - if (i == demux->feednum) - return NULL; - - demux->feed[i].state = DMX_STATE_ALLOCATED; - - return &demux->feed[i]; -} - -static int dvb_demux_feed_find(struct dvb_demux_feed *feed) -{ - struct dvb_demux_feed *entry; - - list_for_each_entry(entry, &feed->demux->feed_list, list_head) - if (entry == feed) - return 1; - - return 0; -} - -static void dvb_demux_feed_add(struct dvb_demux_feed *feed) -{ - spin_lock_irq(&feed->demux->lock); - if (dvb_demux_feed_find(feed)) { - printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n", - __func__, feed->type, feed->state, feed->pid); - goto out; - } - - list_add(&feed->list_head, &feed->demux->feed_list); -out: - spin_unlock_irq(&feed->demux->lock); -} - -static void dvb_demux_feed_del(struct dvb_demux_feed *feed) -{ - spin_lock_irq(&feed->demux->lock); - if (!(dvb_demux_feed_find(feed))) { - printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n", - __func__, feed->type, feed->state, feed->pid); - goto out; - } - - list_del(&feed->list_head); -out: - spin_unlock_irq(&feed->demux->lock); -} - -static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type, - enum dmx_ts_pes pes_type, - size_t circular_buffer_size, struct timespec timeout) -{ - struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - struct dvb_demux *demux = feed->demux; - - if (pid > DMX_MAX_PID) - return -EINVAL; - - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; - - if (ts_type & TS_DECODER) { - if (pes_type >= DMX_TS_PES_OTHER) { - mutex_unlock(&demux->mutex); - return -EINVAL; - } - - if (demux->pesfilter[pes_type] && - demux->pesfilter[pes_type] != feed) { - mutex_unlock(&demux->mutex); - return -EINVAL; - } - - demux->pesfilter[pes_type] = feed; - demux->pids[pes_type] = pid; - } - - dvb_demux_feed_add(feed); - - feed->pid = pid; - feed->buffer_size = circular_buffer_size; - feed->timeout = timeout; - feed->ts_type = ts_type; - feed->pes_type = pes_type; - - if (feed->buffer_size) { -#ifdef NOBUFS - feed->buffer = NULL; -#else - feed->buffer = vmalloc(feed->buffer_size); - if (!feed->buffer) { - mutex_unlock(&demux->mutex); - return -ENOMEM; - } -#endif - } - - feed->state = DMX_STATE_READY; - mutex_unlock(&demux->mutex); - - return 0; -} - -static int dmx_ts_feed_start_filtering(struct dmx_ts_feed *ts_feed) -{ - struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - struct dvb_demux *demux = feed->demux; - int ret; - - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; - - if (feed->state != DMX_STATE_READY || feed->type != DMX_TYPE_TS) { - mutex_unlock(&demux->mutex); - return -EINVAL; - } - - if (!demux->start_feed) { - mutex_unlock(&demux->mutex); - return -ENODEV; - } - - if ((ret = demux->start_feed(feed)) < 0) { - mutex_unlock(&demux->mutex); - return ret; - } - - spin_lock_irq(&demux->lock); - ts_feed->is_filtering = 1; - feed->state = DMX_STATE_GO; - spin_unlock_irq(&demux->lock); - mutex_unlock(&demux->mutex); - - return 0; -} - -static int dmx_ts_feed_stop_filtering(struct dmx_ts_feed *ts_feed) -{ - struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - struct dvb_demux *demux = feed->demux; - int ret; - - mutex_lock(&demux->mutex); - - if (feed->state < DMX_STATE_GO) { - mutex_unlock(&demux->mutex); - return -EINVAL; - } - - if (!demux->stop_feed) { - mutex_unlock(&demux->mutex); - return -ENODEV; - } - - ret = demux->stop_feed(feed); - - spin_lock_irq(&demux->lock); - ts_feed->is_filtering = 0; - feed->state = DMX_STATE_ALLOCATED; - spin_unlock_irq(&demux->lock); - mutex_unlock(&demux->mutex); - - return ret; -} - -static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, - struct dmx_ts_feed **ts_feed, - dmx_ts_cb callback) -{ - struct dvb_demux *demux = (struct dvb_demux *)dmx; - struct dvb_demux_feed *feed; - - if (mutex_lock_interruptible(&demux->mutex)) - return -ERESTARTSYS; - - if (!(feed = dvb_dmx_feed_alloc(demux))) { - mutex_unlock(&demux->mutex); - return -EBUSY; - } - - feed->type = DMX_TYPE_TS; - feed->cb.ts = callback; - feed->demux = demux; - feed->pid = 0xffff; - feed->peslen = 0xfffa; - feed->buffer = NULL; - - (*ts_feed) = &feed->feed.ts; - (*ts_feed)->parent = dmx; - (*ts_feed)->priv = NULL; - (*ts_feed)->is_filtering = 0; - (*ts_feed)->start_filtering = dmx_ts_feed_start_filtering; - (*ts_feed)->stop_filtering = dmx_ts_feed_stop_filtering; - (*ts_feed)->set = dmx_ts_feed_set; - - if (!(feed->filter = dvb_dmx_filter_alloc(demux))) { - feed->state = DMX_STATE_FREE; - mutex_unlock(&demux->mutex); - return -EBUSY; - } - - feed->filter->type = DMX_TYPE_TS; - feed->filter->feed = feed; - feed->filter->state = DMX_STATE_READY; - - mutex_unlock(&demux->mutex); - - return 0; -} - -static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, - struct dmx_ts_feed *ts_feed) -{ - struct dvb_demux *demux = (struct dvb_demux *)dmx; - struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed; - - mutex_lock(&demux->mutex); - - if (feed->state == DMX_STATE_FREE) { - mutex_unlock(&demux->mutex); - return -EINVAL; - } -#ifndef NOBUFS - vfree(feed->buffer); - feed->buffer = NULL; -#endif - - feed->state = DMX_STATE_FREE; - feed->filter->state = DMX_STATE_FREE; - - dvb_demux_feed_del(feed); - - feed->pid = 0xffff; - - if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER) - demux->pesfilter[feed->pes_type] = NULL; - - mutex_unlock(&demux->mutex); - return 0; -} - -/****************************************************************************** - * dmx_section_feed API calls - ******************************************************************************/ - -static int dmx_section_feed_allocate_filter(struct dmx_section_feed *feed, - struct dmx_section_filter **filter) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; - struct dvb_demux *dvbdemux = dvbdmxfeed->demux; - struct dvb_demux_filter *dvbdmxfilter; - - if (mutex_lock_interruptible(&dvbdemux->mutex)) - return -ERESTARTSYS; - - dvbdmxfilter = dvb_dmx_filter_alloc(dvbdemux); - if (!dvbdmxfilter) { - mutex_unlock(&dvbdemux->mutex); - return -EBUSY; - } - - spin_lock_irq(&dvbdemux->lock); - *filter = &dvbdmxfilter->filter; - (*filter)->parent = feed; - (*filter)->priv = NULL; - dvbdmxfilter->feed = dvbdmxfeed; - dvbdmxfilter->type = DMX_TYPE_SEC; - dvbdmxfilter->state = DMX_STATE_READY; - dvbdmxfilter->next = dvbdmxfeed->filter; - dvbdmxfeed->filter = dvbdmxfilter; - spin_unlock_irq(&dvbdemux->lock); - - mutex_unlock(&dvbdemux->mutex); - return 0; -} - -static int dmx_section_feed_set(struct dmx_section_feed *feed, - u16 pid, size_t circular_buffer_size, - int check_crc) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - - if (pid > 0x1fff) - return -EINVAL; - - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; - - dvb_demux_feed_add(dvbdmxfeed); - - dvbdmxfeed->pid = pid; - dvbdmxfeed->buffer_size = circular_buffer_size; - dvbdmxfeed->feed.sec.check_crc = check_crc; - -#ifdef NOBUFS - dvbdmxfeed->buffer = NULL; -#else - dvbdmxfeed->buffer = vmalloc(dvbdmxfeed->buffer_size); - if (!dvbdmxfeed->buffer) { - mutex_unlock(&dvbdmx->mutex); - return -ENOMEM; - } -#endif - - dvbdmxfeed->state = DMX_STATE_READY; - mutex_unlock(&dvbdmx->mutex); - return 0; -} - -static void prepare_secfilters(struct dvb_demux_feed *dvbdmxfeed) -{ - int i; - struct dvb_demux_filter *f; - struct dmx_section_filter *sf; - u8 mask, mode, doneq; - - if (!(f = dvbdmxfeed->filter)) - return; - do { - sf = &f->filter; - doneq = 0; - for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { - mode = sf->filter_mode[i]; - mask = sf->filter_mask[i]; - f->maskandmode[i] = mask & mode; - doneq |= f->maskandnotmode[i] = mask & ~mode; - } - f->doneq = doneq ? 1 : 0; - } while ((f = f->next)); -} - -static int dmx_section_feed_start_filtering(struct dmx_section_feed *feed) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - int ret; - - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; - - if (feed->is_filtering) { - mutex_unlock(&dvbdmx->mutex); - return -EBUSY; - } - - if (!dvbdmxfeed->filter) { - mutex_unlock(&dvbdmx->mutex); - return -EINVAL; - } - - dvbdmxfeed->feed.sec.tsfeedp = 0; - dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; - dvbdmxfeed->feed.sec.secbufp = 0; - dvbdmxfeed->feed.sec.seclen = 0; - - if (!dvbdmx->start_feed) { - mutex_unlock(&dvbdmx->mutex); - return -ENODEV; - } - - prepare_secfilters(dvbdmxfeed); - - if ((ret = dvbdmx->start_feed(dvbdmxfeed)) < 0) { - mutex_unlock(&dvbdmx->mutex); - return ret; - } - - spin_lock_irq(&dvbdmx->lock); - feed->is_filtering = 1; - dvbdmxfeed->state = DMX_STATE_GO; - spin_unlock_irq(&dvbdmx->lock); - - mutex_unlock(&dvbdmx->mutex); - return 0; -} - -static int dmx_section_feed_stop_filtering(struct dmx_section_feed *feed) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - int ret; - - mutex_lock(&dvbdmx->mutex); - - if (!dvbdmx->stop_feed) { - mutex_unlock(&dvbdmx->mutex); - return -ENODEV; - } - - ret = dvbdmx->stop_feed(dvbdmxfeed); - - spin_lock_irq(&dvbdmx->lock); - dvbdmxfeed->state = DMX_STATE_READY; - feed->is_filtering = 0; - spin_unlock_irq(&dvbdmx->lock); - - mutex_unlock(&dvbdmx->mutex); - return ret; -} - -static int dmx_section_feed_release_filter(struct dmx_section_feed *feed, - struct dmx_section_filter *filter) -{ - struct dvb_demux_filter *dvbdmxfilter = (struct dvb_demux_filter *)filter, *f; - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - - mutex_lock(&dvbdmx->mutex); - - if (dvbdmxfilter->feed != dvbdmxfeed) { - mutex_unlock(&dvbdmx->mutex); - return -EINVAL; - } - - if (feed->is_filtering) - feed->stop_filtering(feed); - - spin_lock_irq(&dvbdmx->lock); - f = dvbdmxfeed->filter; - - if (f == dvbdmxfilter) { - dvbdmxfeed->filter = dvbdmxfilter->next; - } else { - while (f->next != dvbdmxfilter) - f = f->next; - f->next = f->next->next; - } - - dvbdmxfilter->state = DMX_STATE_FREE; - spin_unlock_irq(&dvbdmx->lock); - mutex_unlock(&dvbdmx->mutex); - return 0; -} - -static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, - struct dmx_section_feed **feed, - dmx_section_cb callback) -{ - struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; - struct dvb_demux_feed *dvbdmxfeed; - - if (mutex_lock_interruptible(&dvbdmx->mutex)) - return -ERESTARTSYS; - - if (!(dvbdmxfeed = dvb_dmx_feed_alloc(dvbdmx))) { - mutex_unlock(&dvbdmx->mutex); - return -EBUSY; - } - - dvbdmxfeed->type = DMX_TYPE_SEC; - dvbdmxfeed->cb.sec = callback; - dvbdmxfeed->demux = dvbdmx; - dvbdmxfeed->pid = 0xffff; - dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; - dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; - dvbdmxfeed->feed.sec.tsfeedp = 0; - dvbdmxfeed->filter = NULL; - dvbdmxfeed->buffer = NULL; - - (*feed) = &dvbdmxfeed->feed.sec; - (*feed)->is_filtering = 0; - (*feed)->parent = demux; - (*feed)->priv = NULL; - - (*feed)->set = dmx_section_feed_set; - (*feed)->allocate_filter = dmx_section_feed_allocate_filter; - (*feed)->start_filtering = dmx_section_feed_start_filtering; - (*feed)->stop_filtering = dmx_section_feed_stop_filtering; - (*feed)->release_filter = dmx_section_feed_release_filter; - - mutex_unlock(&dvbdmx->mutex); - return 0; -} - -static int dvbdmx_release_section_feed(struct dmx_demux *demux, - struct dmx_section_feed *feed) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *)feed; - struct dvb_demux *dvbdmx = (struct dvb_demux *)demux; - - mutex_lock(&dvbdmx->mutex); - - if (dvbdmxfeed->state == DMX_STATE_FREE) { - mutex_unlock(&dvbdmx->mutex); - return -EINVAL; - } -#ifndef NOBUFS - vfree(dvbdmxfeed->buffer); - dvbdmxfeed->buffer = NULL; -#endif - dvbdmxfeed->state = DMX_STATE_FREE; - - dvb_demux_feed_del(dvbdmxfeed); - - dvbdmxfeed->pid = 0xffff; - - mutex_unlock(&dvbdmx->mutex); - return 0; -} - -/****************************************************************************** - * dvb_demux kernel data API calls - ******************************************************************************/ - -static int dvbdmx_open(struct dmx_demux *demux) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - - if (dvbdemux->users >= MAX_DVB_DEMUX_USERS) - return -EUSERS; - - dvbdemux->users++; - return 0; -} - -static int dvbdmx_close(struct dmx_demux *demux) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - - if (dvbdemux->users == 0) - return -ENODEV; - - dvbdemux->users--; - //FIXME: release any unneeded resources if users==0 - return 0; -} - -static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - void *p; - - if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) - return -EINVAL; - - p = kmalloc(count, GFP_USER); - if (!p) - return -ENOMEM; - if (copy_from_user(p, buf, count)) { - kfree(p); - return -EFAULT; - } - if (mutex_lock_interruptible(&dvbdemux->mutex)) { - kfree(p); - return -ERESTARTSYS; - } - dvb_dmx_swfilter(dvbdemux, p, count); - kfree(p); - mutex_unlock(&dvbdemux->mutex); - - if (signal_pending(current)) - return -EINTR; - return count; -} - -static int dvbdmx_add_frontend(struct dmx_demux *demux, - struct dmx_frontend *frontend) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - struct list_head *head = &dvbdemux->frontend_list; - - list_add(&(frontend->connectivity_list), head); - - return 0; -} - -static int dvbdmx_remove_frontend(struct dmx_demux *demux, - struct dmx_frontend *frontend) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - struct list_head *pos, *n, *head = &dvbdemux->frontend_list; - - list_for_each_safe(pos, n, head) { - if (DMX_FE_ENTRY(pos) == frontend) { - list_del(pos); - return 0; - } - } - - return -ENODEV; -} - -static struct list_head *dvbdmx_get_frontends(struct dmx_demux *demux) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - - if (list_empty(&dvbdemux->frontend_list)) - return NULL; - - return &dvbdemux->frontend_list; -} - -static int dvbdmx_connect_frontend(struct dmx_demux *demux, - struct dmx_frontend *frontend) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - - if (demux->frontend) - return -EINVAL; - - mutex_lock(&dvbdemux->mutex); - - demux->frontend = frontend; - mutex_unlock(&dvbdemux->mutex); - return 0; -} - -static int dvbdmx_disconnect_frontend(struct dmx_demux *demux) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - - mutex_lock(&dvbdemux->mutex); - - demux->frontend = NULL; - mutex_unlock(&dvbdemux->mutex); - return 0; -} - -static int dvbdmx_get_pes_pids(struct dmx_demux *demux, u16 * pids) -{ - struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; - - memcpy(pids, dvbdemux->pids, 5 * sizeof(u16)); - return 0; -} - -int dvb_dmx_init(struct dvb_demux *dvbdemux) -{ - int i; - struct dmx_demux *dmx = &dvbdemux->dmx; - - dvbdemux->users = 0; - dvbdemux->filter = vmalloc(dvbdemux->filternum * sizeof(struct dvb_demux_filter)); - - if (!dvbdemux->filter) - return -ENOMEM; - - dvbdemux->feed = vmalloc(dvbdemux->feednum * sizeof(struct dvb_demux_feed)); - if (!dvbdemux->feed) { - vfree(dvbdemux->filter); - return -ENOMEM; - } - for (i = 0; i < dvbdemux->filternum; i++) { - dvbdemux->filter[i].state = DMX_STATE_FREE; - dvbdemux->filter[i].index = i; - } - for (i = 0; i < dvbdemux->feednum; i++) { - dvbdemux->feed[i].state = DMX_STATE_FREE; - dvbdemux->feed[i].index = i; - } - - INIT_LIST_HEAD(&dvbdemux->frontend_list); - - for (i = 0; i < DMX_TS_PES_OTHER; i++) { - dvbdemux->pesfilter[i] = NULL; - dvbdemux->pids[i] = 0xffff; - } - - INIT_LIST_HEAD(&dvbdemux->feed_list); - - dvbdemux->playing = 0; - dvbdemux->recording = 0; - dvbdemux->tsbufp = 0; - - if (!dvbdemux->check_crc32) - dvbdemux->check_crc32 = dvb_dmx_crc32; - - if (!dvbdemux->memcopy) - dvbdemux->memcopy = dvb_dmx_memcopy; - - dmx->frontend = NULL; - dmx->priv = dvbdemux; - dmx->open = dvbdmx_open; - dmx->close = dvbdmx_close; - dmx->write = dvbdmx_write; - dmx->allocate_ts_feed = dvbdmx_allocate_ts_feed; - dmx->release_ts_feed = dvbdmx_release_ts_feed; - dmx->allocate_section_feed = dvbdmx_allocate_section_feed; - dmx->release_section_feed = dvbdmx_release_section_feed; - - dmx->add_frontend = dvbdmx_add_frontend; - dmx->remove_frontend = dvbdmx_remove_frontend; - dmx->get_frontends = dvbdmx_get_frontends; - dmx->connect_frontend = dvbdmx_connect_frontend; - dmx->disconnect_frontend = dvbdmx_disconnect_frontend; - dmx->get_pes_pids = dvbdmx_get_pes_pids; - - mutex_init(&dvbdemux->mutex); - spin_lock_init(&dvbdemux->lock); - - return 0; -} - -EXPORT_SYMBOL(dvb_dmx_init); - -void dvb_dmx_release(struct dvb_demux *dvbdemux) -{ - vfree(dvbdemux->filter); - vfree(dvbdemux->feed); -} - -EXPORT_SYMBOL(dvb_dmx_release); diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h deleted file mode 100644 index 2c5f915329c..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_demux.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * dvb_demux.h: DVB kernel demux API - * - * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _DVB_DEMUX_H_ -#define _DVB_DEMUX_H_ - -#include <linux/time.h> -#include <linux/timer.h> -#include <linux/spinlock.h> -#include <linux/mutex.h> - -#include "demux.h" - -#define DMX_TYPE_TS 0 -#define DMX_TYPE_SEC 1 -#define DMX_TYPE_PES 2 - -#define DMX_STATE_FREE 0 -#define DMX_STATE_ALLOCATED 1 -#define DMX_STATE_SET 2 -#define DMX_STATE_READY 3 -#define DMX_STATE_GO 4 - -#define DVB_DEMUX_MASK_MAX 18 - -struct dvb_demux_filter { - struct dmx_section_filter filter; - u8 maskandmode[DMX_MAX_FILTER_SIZE]; - u8 maskandnotmode[DMX_MAX_FILTER_SIZE]; - int doneq; - - struct dvb_demux_filter *next; - struct dvb_demux_feed *feed; - int index; - int state; - int type; - - u16 hw_handle; - struct timer_list timer; -}; - -#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head) - -struct dvb_demux_feed { - union { - struct dmx_ts_feed ts; - struct dmx_section_feed sec; - } feed; - - union { - dmx_ts_cb ts; - dmx_section_cb sec; - } cb; - - struct dvb_demux *demux; - void *priv; - int type; - int state; - u16 pid; - u8 *buffer; - int buffer_size; - - struct timespec timeout; - struct dvb_demux_filter *filter; - - int ts_type; - enum dmx_ts_pes pes_type; - - int cc; - int pusi_seen; /* prevents feeding of garbage from previous section */ - - u16 peslen; - - struct list_head list_head; - unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */ -}; - -struct dvb_demux { - struct dmx_demux dmx; - void *priv; - int filternum; - int feednum; - int (*start_feed)(struct dvb_demux_feed *feed); - int (*stop_feed)(struct dvb_demux_feed *feed); - int (*write_to_decoder)(struct dvb_demux_feed *feed, - const u8 *buf, size_t len); - u32 (*check_crc32)(struct dvb_demux_feed *feed, - const u8 *buf, size_t len); - void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst, - const u8 *src, size_t len); - - int users; -#define MAX_DVB_DEMUX_USERS 10 - struct dvb_demux_filter *filter; - struct dvb_demux_feed *feed; - - struct list_head frontend_list; - - struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER]; - u16 pids[DMX_TS_PES_OTHER]; - int playing; - int recording; - -#define DMX_MAX_PID 0x2000 - struct list_head feed_list; - u8 tsbuf[204]; - int tsbufp; - - struct mutex mutex; - spinlock_t lock; -}; - -int dvb_dmx_init(struct dvb_demux *dvbdemux); -void dvb_dmx_release(struct dvb_demux *dvbdemux); -void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, - size_t count); -void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count); -void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, - size_t count); - -#endif /* _DVB_DEMUX_H_ */ diff --git a/drivers/media/dvb/dvb-core/dvb_filter.c b/drivers/media/dvb/dvb-core/dvb_filter.c deleted file mode 100644 index 772003fb182..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_filter.c +++ /dev/null @@ -1,603 +0,0 @@ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include "dvb_filter.h" - -#if 0 -static unsigned int bitrates[3][16] = -{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, - {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, - {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; -#endif - -static u32 freq[4] = {480, 441, 320, 0}; - -static unsigned int ac3_bitrates[32] = - {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, - 0,0,0,0,0,0,0,0,0,0,0,0,0}; - -static u32 ac3_frames[3][32] = - {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, - 1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, - 1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, - 1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - - - -#if 0 -static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, - void (*pes_write)(u8 *buf, int count, void *data), - void *priv) -{ - dvb_filter_ipack_init(pa, IPACKS, pes_write); - dvb_filter_ipack_init(pv, IPACKS, pes_write); - pa->pid = pida; - pv->pid = pidv; - pa->data = priv; - pv->data = priv; -} -#endif - -#if 0 -static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) -{ - u8 off = 0; - - if (!buf || !p ){ - printk("NULL POINTER IDIOT\n"); - return; - } - if (buf[1]&PAY_START) { - if (p->plength == MMAX_PLENGTH-6 && p->found>6){ - p->plength = p->found-6; - p->found = 0; - send_ipack(p); - dvb_filter_ipack_reset(p); - } - } - if (buf[3] & ADAPT_FIELD) { // adaptation field? - off = buf[4] + 1; - if (off+4 > 187) return; - } - dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p); -} -#endif - -#if 0 -/* needs 5 byte input, returns picture coding type*/ -static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr) -{ - u8 pct; - - if (pr) printk( "Pic header: "); - pic->temporal_reference[field] = (( headr[0] << 2 ) | - (headr[1] & 0x03) )& 0x03ff; - if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]); - - pct = ( headr[1] >> 2 ) & 0x07; - pic->picture_coding_type[field] = pct; - if (pr) { - switch(pct){ - case I_FRAME: - printk( " I-FRAME"); - break; - case B_FRAME: - printk( " B-FRAME"); - break; - case P_FRAME: - printk( " P-FRAME"); - break; - } - } - - - pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) | - ( (headr[3] & 0x1F) << 11) ) & 0xffff; - - if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay); - - pic->picture_header_parameter = ( headr[3] & 0xe0 ) | - ((headr[4] & 0x80) >> 3); - - if ( pct == B_FRAME ){ - pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f; - } - if (pr) printk( " pic head param: 0x%x", - pic->picture_header_parameter); - - return pct; -} -#endif - -#if 0 -/* needs 4 byte input */ -static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr) -{ - if (pr) printk("GOP header: "); - - pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) | - ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff; - - if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F, - ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F), - ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F)); - - if ( ( headr[3] & 0x40 ) != 0 ){ - pic->closed_gop = 1; - } else { - pic->closed_gop = 0; - } - if (pr) printk("closed: %d", pic->closed_gop); - - if ( ( headr[3] & 0x20 ) != 0 ){ - pic->broken_link = 1; - } else { - pic->broken_link = 0; - } - if (pr) printk(" broken: %d\n", pic->broken_link); - - return 0; -} -#endif - -#if 0 -/* needs 8 byte input */ -static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr) -{ - int sw; - int form = -1; - - if (pr) printk("Reading sequence header\n"); - - vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4); - vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]); - - sw = (int)((headr[3]&0xF0) >> 4) ; - - switch( sw ){ - case 1: - if (pr) - printk("Videostream: ASPECT: 1:1"); - vi->aspect_ratio = 100; - break; - case 2: - if (pr) - printk("Videostream: ASPECT: 4:3"); - vi->aspect_ratio = 133; - break; - case 3: - if (pr) - printk("Videostream: ASPECT: 16:9"); - vi->aspect_ratio = 177; - break; - case 4: - if (pr) - printk("Videostream: ASPECT: 2.21:1"); - vi->aspect_ratio = 221; - break; - - case 5 ... 15: - if (pr) - printk("Videostream: ASPECT: reserved"); - vi->aspect_ratio = 0; - break; - - default: - vi->aspect_ratio = 0; - return -1; - } - - if (pr) - printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size); - - sw = (int)(headr[3]&0x0F); - - switch ( sw ) { - case 1: - if (pr) - printk(" FRate: 23.976 fps"); - vi->framerate = 23976; - form = -1; - break; - case 2: - if (pr) - printk(" FRate: 24 fps"); - vi->framerate = 24000; - form = -1; - break; - case 3: - if (pr) - printk(" FRate: 25 fps"); - vi->framerate = 25000; - form = VIDEO_MODE_PAL; - break; - case 4: - if (pr) - printk(" FRate: 29.97 fps"); - vi->framerate = 29970; - form = VIDEO_MODE_NTSC; - break; - case 5: - if (pr) - printk(" FRate: 30 fps"); - vi->framerate = 30000; - form = VIDEO_MODE_NTSC; - break; - case 6: - if (pr) - printk(" FRate: 50 fps"); - vi->framerate = 50000; - form = VIDEO_MODE_PAL; - break; - case 7: - if (pr) - printk(" FRate: 60 fps"); - vi->framerate = 60000; - form = VIDEO_MODE_NTSC; - break; - } - - vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03); - - vi->vbv_buffer_size - = (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5); - - if (pr){ - printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000); - printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size)); - printk("\n"); - } - - vi->video_format = form; - - return 0; -} -#endif - - -#if 0 -static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - - while (found < 4 && c+4 < count){ - u8 *b; - - b = mbuf+c; - if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 - && b[3] == 0xb3) found = 4; - else { - c++; - } - } - - if (! found) return -1; - c += 4; - if (c+12 >= count) return -1; - headr = mbuf+c; - if (read_sequence_header(headr, vi, pr) < 0) return -1; - vi->off = c-4; - return 0; -} -#endif - - -#if 0 -static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - int fr = 0; - - while (found < 2 && c < count){ - u8 b[2]; - memcpy( b, mbuf+c, 2); - - if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) - found = 2; - else { - c++; - } - } - - if (!found) return -1; - - if (c+3 >= count) return -1; - headr = mbuf+c; - - ai->layer = (headr[1] & 0x06) >> 1; - - if (pr) - printk("Audiostream: Layer: %d", 4-ai->layer); - - - ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; - - if (pr){ - if (ai->bit_rate == 0) - printk(" Bit rate: free"); - else if (ai->bit_rate == 0xf) - printk(" BRate: reserved"); - else - printk(" BRate: %d kb/s", ai->bit_rate/1000); - } - - fr = (headr[2] & 0x0c ) >> 2; - ai->frequency = freq[fr]*100; - if (pr){ - if (ai->frequency == 3) - printk(" Freq: reserved\n"); - else - printk(" Freq: %d kHz\n",ai->frequency); - - } - ai->off = c; - return 0; -} -#endif - - -int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) -{ - u8 *headr; - int found = 0; - int c = 0; - u8 frame = 0; - int fr = 0; - - while ( !found && c < count){ - u8 *b = mbuf+c; - - if ( b[0] == 0x0b && b[1] == 0x77 ) - found = 1; - else { - c++; - } - } - - if (!found) return -1; - if (pr) - printk("Audiostream: AC3"); - - ai->off = c; - if (c+5 >= count) return -1; - - ai->layer = 0; // 0 for AC3 - headr = mbuf+c+2; - - frame = (headr[2]&0x3f); - ai->bit_rate = ac3_bitrates[frame >> 1]*1000; - - if (pr) - printk(" BRate: %d kb/s", (int) ai->bit_rate/1000); - - ai->frequency = (headr[2] & 0xc0 ) >> 6; - fr = (headr[2] & 0xc0 ) >> 6; - ai->frequency = freq[fr]*100; - if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency); - - - ai->framesize = ac3_frames[fr][frame >> 1]; - if ((frame & 1) && (fr == 1)) ai->framesize++; - ai->framesize = ai->framesize << 1; - if (pr) printk (" Framesize %d\n",(int) ai->framesize); - - - return 0; -} -EXPORT_SYMBOL(dvb_filter_get_ac3info); - - -#if 0 -static u8 *skip_pes_header(u8 **bufp) -{ - u8 *inbuf = *bufp; - u8 *buf = inbuf; - u8 *pts = NULL; - int skip = 0; - - static const int mpeg1_skip_table[16] = { - 1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff - }; - - - if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ - if (buf[7] & PTS_ONLY) - pts = buf+9; - else pts = NULL; - buf = inbuf + 9 + inbuf[8]; - } else { /* mpeg1 */ - for (buf = inbuf + 6; *buf == 0xff; buf++) - if (buf == inbuf + 6 + 16) { - break; - } - if ((*buf & 0xc0) == 0x40) - buf += 2; - skip = mpeg1_skip_table [*buf >> 4]; - if (skip == 5 || skip == 10) pts = buf; - else pts = NULL; - - buf += mpeg1_skip_table [*buf >> 4]; - } - - *bufp = buf; - return pts; -} -#endif - -#if 0 -static void initialize_quant_matrix( u32 *matrix ) -{ - int i; - - matrix[0] = 0x08101013; - matrix[1] = 0x10131616; - matrix[2] = 0x16161616; - matrix[3] = 0x1a181a1b; - matrix[4] = 0x1b1b1a1a; - matrix[5] = 0x1a1a1b1b; - matrix[6] = 0x1b1d1d1d; - matrix[7] = 0x2222221d; - matrix[8] = 0x1d1d1b1b; - matrix[9] = 0x1d1d2020; - matrix[10] = 0x22222526; - matrix[11] = 0x25232322; - matrix[12] = 0x23262628; - matrix[13] = 0x28283030; - matrix[14] = 0x2e2e3838; - matrix[15] = 0x3a454553; - - for ( i = 16 ; i < 32 ; i++ ) - matrix[i] = 0x10101010; -} -#endif - -#if 0 -static void initialize_mpg_picture(struct mpg_picture *pic) -{ - int i; - - /* set MPEG1 */ - pic->mpeg1_flag = 1; - pic->profile_and_level = 0x4A ; /* MP@LL */ - pic->progressive_sequence = 1; - pic->low_delay = 0; - - pic->sequence_display_extension_flag = 0; - for ( i = 0 ; i < 4 ; i++ ){ - pic->frame_centre_horizontal_offset[i] = 0; - pic->frame_centre_vertical_offset[i] = 0; - } - pic->last_frame_centre_horizontal_offset = 0; - pic->last_frame_centre_vertical_offset = 0; - - pic->picture_display_extension_flag[0] = 0; - pic->picture_display_extension_flag[1] = 0; - pic->sequence_header_flag = 0; - pic->gop_flag = 0; - pic->sequence_end_flag = 0; -} -#endif - -#if 0 -static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic ) -{ - int16_t last_h_offset; - int16_t last_v_offset; - - int16_t *p_h_offset; - int16_t *p_v_offset; - - if ( pic->mpeg1_flag ){ - pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE; - pic->top_field_first = 0; - pic->repeat_first_field = 0; - pic->progressive_frame = 1; - pic->picture_coding_parameter = 0x000010; - } - - /* Reset flag */ - pic->picture_display_extension_flag[field_type] = 0; - - last_h_offset = pic->last_frame_centre_horizontal_offset; - last_v_offset = pic->last_frame_centre_vertical_offset; - if ( field_type == FIRST_FIELD ){ - p_h_offset = pic->frame_centre_horizontal_offset; - p_v_offset = pic->frame_centre_vertical_offset; - *p_h_offset = last_h_offset; - *(p_h_offset + 1) = last_h_offset; - *(p_h_offset + 2) = last_h_offset; - *p_v_offset = last_v_offset; - *(p_v_offset + 1) = last_v_offset; - *(p_v_offset + 2) = last_v_offset; - } else { - pic->frame_centre_horizontal_offset[3] = last_h_offset; - pic->frame_centre_vertical_offset[3] = last_v_offset; - } -} -#endif - -#if 0 -static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type) -{ - pic->picture_header = 0; - pic->sequence_header_data - = ( INIT_HORIZONTAL_SIZE << 20 ) - | ( INIT_VERTICAL_SIZE << 8 ) - | ( INIT_ASPECT_RATIO << 4 ) - | ( INIT_FRAME_RATE ); - pic->mpeg1_flag = 0; - pic->vinfo.horizontal_size - = INIT_DISP_HORIZONTAL_SIZE; - pic->vinfo.vertical_size - = INIT_DISP_VERTICAL_SIZE; - pic->picture_display_extension_flag[field_type] - = 0; - pic->pts_flag[field_type] = 0; - - pic->sequence_gop_header = 0; - pic->picture_header = 0; - pic->sequence_header_flag = 0; - pic->gop_flag = 0; - pic->sequence_end_flag = 0; - pic->sequence_display_extension_flag = 0; - pic->last_frame_centre_horizontal_offset = 0; - pic->last_frame_centre_vertical_offset = 0; - pic->channel = chan; -} -#endif - -void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, - dvb_filter_pes2ts_cb_t *cb, void *priv) -{ - unsigned char *buf=p2ts->buf; - - buf[0]=0x47; - buf[1]=(pid>>8); - buf[2]=pid&0xff; - p2ts->cc=0; - p2ts->cb=cb; - p2ts->priv=priv; -} -EXPORT_SYMBOL(dvb_filter_pes2ts_init); - -int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, - int len, int payload_start) -{ - unsigned char *buf=p2ts->buf; - int ret=0, rest; - - //len=6+((pes[4]<<8)|pes[5]); - - if (payload_start) - buf[1]|=0x40; - else - buf[1]&=~0x40; - while (len>=184) { - buf[3]=0x10|((p2ts->cc++)&0x0f); - memcpy(buf+4, pes, 184); - if ((ret=p2ts->cb(p2ts->priv, buf))) - return ret; - len-=184; pes+=184; - buf[1]&=~0x40; - } - if (!len) - return 0; - buf[3]=0x30|((p2ts->cc++)&0x0f); - rest=183-len; - if (rest) { - buf[5]=0x00; - if (rest-1) - memset(buf+6, 0xff, rest-1); - } - buf[4]=rest; - memcpy(buf+5+rest, pes, len); - return p2ts->cb(p2ts->priv, buf); -} -EXPORT_SYMBOL(dvb_filter_pes2ts); diff --git a/drivers/media/dvb/dvb-core/dvb_filter.h b/drivers/media/dvb/dvb-core/dvb_filter.h deleted file mode 100644 index 375e3be184b..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_filter.h +++ /dev/null @@ -1,246 +0,0 @@ -/* - * dvb_filter.h - * - * Copyright (C) 2003 Convergence GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _DVB_FILTER_H_ -#define _DVB_FILTER_H_ - -#include <linux/slab.h> - -#include "demux.h" - -typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *); - -struct dvb_filter_pes2ts { - unsigned char buf[188]; - unsigned char cc; - dvb_filter_pes2ts_cb_t *cb; - void *priv; -}; - -void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, - dvb_filter_pes2ts_cb_t *cb, void *priv); - -int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, - int len, int payload_start); - - -#define PROG_STREAM_MAP 0xBC -#define PRIVATE_STREAM1 0xBD -#define PADDING_STREAM 0xBE -#define PRIVATE_STREAM2 0xBF -#define AUDIO_STREAM_S 0xC0 -#define AUDIO_STREAM_E 0xDF -#define VIDEO_STREAM_S 0xE0 -#define VIDEO_STREAM_E 0xEF -#define ECM_STREAM 0xF0 -#define EMM_STREAM 0xF1 -#define DSM_CC_STREAM 0xF2 -#define ISO13522_STREAM 0xF3 -#define PROG_STREAM_DIR 0xFF - -#define DVB_PICTURE_START 0x00 -#define DVB_USER_START 0xb2 -#define DVB_SEQUENCE_HEADER 0xb3 -#define DVB_SEQUENCE_ERROR 0xb4 -#define DVB_EXTENSION_START 0xb5 -#define DVB_SEQUENCE_END 0xb7 -#define DVB_GOP_START 0xb8 -#define DVB_EXCEPT_SLICE 0xb0 - -#define SEQUENCE_EXTENSION 0x01 -#define SEQUENCE_DISPLAY_EXTENSION 0x02 -#define PICTURE_CODING_EXTENSION 0x08 -#define QUANT_MATRIX_EXTENSION 0x03 -#define PICTURE_DISPLAY_EXTENSION 0x07 - -#define I_FRAME 0x01 -#define B_FRAME 0x02 -#define P_FRAME 0x03 - -/* Initialize sequence_data */ -#define INIT_HORIZONTAL_SIZE 720 -#define INIT_VERTICAL_SIZE 576 -#define INIT_ASPECT_RATIO 0x02 -#define INIT_FRAME_RATE 0x03 -#define INIT_DISP_HORIZONTAL_SIZE 540 -#define INIT_DISP_VERTICAL_SIZE 576 - - -//flags2 -#define PTS_DTS_FLAGS 0xC0 -#define ESCR_FLAG 0x20 -#define ES_RATE_FLAG 0x10 -#define DSM_TRICK_FLAG 0x08 -#define ADD_CPY_FLAG 0x04 -#define PES_CRC_FLAG 0x02 -#define PES_EXT_FLAG 0x01 - -//pts_dts flags -#define PTS_ONLY 0x80 -#define PTS_DTS 0xC0 - -#define TS_SIZE 188 -#define TRANS_ERROR 0x80 -#define PAY_START 0x40 -#define TRANS_PRIO 0x20 -#define PID_MASK_HI 0x1F -//flags -#define TRANS_SCRMBL1 0x80 -#define TRANS_SCRMBL2 0x40 -#define ADAPT_FIELD 0x20 -#define PAYLOAD 0x10 -#define COUNT_MASK 0x0F - -// adaptation flags -#define DISCON_IND 0x80 -#define RAND_ACC_IND 0x40 -#define ES_PRI_IND 0x20 -#define PCR_FLAG 0x10 -#define OPCR_FLAG 0x08 -#define SPLICE_FLAG 0x04 -#define TRANS_PRIV 0x02 -#define ADAP_EXT_FLAG 0x01 - -// adaptation extension flags -#define LTW_FLAG 0x80 -#define PIECE_RATE 0x40 -#define SEAM_SPLICE 0x20 - - -#define MAX_PLENGTH 0xFFFF -#define MMAX_PLENGTH (256*MAX_PLENGTH) - -#ifndef IPACKS -#define IPACKS 2048 -#endif - -struct ipack { - int size; - int found; - u8 *buf; - u8 cid; - u32 plength; - u8 plen[2]; - u8 flag1; - u8 flag2; - u8 hlength; - u8 pts[5]; - u16 *pid; - int mpeg; - u8 check; - int which; - int done; - void *data; - void (*func)(u8 *buf, int size, void *priv); - int count; - int repack_subids; -}; - -struct dvb_video_info { - u32 horizontal_size; - u32 vertical_size; - u32 aspect_ratio; - u32 framerate; - u32 video_format; - u32 bit_rate; - u32 comp_bit_rate; - u32 vbv_buffer_size; - s16 vbv_delay; - u32 CSPF; - u32 off; -}; - -#define OFF_SIZE 4 -#define FIRST_FIELD 0 -#define SECOND_FIELD 1 -#define VIDEO_FRAME_PICTURE 0x03 - -struct mpg_picture { - int channel; - struct dvb_video_info vinfo; - u32 *sequence_gop_header; - u32 *picture_header; - s32 time_code; - int low_delay; - int closed_gop; - int broken_link; - int sequence_header_flag; - int gop_flag; - int sequence_end_flag; - - u8 profile_and_level; - s32 picture_coding_parameter; - u32 matrix[32]; - s8 matrix_change_flag; - - u8 picture_header_parameter; - /* bit 0 - 2: bwd f code - bit 3 : fpb vector - bit 4 - 6: fwd f code - bit 7 : fpf vector */ - - int mpeg1_flag; - int progressive_sequence; - int sequence_display_extension_flag; - u32 sequence_header_data; - s16 last_frame_centre_horizontal_offset; - s16 last_frame_centre_vertical_offset; - - u32 pts[2]; /* [0] 1st field, [1] 2nd field */ - int top_field_first; - int repeat_first_field; - int progressive_frame; - int bank; - int forward_bank; - int backward_bank; - int compress; - s16 frame_centre_horizontal_offset[OFF_SIZE]; - /* [0-2] 1st field, [3] 2nd field */ - s16 frame_centre_vertical_offset[OFF_SIZE]; - /* [0-2] 1st field, [3] 2nd field */ - s16 temporal_reference[2]; - /* [0] 1st field, [1] 2nd field */ - - s8 picture_coding_type[2]; - /* [0] 1st field, [1] 2nd field */ - s8 picture_structure[2]; - /* [0] 1st field, [1] 2nd field */ - s8 picture_display_extension_flag[2]; - /* [0] 1st field, [1] 2nd field */ - /* picture_display_extenion() 0:no 1:exit*/ - s8 pts_flag[2]; - /* [0] 1st field, [1] 2nd field */ -}; - -struct dvb_audio_info { - int layer; - u32 bit_rate; - u32 frequency; - u32 mode; - u32 mode_extension ; - u32 emphasis; - u32 framesize; - u32 off; -}; - -int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr); - - -#endif diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c deleted file mode 100644 index 84340778508..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ /dev/null @@ -1,1988 +0,0 @@ -/* - * dvb_frontend.c: DVB frontend tuning interface/thread - * - * - * Copyright (C) 1999-2001 Ralph Metzler - * Marcus Metzler - * Holger Waechtler - * for convergence integrated media GmbH - * - * Copyright (C) 2004 Andrew de Quincey (tuning thread cleanup) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/slab.h> -#include <linux/poll.h> -#include <linux/module.h> -#include <linux/list.h> -#include <linux/freezer.h> -#include <linux/jiffies.h> -#include <linux/kthread.h> -#include <asm/processor.h> - -#include "dvb_frontend.h" -#include "dvbdev.h" -#include <linux/dvb/version.h> - -static int dvb_frontend_debug; -static int dvb_shutdown_timeout; -static int dvb_force_auto_inversion; -static int dvb_override_tune_delay; -static int dvb_powerdown_on_sleep = 1; -static int dvb_mfe_wait_time = 5; - -module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); -MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); -module_param(dvb_shutdown_timeout, int, 0644); -MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); -module_param(dvb_force_auto_inversion, int, 0644); -MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); -module_param(dvb_override_tune_delay, int, 0644); -MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); -module_param(dvb_powerdown_on_sleep, int, 0644); -MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)"); -module_param(dvb_mfe_wait_time, int, 0644); -MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)"); - -#define dprintk if (dvb_frontend_debug) printk - -#define FESTATE_IDLE 1 -#define FESTATE_RETUNE 2 -#define FESTATE_TUNING_FAST 4 -#define FESTATE_TUNING_SLOW 8 -#define FESTATE_TUNED 16 -#define FESTATE_ZIGZAG_FAST 32 -#define FESTATE_ZIGZAG_SLOW 64 -#define FESTATE_DISEQC 128 -#define FESTATE_WAITFORLOCK (FESTATE_TUNING_FAST | FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW | FESTATE_DISEQC) -#define FESTATE_SEARCHING_FAST (FESTATE_TUNING_FAST | FESTATE_ZIGZAG_FAST) -#define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) -#define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) - -#define FE_ALGO_HW 1 -/* - * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. - * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. - * FESTATE_TUNING_FAST. Tuning parameters have been supplied and fast zigzag scan is in progress. - * FESTATE_TUNING_SLOW. Tuning parameters have been supplied. Fast zigzag failed, so we're trying again, but slower. - * FESTATE_TUNED. The frontend has successfully locked on. - * FESTATE_ZIGZAG_FAST. The lock has been lost, and a fast zigzag has been initiated to try and regain it. - * FESTATE_ZIGZAG_SLOW. The lock has been lost. Fast zigzag has been failed, so we're trying again, but slower. - * FESTATE_DISEQC. A DISEQC command has just been issued. - * FESTATE_WAITFORLOCK. When we're waiting for a lock. - * FESTATE_SEARCHING_FAST. When we're searching for a signal using a fast zigzag scan. - * FESTATE_SEARCHING_SLOW. When we're searching for a signal using a slow zigzag scan. - * FESTATE_LOSTLOCK. When the lock has been lost, and we're searching it again. - */ - -static DEFINE_MUTEX(frontend_mutex); - -struct dvb_frontend_private { - - /* thread/frontend values */ - struct dvb_device *dvbdev; - struct dvb_frontend_parameters parameters; - struct dvb_fe_events events; - struct semaphore sem; - struct list_head list_head; - wait_queue_head_t wait_queue; - struct task_struct *thread; - unsigned long release_jiffies; - unsigned int exit; - unsigned int wakeup; - fe_status_t status; - unsigned long tune_mode_flags; - unsigned int delay; - unsigned int reinitialise; - int tone; - int voltage; - - /* swzigzag values */ - unsigned int state; - unsigned int bending; - int lnb_drift; - unsigned int inversion; - unsigned int auto_step; - unsigned int auto_sub_step; - unsigned int started_auto_step; - unsigned int min_delay; - unsigned int max_drift; - unsigned int step_size; - int quality; - unsigned int check_wrapped; - enum dvbfe_search algo_status; -}; - -static void dvb_frontend_wakeup(struct dvb_frontend *fe); - -static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_fe_events *events = &fepriv->events; - struct dvb_frontend_event *e; - int wp; - - dprintk ("%s\n", __func__); - - if (mutex_lock_interruptible (&events->mtx)) - return; - - 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]; - - memcpy (&e->parameters, &fepriv->parameters, - sizeof (struct dvb_frontend_parameters)); - - if (status & FE_HAS_LOCK) - if (fe->ops.get_frontend) - fe->ops.get_frontend(fe, &e->parameters); - - events->eventw = wp; - - mutex_unlock(&events->mtx); - - e->status = status; - - wake_up_interruptible (&events->wait_queue); -} - -static int dvb_frontend_get_event(struct dvb_frontend *fe, - struct dvb_frontend_event *event, int flags) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_fe_events *events = &fepriv->events; - - dprintk ("%s\n", __func__); - - if (events->overflow) { - events->overflow = 0; - return -EOVERFLOW; - } - - if (events->eventw == events->eventr) { - int ret; - - if (flags & O_NONBLOCK) - return -EWOULDBLOCK; - - up(&fepriv->sem); - - ret = wait_event_interruptible (events->wait_queue, - events->eventw != events->eventr); - - if (down_interruptible (&fepriv->sem)) - return -ERESTARTSYS; - - if (ret < 0) - return ret; - } - - if (mutex_lock_interruptible (&events->mtx)) - return -ERESTARTSYS; - - memcpy (event, &events->events[events->eventr], - sizeof(struct dvb_frontend_event)); - - events->eventr = (events->eventr + 1) % MAX_EVENT; - - mutex_unlock(&events->mtx); - - return 0; -} - -static void dvb_frontend_init(struct dvb_frontend *fe) -{ - dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n", - fe->dvb->num, - fe->id, - fe->ops.info.name); - - if (fe->ops.init) - fe->ops.init(fe); - if (fe->ops.tuner_ops.init) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.init(fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } -} - -void dvb_frontend_reinitialise(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - fepriv->reinitialise = 1; - dvb_frontend_wakeup(fe); -} -EXPORT_SYMBOL(dvb_frontend_reinitialise); - -static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) -{ - int q2; - - dprintk ("%s\n", __func__); - - if (locked) - (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; - else - (fepriv->quality) = (fepriv->quality * 220 + 0) / 256; - - q2 = fepriv->quality - 128; - q2 *= q2; - - fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128); -} - -/** - * Performs automatic twiddling of frontend parameters. - * - * @param fe The frontend concerned. - * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT - * @returns Number of complete iterations that have been performed. - */ -static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped) -{ - int autoinversion; - int ready = 0; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - int original_inversion = fepriv->parameters.inversion; - u32 original_frequency = fepriv->parameters.frequency; - - /* are we using autoinversion? */ - autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && - (fepriv->parameters.inversion == INVERSION_AUTO)); - - /* setup parameters correctly */ - while(!ready) { - /* calculate the lnb_drift */ - fepriv->lnb_drift = fepriv->auto_step * fepriv->step_size; - - /* wrap the auto_step if we've exceeded the maximum drift */ - if (fepriv->lnb_drift > fepriv->max_drift) { - fepriv->auto_step = 0; - fepriv->auto_sub_step = 0; - fepriv->lnb_drift = 0; - } - - /* perform inversion and +/- zigzag */ - switch(fepriv->auto_sub_step) { - case 0: - /* try with the current inversion and current drift setting */ - ready = 1; - break; - - case 1: - if (!autoinversion) break; - - fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF; - ready = 1; - break; - - case 2: - if (fepriv->lnb_drift == 0) break; - - fepriv->lnb_drift = -fepriv->lnb_drift; - ready = 1; - break; - - case 3: - if (fepriv->lnb_drift == 0) break; - if (!autoinversion) break; - - fepriv->inversion = (fepriv->inversion == INVERSION_OFF) ? INVERSION_ON : INVERSION_OFF; - fepriv->lnb_drift = -fepriv->lnb_drift; - ready = 1; - break; - - default: - fepriv->auto_step++; - fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */ - break; - } - - if (!ready) fepriv->auto_sub_step++; - } - - /* if this attempt would hit where we started, indicate a complete - * iteration has occurred */ - if ((fepriv->auto_step == fepriv->started_auto_step) && - (fepriv->auto_sub_step == 0) && check_wrapped) { - return 1; - } - - dprintk("%s: drift:%i inversion:%i auto_step:%i " - "auto_sub_step:%i started_auto_step:%i\n", - __func__, fepriv->lnb_drift, fepriv->inversion, - fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step); - - /* set the frontend itself */ - fepriv->parameters.frequency += fepriv->lnb_drift; - if (autoinversion) - fepriv->parameters.inversion = fepriv->inversion; - if (fe->ops.set_frontend) - fe->ops.set_frontend(fe, &fepriv->parameters); - - fepriv->parameters.frequency = original_frequency; - fepriv->parameters.inversion = original_inversion; - - fepriv->auto_sub_step++; - return 0; -} - -static void dvb_frontend_swzigzag(struct dvb_frontend *fe) -{ - fe_status_t s = 0; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - /* if we've got no parameters, just keep idling */ - if (fepriv->state & FESTATE_IDLE) { - fepriv->delay = 3*HZ; - fepriv->quality = 0; - return; - } - - /* in SCAN mode, we just set the frontend when asked and leave it alone */ - if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { - if (fepriv->state & FESTATE_RETUNE) { - if (fe->ops.set_frontend) - fe->ops.set_frontend(fe, &fepriv->parameters); - fepriv->state = FESTATE_TUNED; - } - fepriv->delay = 3*HZ; - fepriv->quality = 0; - return; - } - - /* get the frontend status */ - if (fepriv->state & FESTATE_RETUNE) { - s = 0; - } else { - if (fe->ops.read_status) - fe->ops.read_status(fe, &s); - if (s != fepriv->status) { - dvb_frontend_add_event(fe, s); - fepriv->status = s; - } - } - - /* if we're not tuned, and we have a lock, move to the TUNED state */ - if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - fepriv->state = FESTATE_TUNED; - - /* if we're tuned, then we have determined the correct inversion */ - if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) && - (fepriv->parameters.inversion == INVERSION_AUTO)) { - fepriv->parameters.inversion = fepriv->inversion; - } - return; - } - - /* if we are tuned already, check we're still locked */ - if (fepriv->state & FESTATE_TUNED) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - - /* we're tuned, and the lock is still good... */ - if (s & FE_HAS_LOCK) { - return; - } else { /* if we _WERE_ tuned, but now don't have a lock */ - fepriv->state = FESTATE_ZIGZAG_FAST; - fepriv->started_auto_step = fepriv->auto_step; - fepriv->check_wrapped = 0; - } - } - - /* don't actually do anything if we're in the LOSTLOCK state, - * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ - if ((fepriv->state & FESTATE_LOSTLOCK) && - (fe->ops.info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - return; - } - - /* don't do anything if we're in the DISEQC state, since this - * might be someone with a motorized dish controlled by DISEQC. - * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ - if (fepriv->state & FESTATE_DISEQC) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - return; - } - - /* if we're in the RETUNE state, set everything up for a brand - * new scan, keeping the current inversion setting, as the next - * tune is _very_ likely to require the same */ - if (fepriv->state & FESTATE_RETUNE) { - fepriv->lnb_drift = 0; - fepriv->auto_step = 0; - fepriv->auto_sub_step = 0; - fepriv->started_auto_step = 0; - fepriv->check_wrapped = 0; - } - - /* fast zigzag. */ - if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { - fepriv->delay = fepriv->min_delay; - - /* peform a tune */ - if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { - /* OK, if we've run out of trials at the fast speed. - * Drop back to slow for the _next_ attempt */ - fepriv->state = FESTATE_SEARCHING_SLOW; - fepriv->started_auto_step = fepriv->auto_step; - return; - } - fepriv->check_wrapped = 1; - - /* if we've just retuned, enter the ZIGZAG_FAST state. - * This ensures we cannot return from an - * FE_SET_FRONTEND ioctl before the first frontend tune - * occurs */ - if (fepriv->state & FESTATE_RETUNE) { - fepriv->state = FESTATE_TUNING_FAST; - } - } - - /* slow zigzag */ - if (fepriv->state & FESTATE_SEARCHING_SLOW) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - - /* Note: don't bother checking for wrapping; we stay in this - * state until we get a lock */ - dvb_frontend_swzigzag_autotune(fe, 0); - } -} - -static int dvb_frontend_is_exiting(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - if (fepriv->exit) - return 1; - - if (fepriv->dvbdev->writers == 1) - if (time_after(jiffies, fepriv->release_jiffies + - dvb_shutdown_timeout * HZ)) - return 1; - - return 0; -} - -static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - if (fepriv->wakeup) { - fepriv->wakeup = 0; - return 1; - } - return dvb_frontend_is_exiting(fe); -} - -static void dvb_frontend_wakeup(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - fepriv->wakeup = 1; - wake_up_interruptible(&fepriv->wait_queue); -} - -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; - - struct dvb_frontend_parameters *params; - - dprintk("%s\n", __func__); - - fepriv->check_wrapped = 0; - fepriv->quality = 0; - fepriv->delay = 3*HZ; - fepriv->status = 0; - fepriv->wakeup = 0; - fepriv->reinitialise = 0; - - dvb_frontend_init(fe); - - set_freezable(); - while (1) { - up(&fepriv->sem); /* is locked when we enter the thread... */ -restart: - timeout = wait_event_interruptible_timeout(fepriv->wait_queue, - dvb_frontend_should_wakeup(fe) || kthread_should_stop() - || freezing(current), - fepriv->delay); - - if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { - /* got signal or quitting */ - break; - } - - if (try_to_freeze()) - goto restart; - - if (down_interruptible(&fepriv->sem)) - break; - - if (fepriv->reinitialise) { - dvb_frontend_init(fe); - if (fepriv->tone != -1) { - fe->ops.set_tone(fe, fepriv->tone); - } - if (fepriv->voltage != -1) { - fe->ops.set_voltage(fe, fepriv->voltage); - } - fepriv->reinitialise = 0; - } - - /* do an iteration of the tuning loop */ - if (fe->ops.get_frontend_algo) { - algo = fe->ops.get_frontend_algo(fe); - switch (algo) { - case DVBFE_ALGO_HW: - dprintk("%s: Frontend ALGO = DVBFE_ALGO_HW\n", __func__); - params = NULL; /* have we been asked to RETUNE ? */ - - if (fepriv->state & FESTATE_RETUNE) { - dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__); - params = &fepriv->parameters; - fepriv->state = FESTATE_TUNED; - } - - if (fe->ops.tune) - fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); - - if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) { - dprintk("%s: state changed, adding current state\n", __func__); - dvb_frontend_add_event(fe, s); - fepriv->status = s; - } - break; - case DVBFE_ALGO_SW: - dprintk("%s: Frontend ALGO = DVBFE_ALGO_SW\n", __func__); - dvb_frontend_swzigzag(fe); - break; - case DVBFE_ALGO_CUSTOM: - params = NULL; /* have we been asked to RETUNE ? */ - dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state); - if (fepriv->state & FESTATE_RETUNE) { - dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__); - params = &fepriv->parameters; - fepriv->state = FESTATE_TUNED; - } - /* Case where we are going to search for a carrier - * User asked us to retune again for some reason, possibly - * requesting a search with a new set of parameters - */ - if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) { - if (fe->ops.search) { - fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters); - /* We did do a search as was requested, the flags are - * now unset as well and has the flags wrt to search. - */ - } else { - fepriv->algo_status &= ~DVBFE_ALGO_SEARCH_AGAIN; - } - } - /* Track the carrier if the search was successful */ - if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) { - if (fe->ops.track) - fe->ops.track(fe, &fepriv->parameters); - } else { - fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; - fepriv->delay = HZ / 2; - } - fe->ops.read_status(fe, &s); - if (s != fepriv->status) { - dvb_frontend_add_event(fe, s); /* update event list */ - fepriv->status = s; - if (!(s & FE_HAS_LOCK)) { - fepriv->delay = HZ / 10; - fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; - } else { - fepriv->delay = 60 * HZ; - } - } - break; - default: - dprintk("%s: UNDEFINED ALGO !\n", __func__); - break; - } - } else { - dvb_frontend_swzigzag(fe); - } - } - - if (dvb_powerdown_on_sleep) { - if (fe->ops.set_voltage) - fe->ops.set_voltage(fe, SEC_VOLTAGE_OFF); - if (fe->ops.tuner_ops.sleep) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.sleep(fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.sleep) - fe->ops.sleep(fe); - } - - fepriv->thread = NULL; - mb(); - - dvb_frontend_wakeup(fe); - return 0; -} - -static void dvb_frontend_stop(struct dvb_frontend *fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - dprintk ("%s\n", __func__); - - fepriv->exit = 1; - mb(); - - if (!fepriv->thread) - return; - - kthread_stop(fepriv->thread); - - init_MUTEX (&fepriv->sem); - fepriv->state = FESTATE_IDLE; - - /* paranoia check in case a signal arrived */ - if (fepriv->thread) - printk("dvb_frontend_stop: warning: thread %p won't exit\n", - fepriv->thread); -} - -s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) -{ - return ((curtime.tv_usec < lasttime.tv_usec) ? - 1000000 - lasttime.tv_usec + curtime.tv_usec : - curtime.tv_usec - lasttime.tv_usec); -} -EXPORT_SYMBOL(timeval_usec_diff); - -static inline void timeval_usec_add(struct timeval *curtime, u32 add_usec) -{ - curtime->tv_usec += add_usec; - if (curtime->tv_usec >= 1000000) { - curtime->tv_usec -= 1000000; - curtime->tv_sec++; - } -} - -/* - * Sleep until gettimeofday() > waketime + add_usec - * This needs to be as precise as possible, but as the delay is - * usually between 2ms and 32ms, it is done using a scheduled msleep - * followed by usleep (normally a busy-wait loop) for the remainder - */ -void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec) -{ - struct timeval lasttime; - s32 delta, newdelta; - - timeval_usec_add(waketime, add_usec); - - do_gettimeofday(&lasttime); - delta = timeval_usec_diff(lasttime, *waketime); - if (delta > 2500) { - msleep((delta - 1500) / 1000); - do_gettimeofday(&lasttime); - newdelta = timeval_usec_diff(lasttime, *waketime); - delta = (newdelta > delta) ? 0 : newdelta; - } - if (delta > 0) - udelay(delta); -} -EXPORT_SYMBOL(dvb_frontend_sleep_until); - -static int dvb_frontend_start(struct dvb_frontend *fe) -{ - int ret; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct task_struct *fe_thread; - - dprintk ("%s\n", __func__); - - if (fepriv->thread) { - if (!fepriv->exit) - return 0; - else - dvb_frontend_stop (fe); - } - - if (signal_pending(current)) - return -EINTR; - if (down_interruptible (&fepriv->sem)) - return -EINTR; - - fepriv->state = FESTATE_IDLE; - fepriv->exit = 0; - fepriv->thread = NULL; - mb(); - - fe_thread = kthread_run(dvb_frontend_thread, fe, - "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id); - if (IS_ERR(fe_thread)) { - ret = PTR_ERR(fe_thread); - printk("dvb_frontend_start: failed to start kthread (%d)\n", ret); - up(&fepriv->sem); - return ret; - } - fepriv->thread = fe_thread; - return 0; -} - -static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe, - u32 *freq_min, u32 *freq_max) -{ - *freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min); - - if (fe->ops.info.frequency_max == 0) - *freq_max = fe->ops.tuner_ops.info.frequency_max; - else if (fe->ops.tuner_ops.info.frequency_max == 0) - *freq_max = fe->ops.info.frequency_max; - else - *freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max); - - if (*freq_min == 0 || *freq_max == 0) - printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n", - fe->dvb->num,fe->id); -} - -static int dvb_frontend_check_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *parms) -{ - u32 freq_min; - u32 freq_max; - - /* range check: frequency */ - dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max); - if ((freq_min && parms->frequency < freq_min) || - (freq_max && parms->frequency > freq_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max); - return -EINVAL; - } - - /* range check: symbol rate */ - if (fe->ops.info.type == FE_QPSK) { - if ((fe->ops.info.symbol_rate_min && - parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || - (fe->ops.info.symbol_rate_max && - parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate, - fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); - return -EINVAL; - } - - } else if (fe->ops.info.type == FE_QAM) { - if ((fe->ops.info.symbol_rate_min && - parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) || - (fe->ops.info.symbol_rate_max && - parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) { - printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n", - fe->dvb->num, fe->id, parms->u.qam.symbol_rate, - fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max); - return -EINVAL; - } - } - - return 0; -} - -static struct dtv_cmds_h dtv_cmds[] = { - [DTV_TUNE] = { - .name = "DTV_TUNE", - .cmd = DTV_TUNE, - .set = 1, - }, - [DTV_CLEAR] = { - .name = "DTV_CLEAR", - .cmd = DTV_CLEAR, - .set = 1, - }, - - /* Set */ - [DTV_FREQUENCY] = { - .name = "DTV_FREQUENCY", - .cmd = DTV_FREQUENCY, - .set = 1, - }, - [DTV_BANDWIDTH_HZ] = { - .name = "DTV_BANDWIDTH_HZ", - .cmd = DTV_BANDWIDTH_HZ, - .set = 1, - }, - [DTV_MODULATION] = { - .name = "DTV_MODULATION", - .cmd = DTV_MODULATION, - .set = 1, - }, - [DTV_INVERSION] = { - .name = "DTV_INVERSION", - .cmd = DTV_INVERSION, - .set = 1, - }, - [DTV_DISEQC_MASTER] = { - .name = "DTV_DISEQC_MASTER", - .cmd = DTV_DISEQC_MASTER, - .set = 1, - .buffer = 1, - }, - [DTV_SYMBOL_RATE] = { - .name = "DTV_SYMBOL_RATE", - .cmd = DTV_SYMBOL_RATE, - .set = 1, - }, - [DTV_INNER_FEC] = { - .name = "DTV_INNER_FEC", - .cmd = DTV_INNER_FEC, - .set = 1, - }, - [DTV_VOLTAGE] = { - .name = "DTV_VOLTAGE", - .cmd = DTV_VOLTAGE, - .set = 1, - }, - [DTV_TONE] = { - .name = "DTV_TONE", - .cmd = DTV_TONE, - .set = 1, - }, - [DTV_PILOT] = { - .name = "DTV_PILOT", - .cmd = DTV_PILOT, - .set = 1, - }, - [DTV_ROLLOFF] = { - .name = "DTV_ROLLOFF", - .cmd = DTV_ROLLOFF, - .set = 1, - }, - [DTV_DELIVERY_SYSTEM] = { - .name = "DTV_DELIVERY_SYSTEM", - .cmd = DTV_DELIVERY_SYSTEM, - .set = 1, - }, - [DTV_HIERARCHY] = { - .name = "DTV_HIERARCHY", - .cmd = DTV_HIERARCHY, - .set = 1, - }, - [DTV_CODE_RATE_HP] = { - .name = "DTV_CODE_RATE_HP", - .cmd = DTV_CODE_RATE_HP, - .set = 1, - }, - [DTV_CODE_RATE_LP] = { - .name = "DTV_CODE_RATE_LP", - .cmd = DTV_CODE_RATE_LP, - .set = 1, - }, - [DTV_GUARD_INTERVAL] = { - .name = "DTV_GUARD_INTERVAL", - .cmd = DTV_GUARD_INTERVAL, - .set = 1, - }, - [DTV_TRANSMISSION_MODE] = { - .name = "DTV_TRANSMISSION_MODE", - .cmd = DTV_TRANSMISSION_MODE, - .set = 1, - }, - /* Get */ - [DTV_DISEQC_SLAVE_REPLY] = { - .name = "DTV_DISEQC_SLAVE_REPLY", - .cmd = DTV_DISEQC_SLAVE_REPLY, - .set = 0, - .buffer = 1, - }, - [DTV_API_VERSION] = { - .name = "DTV_API_VERSION", - .cmd = DTV_API_VERSION, - .set = 0, - }, - [DTV_CODE_RATE_HP] = { - .name = "DTV_CODE_RATE_HP", - .cmd = DTV_CODE_RATE_HP, - .set = 0, - }, - [DTV_CODE_RATE_LP] = { - .name = "DTV_CODE_RATE_LP", - .cmd = DTV_CODE_RATE_LP, - .set = 0, - }, - [DTV_GUARD_INTERVAL] = { - .name = "DTV_GUARD_INTERVAL", - .cmd = DTV_GUARD_INTERVAL, - .set = 0, - }, - [DTV_TRANSMISSION_MODE] = { - .name = "DTV_TRANSMISSION_MODE", - .cmd = DTV_TRANSMISSION_MODE, - .set = 0, - }, - [DTV_HIERARCHY] = { - .name = "DTV_HIERARCHY", - .cmd = DTV_HIERARCHY, - .set = 0, - }, -}; - -static void dtv_property_dump(struct dtv_property *tvp) -{ - int i; - - if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) { - printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n", - __func__, tvp->cmd); - return; - } - - dprintk("%s() tvp.cmd = 0x%08x (%s)\n" - ,__func__ - ,tvp->cmd - ,dtv_cmds[ tvp->cmd ].name); - - if(dtv_cmds[ tvp->cmd ].buffer) { - - dprintk("%s() tvp.u.buffer.len = 0x%02x\n" - ,__func__ - ,tvp->u.buffer.len); - - for(i = 0; i < tvp->u.buffer.len; i++) - dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n" - ,__func__ - ,i - ,tvp->u.buffer.data[i]); - - } else - dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data); -} - -static int is_legacy_delivery_system(fe_delivery_system_t s) -{ - if((s == SYS_UNDEFINED) || (s == SYS_DVBC_ANNEX_AC) || - (s == SYS_DVBC_ANNEX_B) || (s == SYS_DVBT) || (s == SYS_DVBS) || - (s == SYS_ATSC)) - return 1; - - return 0; -} - -/* 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. - */ -static void dtv_property_cache_sync(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - c->frequency = p->frequency; - c->inversion = p->inversion; - - 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) - c->bandwidth_hz = 6000000; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - c->bandwidth_hz = 7000000; - else if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - c->bandwidth_hz = 8000000; - else - /* Including BANDWIDTH_AUTO */ - c->bandwidth_hz = 0; - c->code_rate_HP = p->u.ofdm.code_rate_HP; - c->code_rate_LP = p->u.ofdm.code_rate_LP; - c->modulation = p->u.ofdm.constellation; - 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; - if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) - c->delivery_system = SYS_ATSC; - else - c->delivery_system = SYS_DVBC_ANNEX_B; - break; - } -} - -/* Ensure the cached values are set correctly in the frontend - * legacy tuning structures, for the advanced tuning API. - */ -static void dtv_property_legacy_params_sync(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters *p = &fepriv->parameters; - - p->frequency = c->frequency; - p->inversion = c->inversion; - - switch (fe->ops.info.type) { - case FE_QPSK: - dprintk("%s() Preparing QPSK req\n", __func__); - p->u.qpsk.symbol_rate = c->symbol_rate; - p->u.qpsk.fec_inner = c->fec_inner; - c->delivery_system = SYS_DVBS; - break; - case FE_QAM: - dprintk("%s() Preparing QAM req\n", __func__); - p->u.qam.symbol_rate = c->symbol_rate; - p->u.qam.fec_inner = c->fec_inner; - p->u.qam.modulation = c->modulation; - c->delivery_system = SYS_DVBC_ANNEX_AC; - break; - case FE_OFDM: - dprintk("%s() Preparing OFDM req\n", __func__); - if (c->bandwidth_hz == 6000000) - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - else if (c->bandwidth_hz == 7000000) - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - else if (c->bandwidth_hz == 8000000) - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - else - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; - p->u.ofdm.code_rate_HP = c->code_rate_HP; - p->u.ofdm.code_rate_LP = c->code_rate_LP; - p->u.ofdm.constellation = c->modulation; - p->u.ofdm.transmission_mode = c->transmission_mode; - p->u.ofdm.guard_interval = c->guard_interval; - p->u.ofdm.hierarchy_information = c->hierarchy; - c->delivery_system = SYS_DVBT; - break; - case FE_ATSC: - dprintk("%s() Preparing VSB req\n", __func__); - p->u.vsb.modulation = c->modulation; - if ((c->modulation == VSB_8) || (c->modulation == VSB_16)) - c->delivery_system = SYS_ATSC; - else - c->delivery_system = SYS_DVBC_ANNEX_B; - break; - } -} - -/* Ensure the cached values are set correctly in the frontend - * legacy tuning structures, for the legacy tuning API. - */ -static void dtv_property_adv_params_sync(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_frontend_parameters *p = &fepriv->parameters; - - p->frequency = c->frequency; - p->inversion = c->inversion; - - switch(c->modulation) { - case PSK_8: - case APSK_16: - case APSK_32: - case QPSK: - p->u.qpsk.symbol_rate = c->symbol_rate; - p->u.qpsk.fec_inner = c->fec_inner; - break; - default: - break; - } - - if(c->delivery_system == SYS_ISDBT) { - /* Fake out a generic DVB-T request so we pass validation in the ioctl */ - p->frequency = c->frequency; - p->inversion = INVERSION_AUTO; - p->u.ofdm.constellation = QAM_AUTO; - p->u.ofdm.code_rate_HP = FEC_AUTO; - p->u.ofdm.code_rate_LP = FEC_AUTO; - p->u.ofdm.bandwidth = BANDWIDTH_AUTO; - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; - } -} - -static void dtv_property_cache_submit(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - /* For legacy delivery systems we don't need the delivery_system to - * be specified, but we populate the older structures from the cache - * so we can call set_frontend on older drivers. - */ - if(is_legacy_delivery_system(c->delivery_system)) { - - dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation); - dtv_property_legacy_params_sync(fe); - - } else { - dprintk("%s() adv, modulation = %d\n", __func__, c->modulation); - - /* For advanced delivery systems / modulation types ... - * we seed the lecacy dvb_frontend_parameters structure - * so that the sanity checking code later in the IOCTL processing - * can validate our basic frequency ranges, symbolrates, modulation - * etc. - */ - dtv_property_adv_params_sync(fe); - } -} - -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, - unsigned int cmd, void *parg); -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, - unsigned int cmd, void *parg); - -static int dtv_property_process_get(struct dvb_frontend *fe, - struct dtv_property *tvp, - struct inode *inode, struct file *file) -{ - int r = 0; - - dtv_property_dump(tvp); - - /* Allow the frontend to validate incoming properties */ - if (fe->ops.get_property) - r = fe->ops.get_property(fe, tvp); - - if (r < 0) - return r; - - switch(tvp->cmd) { - case DTV_FREQUENCY: - tvp->u.data = fe->dtv_property_cache.frequency; - break; - case DTV_MODULATION: - tvp->u.data = fe->dtv_property_cache.modulation; - break; - case DTV_BANDWIDTH_HZ: - tvp->u.data = fe->dtv_property_cache.bandwidth_hz; - break; - case DTV_INVERSION: - tvp->u.data = fe->dtv_property_cache.inversion; - break; - case DTV_SYMBOL_RATE: - tvp->u.data = fe->dtv_property_cache.symbol_rate; - break; - case DTV_INNER_FEC: - tvp->u.data = fe->dtv_property_cache.fec_inner; - break; - case DTV_PILOT: - tvp->u.data = fe->dtv_property_cache.pilot; - break; - case DTV_ROLLOFF: - tvp->u.data = fe->dtv_property_cache.rolloff; - break; - case DTV_DELIVERY_SYSTEM: - tvp->u.data = fe->dtv_property_cache.delivery_system; - break; - case DTV_VOLTAGE: - tvp->u.data = fe->dtv_property_cache.voltage; - break; - case DTV_TONE: - tvp->u.data = fe->dtv_property_cache.sectone; - break; - case DTV_API_VERSION: - tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR; - break; - case DTV_CODE_RATE_HP: - tvp->u.data = fe->dtv_property_cache.code_rate_HP; - break; - case DTV_CODE_RATE_LP: - tvp->u.data = fe->dtv_property_cache.code_rate_LP; - break; - case DTV_GUARD_INTERVAL: - tvp->u.data = fe->dtv_property_cache.guard_interval; - break; - case DTV_TRANSMISSION_MODE: - tvp->u.data = fe->dtv_property_cache.transmission_mode; - break; - case DTV_HIERARCHY: - tvp->u.data = fe->dtv_property_cache.hierarchy; - break; - default: - r = -1; - } - - return r; -} - -static int dtv_property_process_set(struct dvb_frontend *fe, - struct dtv_property *tvp, - struct inode *inode, - struct file *file) -{ - int r = 0; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - dtv_property_dump(tvp); - - /* Allow the frontend to validate incoming properties */ - if (fe->ops.set_property) - r = fe->ops.set_property(fe, tvp); - - if (r < 0) - return r; - - switch(tvp->cmd) { - case DTV_CLEAR: - /* Reset a cache of data specific to the frontend here. This does - * not effect hardware. - */ - dprintk("%s() Flushing property cache\n", __func__); - memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties)); - fe->dtv_property_cache.state = tvp->cmd; - fe->dtv_property_cache.delivery_system = SYS_UNDEFINED; - break; - case DTV_TUNE: - /* interpret the cache of data, build either a traditional frontend - * tunerequest so we can pass validation in the FE_SET_FRONTEND - * ioctl. - */ - fe->dtv_property_cache.state = tvp->cmd; - dprintk("%s() Finalised property cache\n", __func__); - dtv_property_cache_submit(fe); - - /* Request the search algorithm to search */ - fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; - - r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND, - &fepriv->parameters); - break; - case DTV_FREQUENCY: - fe->dtv_property_cache.frequency = tvp->u.data; - break; - case DTV_MODULATION: - fe->dtv_property_cache.modulation = tvp->u.data; - break; - case DTV_BANDWIDTH_HZ: - fe->dtv_property_cache.bandwidth_hz = tvp->u.data; - break; - case DTV_INVERSION: - fe->dtv_property_cache.inversion = tvp->u.data; - break; - case DTV_SYMBOL_RATE: - fe->dtv_property_cache.symbol_rate = tvp->u.data; - break; - case DTV_INNER_FEC: - fe->dtv_property_cache.fec_inner = tvp->u.data; - break; - case DTV_PILOT: - fe->dtv_property_cache.pilot = tvp->u.data; - break; - case DTV_ROLLOFF: - fe->dtv_property_cache.rolloff = tvp->u.data; - break; - case DTV_DELIVERY_SYSTEM: - fe->dtv_property_cache.delivery_system = tvp->u.data; - break; - case DTV_VOLTAGE: - fe->dtv_property_cache.voltage = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_VOLTAGE, - (void *)fe->dtv_property_cache.voltage); - break; - case DTV_TONE: - fe->dtv_property_cache.sectone = tvp->u.data; - r = dvb_frontend_ioctl_legacy(inode, file, FE_SET_TONE, - (void *)fe->dtv_property_cache.sectone); - break; - case DTV_CODE_RATE_HP: - fe->dtv_property_cache.code_rate_HP = tvp->u.data; - break; - case DTV_CODE_RATE_LP: - fe->dtv_property_cache.code_rate_LP = tvp->u.data; - break; - case DTV_GUARD_INTERVAL: - fe->dtv_property_cache.guard_interval = tvp->u.data; - break; - case DTV_TRANSMISSION_MODE: - fe->dtv_property_cache.transmission_mode = tvp->u.data; - break; - case DTV_HIERARCHY: - fe->dtv_property_cache.hierarchy = tvp->u.data; - break; - default: - r = -1; - } - - return r; -} - -static int dvb_frontend_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - int err = -EOPNOTSUPP; - - dprintk ("%s\n", __func__); - - if (fepriv->exit) - return -ENODEV; - - if ((file->f_flags & O_ACCMODE) == O_RDONLY && - (_IOC_DIR(cmd) != _IOC_READ || cmd == FE_GET_EVENT || - cmd == FE_DISEQC_RECV_SLAVE_REPLY)) - return -EPERM; - - if (down_interruptible (&fepriv->sem)) - return -ERESTARTSYS; - - if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) - err = dvb_frontend_ioctl_properties(inode, file, cmd, parg); - else { - fe->dtv_property_cache.state = DTV_UNDEFINED; - err = dvb_frontend_ioctl_legacy(inode, file, cmd, parg); - } - - up(&fepriv->sem); - return err; -} - -static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - int err = 0; - - struct dtv_properties *tvps = NULL; - struct dtv_property *tvp = NULL; - int i; - - dprintk("%s\n", __func__); - - if(cmd == FE_SET_PROPERTY) { - tvps = (struct dtv_properties __user *)parg; - - dprintk("%s() properties.num = %d\n", __func__, tvps->num); - dprintk("%s() properties.props = %p\n", __func__, tvps->props); - - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ - if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) - return -EINVAL; - - tvp = (struct dtv_property *) kmalloc(tvps->num * - sizeof(struct dtv_property), GFP_KERNEL); - if (!tvp) { - err = -ENOMEM; - goto out; - } - - if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_set(fe, tvp + i, inode, file); - err |= (tvp + i)->result; - } - - if(fe->dtv_property_cache.state == DTV_TUNE) - dprintk("%s() Property cache is full, tuning\n", __func__); - - } else - if(cmd == FE_GET_PROPERTY) { - - tvps = (struct dtv_properties __user *)parg; - - dprintk("%s() properties.num = %d\n", __func__, tvps->num); - dprintk("%s() properties.props = %p\n", __func__, tvps->props); - - /* Put an arbitrary limit on the number of messages that can - * be sent at once */ - if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) - return -EINVAL; - - tvp = (struct dtv_property *) kmalloc(tvps->num * - sizeof(struct dtv_property), GFP_KERNEL); - if (!tvp) { - err = -ENOMEM; - goto out; - } - - if (copy_from_user(tvp, tvps->props, tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - for (i = 0; i < tvps->num; i++) { - (tvp + i)->result = dtv_property_process_get(fe, tvp + i, inode, file); - err |= (tvp + i)->result; - } - - if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) { - err = -EFAULT; - goto out; - } - - } else - err = -EOPNOTSUPP; - -out: - kfree(tvp); - return err; -} - -static int dvb_frontend_ioctl_legacy(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - int err = -EOPNOTSUPP; - - switch (cmd) { - case FE_GET_INFO: { - struct dvb_frontend_info* info = parg; - memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info)); - dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max); - - /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't - * do it, it is done for it. */ - info->caps |= FE_CAN_INVERSION_AUTO; - err = 0; - break; - } - - case FE_READ_STATUS: { - fe_status_t* status = parg; - - /* if retune was requested but hasn't occured yet, prevent - * that user get signal state from previous tuning */ - if(fepriv->state == FESTATE_RETUNE) { - err=0; - *status = 0; - break; - } - - if (fe->ops.read_status) - err = fe->ops.read_status(fe, status); - break; - } - case FE_READ_BER: - if (fe->ops.read_ber) - err = fe->ops.read_ber(fe, (__u32*) parg); - break; - - case FE_READ_SIGNAL_STRENGTH: - if (fe->ops.read_signal_strength) - err = fe->ops.read_signal_strength(fe, (__u16*) parg); - break; - - case FE_READ_SNR: - if (fe->ops.read_snr) - err = fe->ops.read_snr(fe, (__u16*) parg); - break; - - case FE_READ_UNCORRECTED_BLOCKS: - if (fe->ops.read_ucblocks) - err = fe->ops.read_ucblocks(fe, (__u32*) parg); - break; - - - case FE_DISEQC_RESET_OVERLOAD: - if (fe->ops.diseqc_reset_overload) { - err = fe->ops.diseqc_reset_overload(fe); - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } - break; - - case FE_DISEQC_SEND_MASTER_CMD: - if (fe->ops.diseqc_send_master_cmd) { - err = fe->ops.diseqc_send_master_cmd(fe, (struct dvb_diseqc_master_cmd*) parg); - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } - break; - - case FE_DISEQC_SEND_BURST: - if (fe->ops.diseqc_send_burst) { - err = fe->ops.diseqc_send_burst(fe, (fe_sec_mini_cmd_t) parg); - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } - break; - - case FE_SET_TONE: - if (fe->ops.set_tone) { - err = fe->ops.set_tone(fe, (fe_sec_tone_mode_t) parg); - fepriv->tone = (fe_sec_tone_mode_t) parg; - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } - break; - - case FE_SET_VOLTAGE: - if (fe->ops.set_voltage) { - err = fe->ops.set_voltage(fe, (fe_sec_voltage_t) parg); - fepriv->voltage = (fe_sec_voltage_t) parg; - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } - break; - - case FE_DISHNETWORK_SEND_LEGACY_CMD: - if (fe->ops.dishnetwork_send_legacy_command) { - err = fe->ops.dishnetwork_send_legacy_command(fe, (unsigned long) parg); - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } else if (fe->ops.set_voltage) { - /* - * NOTE: This is a fallback condition. Some frontends - * (stv0299 for instance) take longer than 8msec to - * respond to a set_voltage command. Those switches - * need custom routines to switch properly. For all - * other frontends, the following shoule work ok. - * Dish network legacy switches (as used by Dish500) - * are controlled by sending 9-bit command words - * spaced 8msec apart. - * the actual command word is switch/port dependant - * so it is up to the userspace application to send - * the right command. - * The command must always start with a '0' after - * initialization, so parg is 8 bits and does not - * include the initialization or start bit - */ - unsigned long swcmd = ((unsigned long) parg) << 1; - struct timeval nexttime; - struct timeval tv[10]; - int i; - u8 last = 1; - if (dvb_frontend_debug) - printk("%s switch command: 0x%04lx\n", __func__, swcmd); - do_gettimeofday(&nexttime); - if (dvb_frontend_debug) - memcpy(&tv[0], &nexttime, sizeof(struct timeval)); - /* before sending a command, initialize by sending - * a 32ms 18V to the switch - */ - fe->ops.set_voltage(fe, SEC_VOLTAGE_18); - dvb_frontend_sleep_until(&nexttime, 32000); - - for (i = 0; i < 9; i++) { - if (dvb_frontend_debug) - do_gettimeofday(&tv[i + 1]); - if ((swcmd & 0x01) != last) { - /* set voltage to (last ? 13V : 18V) */ - fe->ops.set_voltage(fe, (last) ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); - last = (last) ? 0 : 1; - } - swcmd = swcmd >> 1; - if (i != 8) - dvb_frontend_sleep_until(&nexttime, 8000); - } - if (dvb_frontend_debug) { - printk("%s(%d): switch delay (should be 32k followed by all 8k\n", - __func__, fe->dvb->num); - for (i = 1; i < 10; i++) - printk("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); - } - err = 0; - fepriv->state = FESTATE_DISEQC; - fepriv->status = 0; - } - break; - - case FE_DISEQC_RECV_SLAVE_REPLY: - if (fe->ops.diseqc_recv_slave_reply) - err = fe->ops.diseqc_recv_slave_reply(fe, (struct dvb_diseqc_slave_reply*) parg); - break; - - case FE_ENABLE_HIGH_LNB_VOLTAGE: - if (fe->ops.enable_high_lnb_voltage) - err = fe->ops.enable_high_lnb_voltage(fe, (long) parg); - break; - - case FE_SET_FRONTEND: { - struct dvb_frontend_tune_settings fetunesettings; - - if(fe->dtv_property_cache.state == DTV_TUNE) { - if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) { - err = -EINVAL; - break; - } - } else { - if (dvb_frontend_check_parameters(fe, parg) < 0) { - err = -EINVAL; - break; - } - - memcpy (&fepriv->parameters, parg, - sizeof (struct dvb_frontend_parameters)); - dtv_property_cache_sync(fe, &fepriv->parameters); - } - - memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); - memcpy(&fetunesettings.parameters, parg, - sizeof (struct dvb_frontend_parameters)); - - /* force auto frequency inversion if requested */ - if (dvb_force_auto_inversion) { - fepriv->parameters.inversion = INVERSION_AUTO; - fetunesettings.parameters.inversion = INVERSION_AUTO; - } - if (fe->ops.info.type == FE_OFDM) { - /* without hierarchical coding code_rate_LP is irrelevant, - * so we tolerate the otherwise invalid FEC_NONE setting */ - if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE && - fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE) - fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO; - } - - /* get frontend-specific tuning settings */ - if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) { - fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000; - fepriv->max_drift = fetunesettings.max_drift; - fepriv->step_size = fetunesettings.step_size; - } else { - /* default values */ - switch(fe->ops.info.type) { - case FE_QPSK: - fepriv->min_delay = HZ/20; - fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000; - fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000; - break; - - case FE_QAM: - fepriv->min_delay = HZ/20; - fepriv->step_size = 0; /* no zigzag */ - fepriv->max_drift = 0; - break; - - case FE_OFDM: - fepriv->min_delay = HZ/20; - fepriv->step_size = fe->ops.info.frequency_stepsize * 2; - fepriv->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1; - break; - case FE_ATSC: - fepriv->min_delay = HZ/20; - fepriv->step_size = 0; - fepriv->max_drift = 0; - break; - } - } - if (dvb_override_tune_delay > 0) - fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000; - - fepriv->state = FESTATE_RETUNE; - dvb_frontend_wakeup(fe); - dvb_frontend_add_event(fe, 0); - fepriv->status = 0; - err = 0; - break; - } - - case FE_GET_EVENT: - err = dvb_frontend_get_event (fe, parg, file->f_flags); - break; - - case FE_GET_FRONTEND: - if (fe->ops.get_frontend) { - memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters)); - err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg); - } - break; - - case FE_SET_FRONTEND_TUNE_MODE: - fepriv->tune_mode_flags = (unsigned long) parg; - err = 0; - break; - }; - - return err; -} - - -static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struct *wait) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - dprintk ("%s\n", __func__); - - poll_wait (file, &fepriv->events.wait_queue, wait); - - if (fepriv->events.eventw != fepriv->events.eventr) - return (POLLIN | POLLRDNORM | POLLPRI); - - return 0; -} - -static int dvb_frontend_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - struct dvb_adapter *adapter = fe->dvb; - int ret; - - dprintk ("%s\n", __func__); - - if (adapter->mfe_shared) { - mutex_lock (&adapter->mfe_lock); - - if (adapter->mfe_dvbdev == NULL) - adapter->mfe_dvbdev = dvbdev; - - else if (adapter->mfe_dvbdev != dvbdev) { - struct dvb_device - *mfedev = adapter->mfe_dvbdev; - struct dvb_frontend - *mfe = mfedev->priv; - struct dvb_frontend_private - *mfepriv = mfe->frontend_priv; - int mferetry = (dvb_mfe_wait_time << 1); - - mutex_unlock (&adapter->mfe_lock); - while (mferetry-- && (mfedev->users != -1 || - mfepriv->thread != NULL)) { - if(msleep_interruptible(500)) { - if(signal_pending(current)) - return -EINTR; - } - } - - mutex_lock (&adapter->mfe_lock); - if(adapter->mfe_dvbdev != dvbdev) { - mfedev = adapter->mfe_dvbdev; - mfe = mfedev->priv; - mfepriv = mfe->frontend_priv; - if (mfedev->users != -1 || - mfepriv->thread != NULL) { - mutex_unlock (&adapter->mfe_lock); - return -EBUSY; - } - adapter->mfe_dvbdev = dvbdev; - } - } - } - - if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { - if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) - goto err0; - } - - if ((ret = dvb_generic_open (inode, file)) < 0) - goto err1; - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - /* normal tune mode when opened R/W */ - fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; - fepriv->tone = -1; - fepriv->voltage = -1; - - ret = dvb_frontend_start (fe); - if (ret) - goto err2; - - /* empty event queue */ - fepriv->events.eventr = fepriv->events.eventw = 0; - } - - if (adapter->mfe_shared) - mutex_unlock (&adapter->mfe_lock); - return ret; - -err2: - dvb_generic_release(inode, file); -err1: - if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) - fe->ops.ts_bus_ctrl(fe, 0); -err0: - if (adapter->mfe_shared) - mutex_unlock (&adapter->mfe_lock); - return ret; -} - -static int dvb_frontend_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_frontend *fe = dvbdev->priv; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - int ret; - - dprintk ("%s\n", __func__); - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) - fepriv->release_jiffies = jiffies; - - ret = dvb_generic_release (inode, file); - - if (dvbdev->users == -1) { - if (fepriv->exit == 1) { - fops_put(file->f_op); - file->f_op = NULL; - wake_up(&dvbdev->wait_queue); - } - if (fe->ops.ts_bus_ctrl) - fe->ops.ts_bus_ctrl(fe, 0); - } - - return ret; -} - -static struct file_operations dvb_frontend_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, - .poll = dvb_frontend_poll, - .open = dvb_frontend_open, - .release = dvb_frontend_release -}; - -int dvb_register_frontend(struct dvb_adapter* dvb, - struct dvb_frontend* fe) -{ - struct dvb_frontend_private *fepriv; - static const struct dvb_device dvbdev_template = { - .users = ~0, - .writers = 1, - .readers = (~0)-1, - .fops = &dvb_frontend_fops, - .kernel_ioctl = dvb_frontend_ioctl - }; - - dprintk ("%s\n", __func__); - - if (mutex_lock_interruptible(&frontend_mutex)) - return -ERESTARTSYS; - - fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL); - if (fe->frontend_priv == NULL) { - mutex_unlock(&frontend_mutex); - return -ENOMEM; - } - fepriv = fe->frontend_priv; - - init_MUTEX (&fepriv->sem); - init_waitqueue_head (&fepriv->wait_queue); - init_waitqueue_head (&fepriv->events.wait_queue); - mutex_init(&fepriv->events.mtx); - fe->dvb = dvb; - fepriv->inversion = INVERSION_OFF; - - printk ("DVB: registering adapter %i frontend %i (%s)...\n", - fe->dvb->num, - fe->id, - fe->ops.info.name); - - dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template, - fe, DVB_DEVICE_FRONTEND); - - mutex_unlock(&frontend_mutex); - return 0; -} -EXPORT_SYMBOL(dvb_register_frontend); - -int dvb_unregister_frontend(struct dvb_frontend* fe) -{ - struct dvb_frontend_private *fepriv = fe->frontend_priv; - dprintk ("%s\n", __func__); - - mutex_lock(&frontend_mutex); - dvb_frontend_stop (fe); - mutex_unlock(&frontend_mutex); - - if (fepriv->dvbdev->users < -1) - wait_event(fepriv->dvbdev->wait_queue, - fepriv->dvbdev->users==-1); - - mutex_lock(&frontend_mutex); - dvb_unregister_device (fepriv->dvbdev); - - /* fe is invalid now */ - kfree(fepriv); - mutex_unlock(&frontend_mutex); - return 0; -} -EXPORT_SYMBOL(dvb_unregister_frontend); - -#ifdef CONFIG_MEDIA_ATTACH -void dvb_frontend_detach(struct dvb_frontend* fe) -{ - void *ptr; - - if (fe->ops.release_sec) { - fe->ops.release_sec(fe); - symbol_put_addr(fe->ops.release_sec); - } - if (fe->ops.tuner_ops.release) { - fe->ops.tuner_ops.release(fe); - symbol_put_addr(fe->ops.tuner_ops.release); - } - if (fe->ops.analog_ops.release) { - fe->ops.analog_ops.release(fe); - symbol_put_addr(fe->ops.analog_ops.release); - } - ptr = (void*)fe->ops.release; - if (ptr) { - fe->ops.release(fe); - symbol_put_addr(ptr); - } -} -#else -void dvb_frontend_detach(struct dvb_frontend* fe) -{ - if (fe->ops.release_sec) - fe->ops.release_sec(fe); - if (fe->ops.tuner_ops.release) - fe->ops.tuner_ops.release(fe); - if (fe->ops.analog_ops.release) - fe->ops.analog_ops.release(fe); - if (fe->ops.release) - fe->ops.release(fe); -} -#endif -EXPORT_SYMBOL(dvb_frontend_detach); diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h deleted file mode 100644 index e176da472d7..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ /dev/null @@ -1,372 +0,0 @@ -/* - * dvb_frontend.h - * - * Copyright (C) 2001 convergence integrated media GmbH - * Copyright (C) 2004 convergence GmbH - * - * Written by Ralph Metzler - * Overhauled by Holger Waechtler - * Kernel I2C stuff by Michael Hunold <hunold@convergence.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _DVB_FRONTEND_H_ -#define _DVB_FRONTEND_H_ - -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/ioctl.h> -#include <linux/i2c.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/mutex.h> - -#include <linux/dvb/frontend.h> - -#include "dvbdev.h" - -struct dvb_frontend_tune_settings { - int min_delay_ms; - int step_size; - int max_drift; - struct dvb_frontend_parameters parameters; -}; - -struct dvb_frontend; - -struct dvb_tuner_info { - char name[128]; - - u32 frequency_min; - u32 frequency_max; - u32 frequency_step; - - u32 bandwidth_min; - u32 bandwidth_max; - u32 bandwidth_step; -}; - -struct analog_parameters { - unsigned int frequency; - unsigned int mode; - unsigned int audmode; - u64 std; -}; - -enum dvbfe_modcod { - DVBFE_MODCOD_DUMMY_PLFRAME = 0, - DVBFE_MODCOD_QPSK_1_4, - DVBFE_MODCOD_QPSK_1_3, - DVBFE_MODCOD_QPSK_2_5, - DVBFE_MODCOD_QPSK_1_2, - DVBFE_MODCOD_QPSK_3_5, - DVBFE_MODCOD_QPSK_2_3, - DVBFE_MODCOD_QPSK_3_4, - DVBFE_MODCOD_QPSK_4_5, - DVBFE_MODCOD_QPSK_5_6, - DVBFE_MODCOD_QPSK_8_9, - DVBFE_MODCOD_QPSK_9_10, - DVBFE_MODCOD_8PSK_3_5, - DVBFE_MODCOD_8PSK_2_3, - DVBFE_MODCOD_8PSK_3_4, - DVBFE_MODCOD_8PSK_5_6, - DVBFE_MODCOD_8PSK_8_9, - DVBFE_MODCOD_8PSK_9_10, - DVBFE_MODCOD_16APSK_2_3, - DVBFE_MODCOD_16APSK_3_4, - DVBFE_MODCOD_16APSK_4_5, - DVBFE_MODCOD_16APSK_5_6, - DVBFE_MODCOD_16APSK_8_9, - DVBFE_MODCOD_16APSK_9_10, - DVBFE_MODCOD_32APSK_3_4, - DVBFE_MODCOD_32APSK_4_5, - DVBFE_MODCOD_32APSK_5_6, - DVBFE_MODCOD_32APSK_8_9, - DVBFE_MODCOD_32APSK_9_10, - DVBFE_MODCOD_RESERVED_1, - DVBFE_MODCOD_BPSK_1_3, - DVBFE_MODCOD_BPSK_1_4, - DVBFE_MODCOD_RESERVED_2 -}; - -enum tuner_param { - DVBFE_TUNER_FREQUENCY = (1 << 0), - DVBFE_TUNER_TUNERSTEP = (1 << 1), - DVBFE_TUNER_IFFREQ = (1 << 2), - DVBFE_TUNER_BANDWIDTH = (1 << 3), - DVBFE_TUNER_REFCLOCK = (1 << 4), - DVBFE_TUNER_IQSENSE = (1 << 5), - DVBFE_TUNER_DUMMY = (1 << 31) -}; - -/* - * ALGO_HW: (Hardware Algorithm) - * ---------------------------------------------------------------- - * Devices that support this algorithm do everything in hardware - * and no software support is needed to handle them. - * Requesting these devices to LOCK is the only thing required, - * device is supposed to do everything in the hardware. - * - * ALGO_SW: (Software Algorithm) - * ---------------------------------------------------------------- - * These are dumb devices, that require software to do everything - * - * ALGO_CUSTOM: (Customizable Agorithm) - * ---------------------------------------------------------------- - * Devices having this algorithm can be customized to have specific - * algorithms in the frontend driver, rather than simply doing a - * software zig-zag. In this case the zigzag maybe hardware assisted - * or it maybe completely done in hardware. In all cases, usage of - * this algorithm, in conjunction with the search and track - * callbacks, utilizes the driver specific algorithm. - * - * ALGO_RECOVERY: (Recovery Algorithm) - * ---------------------------------------------------------------- - * These devices have AUTO recovery capabilities from LOCK failure - */ -enum dvbfe_algo { - DVBFE_ALGO_HW = (1 << 0), - DVBFE_ALGO_SW = (1 << 1), - DVBFE_ALGO_CUSTOM = (1 << 2), - DVBFE_ALGO_RECOVERY = (1 << 31) -}; - -struct tuner_state { - u32 frequency; - u32 tunerstep; - u32 ifreq; - u32 bandwidth; - u32 iqsense; - u32 refclock; -}; - -/* - * search callback possible return status - * - * DVBFE_ALGO_SEARCH_SUCCESS - * The frontend search algorithm completed and returned succesfully - * - * DVBFE_ALGO_SEARCH_ASLEEP - * The frontend search algorithm is sleeping - * - * DVBFE_ALGO_SEARCH_FAILED - * The frontend search for a signal failed - * - * DVBFE_ALGO_SEARCH_INVALID - * The frontend search algorith was probably supplied with invalid - * parameters and the search is an invalid one - * - * DVBFE_ALGO_SEARCH_ERROR - * The frontend search algorithm failed due to some error - * - * DVBFE_ALGO_SEARCH_AGAIN - * The frontend search algorithm was requested to search again - */ -enum dvbfe_search { - DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0), - DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1), - DVBFE_ALGO_SEARCH_FAILED = (1 << 2), - DVBFE_ALGO_SEARCH_INVALID = (1 << 3), - DVBFE_ALGO_SEARCH_AGAIN = (1 << 4), - DVBFE_ALGO_SEARCH_ERROR = (1 << 31), -}; - - -struct dvb_tuner_ops { - - struct dvb_tuner_info info; - - int (*release)(struct dvb_frontend *fe); - int (*init)(struct dvb_frontend *fe); - int (*sleep)(struct dvb_frontend *fe); - - /** This is for simple PLLs - set all parameters in one go. */ - int (*set_params)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); - int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p); - - /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ - int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len); - - /** This is to allow setting tuner-specific configs */ - int (*set_config)(struct dvb_frontend *fe, void *priv_cfg); - - int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency); - int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); - -#define TUNER_STATUS_LOCKED 1 -#define TUNER_STATUS_STEREO 2 - int (*get_status)(struct dvb_frontend *fe, u32 *status); - int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); - - /** These are provided seperately from set_params in order to facilitate silicon - * tuners which require sophisticated tuning loops, controlling each parameter seperately. */ - int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); - int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); - - /* - * These are provided seperately from set_params in order to facilitate silicon - * tuners which require sophisticated tuning loops, controlling each parameter seperately. - */ - int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); - int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); -}; - -struct analog_demod_info { - char *name; -}; - -struct analog_demod_ops { - - struct analog_demod_info info; - - void (*set_params)(struct dvb_frontend *fe, - struct analog_parameters *params); - int (*has_signal)(struct dvb_frontend *fe); - int (*is_stereo)(struct dvb_frontend *fe); - int (*get_afc)(struct dvb_frontend *fe); - void (*tuner_status)(struct dvb_frontend *fe); - void (*standby)(struct dvb_frontend *fe); - void (*release)(struct dvb_frontend *fe); - int (*i2c_gate_ctrl)(struct dvb_frontend *fe, int enable); - - /** This is to allow setting tuner-specific configuration */ - int (*set_config)(struct dvb_frontend *fe, void *priv_cfg); -}; - -struct dvb_frontend_ops { - - struct dvb_frontend_info info; - - void (*release)(struct dvb_frontend* fe); - void (*release_sec)(struct dvb_frontend* fe); - - int (*init)(struct dvb_frontend* fe); - int (*sleep)(struct dvb_frontend* fe); - - int (*write)(struct dvb_frontend* fe, u8* buf, int len); - - /* if this is set, it overrides the default swzigzag */ - int (*tune)(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params, - unsigned int mode_flags, - unsigned int *delay, - fe_status_t *status); - /* get frontend tuning algorithm from the module */ - enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe); - - /* these two are only used for the swzigzag code */ - int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); - int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); - - int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); - - int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); - int (*read_ber)(struct dvb_frontend* fe, u32* ber); - int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); - int (*read_snr)(struct dvb_frontend* fe, u16* snr); - int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks); - - int (*diseqc_reset_overload)(struct dvb_frontend* fe); - int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); - int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply); - int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); - int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); - int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); - int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); - int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); - int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); - int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire); - - /* These callbacks are for devices that implement their own - * tuning algorithms, rather than a simple swzigzag - */ - enum dvbfe_search (*search)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); - int (*track)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p); - - struct dvb_tuner_ops tuner_ops; - struct analog_demod_ops analog_ops; - - int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); - int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); -}; - -#define MAX_EVENT 8 - -struct dvb_fe_events { - struct dvb_frontend_event events[MAX_EVENT]; - int eventw; - int eventr; - int overflow; - wait_queue_head_t wait_queue; - struct mutex mtx; -}; - -struct dtv_frontend_properties { - - /* Cache State */ - u32 state; - - u32 frequency; - fe_modulation_t modulation; - - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t sectone; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec_inner; - fe_transmit_mode_t transmission_mode; - u32 bandwidth_hz; /* 0 = AUTO */ - fe_guard_interval_t guard_interval; - fe_hierarchy_t hierarchy; - u32 symbol_rate; - fe_code_rate_t code_rate_HP; - fe_code_rate_t code_rate_LP; - - fe_pilot_t pilot; - fe_rolloff_t rolloff; - - fe_delivery_system_t delivery_system; -}; - -struct dvb_frontend { - struct dvb_frontend_ops ops; - struct dvb_adapter *dvb; - void *demodulator_priv; - void *tuner_priv; - void *frontend_priv; - void *sec_priv; - void *analog_demod_priv; - struct dtv_frontend_properties dtv_property_cache; -#define DVB_FRONTEND_COMPONENT_TUNER 0 - int (*callback)(void *adapter_priv, int component, int cmd, int arg); - int id; -}; - -extern int dvb_register_frontend(struct dvb_adapter *dvb, - struct dvb_frontend *fe); - -extern int dvb_unregister_frontend(struct dvb_frontend *fe); - -extern void dvb_frontend_detach(struct dvb_frontend *fe); - -extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); - -extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); -extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); - -#endif diff --git a/drivers/media/dvb/dvb-core/dvb_math.c b/drivers/media/dvb/dvb-core/dvb_math.c deleted file mode 100644 index beb7c93aa6c..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_math.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * dvb-math provides some complex fixed-point math - * operations shared between the dvb related stuff - * - * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include <linux/bitops.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <asm/bug.h> -#include "dvb_math.h" - -static const unsigned short logtable[256] = { - 0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7, - 0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508, - 0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6, - 0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37, - 0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f, - 0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41, - 0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1, - 0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142, - 0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68, - 0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355, - 0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c, - 0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490, - 0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3, - 0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507, - 0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe, - 0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca, - 0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c, - 0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7, - 0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c, - 0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c, - 0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a, - 0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065, - 0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730, - 0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc, - 0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469, - 0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9, - 0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c, - 0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765, - 0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83, - 0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387, - 0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973, - 0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47 -}; - -unsigned int intlog2(u32 value) -{ - /** - * returns: log2(value) * 2^24 - * wrong result if value = 0 (log2(0) is undefined) - */ - unsigned int msb; - unsigned int logentry; - unsigned int significand; - unsigned int interpolation; - - if (unlikely(value == 0)) { - WARN_ON(1); - return 0; - } - - /* first detect the msb (count begins at 0) */ - msb = fls(value) - 1; - - /** - * now we use a logtable after the following method: - * - * log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24 - * where x = msb and therefore 1 <= y < 2 - * first y is determined by shifting the value left - * so that msb is bit 31 - * 0x00231f56 -> 0x8C7D5800 - * the result is y * 2^31 -> "significand" - * then the highest 9 bits are used for a table lookup - * the highest bit is discarded because it's always set - * the highest nine bits in our example are 100011000 - * so we would use the entry 0x18 - */ - significand = value << (31 - msb); - logentry = (significand >> 23) & 0xff; - - /** - * last step we do is interpolation because of the - * limitations of the log table the error is that part of - * the significand which isn't used for lookup then we - * compute the ratio between the error and the next table entry - * and interpolate it between the log table entry used and the - * next one the biggest error possible is 0x7fffff - * (in our example it's 0x7D5800) - * needed value for next table entry is 0x800000 - * so the interpolation is - * (error / 0x800000) * (logtable_next - logtable_current) - * in the implementation the division is moved to the end for - * better accuracy there is also an overflow correction if - * logtable_next is 256 - */ - interpolation = ((significand & 0x7fffff) * - ((logtable[(logentry + 1) & 0xff] - - logtable[logentry]) & 0xffff)) >> 15; - - /* now we return the result */ - return ((msb << 24) + (logtable[logentry] << 8) + interpolation); -} -EXPORT_SYMBOL(intlog2); - -unsigned int intlog10(u32 value) -{ - /** - * returns: log10(value) * 2^24 - * wrong result if value = 0 (log10(0) is undefined) - */ - u64 log; - - if (unlikely(value == 0)) { - WARN_ON(1); - return 0; - } - - log = intlog2(value); - - /** - * we use the following method: - * log10(x) = log2(x) * log10(2) - */ - - return (log * 646456993) >> 31; -} -EXPORT_SYMBOL(intlog10); diff --git a/drivers/media/dvb/dvb-core/dvb_math.h b/drivers/media/dvb/dvb-core/dvb_math.h deleted file mode 100644 index aecc867e940..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_math.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * dvb-math provides some complex fixed-point math - * operations shared between the dvb related stuff - * - * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef __DVB_MATH_H -#define __DVB_MATH_H - -#include <linux/types.h> - -/** - * computes log2 of a value; the result is shifted left by 24 bits - * - * to use rational values you can use the following method: - * intlog2(value) = intlog2(value * 2^x) - x * 2^24 - * - * example: intlog2(8) will give 3 << 24 = 3 * 2^24 - * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 - * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 - * - * @param value The value (must be != 0) - * @return log2(value) * 2^24 - */ -extern unsigned int intlog2(u32 value); - -/** - * computes log10 of a value; the result is shifted left by 24 bits - * - * to use rational values you can use the following method: - * intlog10(value) = intlog10(value * 10^x) - x * 2^24 - * - * example: intlog10(1000) will give 3 << 24 = 3 * 2^24 - * due to the implementation intlog10(1000) might be not exactly 3 * 2^24 - * - * look at intlog2 for similar examples - * - * @param value The value (must be != 0) - * @return log10(value) * 2^24 - */ -extern unsigned int intlog10(u32 value); - -#endif diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c deleted file mode 100644 index f6ba8468858..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ /dev/null @@ -1,1512 +0,0 @@ -/* - * dvb_net.c - * - * Copyright (C) 2001 Convergence integrated media GmbH - * Ralph Metzler <ralph@convergence.de> - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * ULE Decapsulation code: - * Copyright (C) 2003, 2004 gcs - Global Communication & Services GmbH. - * and Department of Scientific Computing - * Paris Lodron University of Salzburg. - * Hilmar Linder <hlinder@cosy.sbg.ac.at> - * and Wolfram Stering <wstering@cosy.sbg.ac.at> - * - * ULE Decaps according to RFC 4326. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - */ - -/* - * ULE ChangeLog: - * Feb 2004: hl/ws v1: Implementing draft-fair-ipdvb-ule-01.txt - * - * Dec 2004: hl/ws v2: Implementing draft-ietf-ipdvb-ule-03.txt: - * ULE Extension header handling. - * Bugreports by Moritz Vieth and Hanno Tersteegen, - * Fraunhofer Institute for Open Communication Systems - * Competence Center for Advanced Satellite Communications. - * Bugfixes and robustness improvements. - * Filtering on dest MAC addresses, if present (D-Bit = 0) - * ULE_DEBUG compile-time option. - * Apr 2006: cp v3: Bugfixes and compliency with RFC 4326 (ULE) by - * Christian Praehauser <cpraehaus@cosy.sbg.ac.at>, - * Paris Lodron University of Salzburg. - */ - -/* - * FIXME / TODO (dvb_net.c): - * - * Unloading does not work for 2.6.9 kernels: a refcount doesn't go to zero. - * - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/dvb/net.h> -#include <linux/uio.h> -#include <asm/uaccess.h> -#include <linux/crc32.h> -#include <linux/mutex.h> - -#include "dvb_demux.h" -#include "dvb_net.h" - -static int dvb_net_debug; -module_param(dvb_net_debug, int, 0444); -MODULE_PARM_DESC(dvb_net_debug, "enable debug messages"); - -#define dprintk(x...) do { if (dvb_net_debug) printk(x); } while (0) - - -static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt ) -{ - unsigned int j; - for (j = 0; j < cnt; j++) - c = crc32_be( c, iov[j].iov_base, iov[j].iov_len ); - return c; -} - - -#define DVB_NET_MULTICAST_MAX 10 - -#undef ULE_DEBUG - -#ifdef ULE_DEBUG - -#define MAC_ADDR_PRINTFMT "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" -#define MAX_ADDR_PRINTFMT_ARGS(macap) (macap)[0],(macap)[1],(macap)[2],(macap)[3],(macap)[4],(macap)[5] - -#define isprint(c) ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) - -static void hexdump( const unsigned char *buf, unsigned short len ) -{ - char str[80], octet[10]; - int ofs, i, l; - - for (ofs = 0; ofs < len; ofs += 16) { - sprintf( str, "%03d: ", ofs ); - - for (i = 0; i < 16; i++) { - if ((i + ofs) < len) - sprintf( octet, "%02x ", buf[ofs + i] ); - else - strcpy( octet, " " ); - - strcat( str, octet ); - } - strcat( str, " " ); - l = strlen( str ); - - for (i = 0; (i < 16) && ((i + ofs) < len); i++) - str[l++] = isprint( buf[ofs + i] ) ? buf[ofs + i] : '.'; - - str[l] = '\0'; - printk( KERN_WARNING "%s\n", str ); - } -} - -#endif - -struct dvb_net_priv { - int in_use; - u16 pid; - struct net_device *net; - struct dvb_net *host; - struct dmx_demux *demux; - struct dmx_section_feed *secfeed; - struct dmx_section_filter *secfilter; - struct dmx_ts_feed *tsfeed; - int multi_num; - struct dmx_section_filter *multi_secfilter[DVB_NET_MULTICAST_MAX]; - unsigned char multi_macs[DVB_NET_MULTICAST_MAX][6]; - int rx_mode; -#define RX_MODE_UNI 0 -#define RX_MODE_MULTI 1 -#define RX_MODE_ALL_MULTI 2 -#define RX_MODE_PROMISC 3 - struct work_struct set_multicast_list_wq; - struct work_struct restart_net_feed_wq; - unsigned char feedtype; /* Either FEED_TYPE_ or FEED_TYPE_ULE */ - int need_pusi; /* Set to 1, if synchronization on PUSI required. */ - unsigned char tscc; /* TS continuity counter after sync on PUSI. */ - struct sk_buff *ule_skb; /* ULE SNDU decodes into this buffer. */ - unsigned char *ule_next_hdr; /* Pointer into skb to next ULE extension header. */ - unsigned short ule_sndu_len; /* ULE SNDU length in bytes, w/o D-Bit. */ - unsigned short ule_sndu_type; /* ULE SNDU type field, complete. */ - unsigned char ule_sndu_type_1; /* ULE SNDU type field, if split across 2 TS cells. */ - unsigned char ule_dbit; /* Whether the DestMAC address present - * or not (bit is set). */ - unsigned char ule_bridged; /* Whether the ULE_BRIDGED extension header was found. */ - int ule_sndu_remain; /* Nr. of bytes still required for current ULE SNDU. */ - unsigned long ts_count; /* Current ts cell counter. */ - struct mutex mutex; -}; - - -/** - * Determine the packet's protocol ID. The rule here is that we - * assume 802.3 if the type field is short enough to be a length. - * This is normal practice and works for any 'now in use' protocol. - * - * stolen from eth.c out of the linux kernel, hacked for dvb-device - * by Michael Holzt <kju@debian.org> - */ -static __be16 dvb_net_eth_type_trans(struct sk_buff *skb, - struct net_device *dev) -{ - struct ethhdr *eth; - unsigned char *rawp; - - skb_reset_mac_header(skb); - skb_pull(skb,dev->hard_header_len); - eth = eth_hdr(skb); - - if (*eth->h_dest & 1) { - if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0) - skb->pkt_type=PACKET_BROADCAST; - else - skb->pkt_type=PACKET_MULTICAST; - } - - if (ntohs(eth->h_proto) >= 1536) - return eth->h_proto; - - rawp = skb->data; - - /** - * This is a magic hack to spot IPX packets. Older Novell breaks - * the protocol design and runs IPX over 802.3 without an 802.2 LLC - * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This - * won't work for fault tolerant netware but does for the rest. - */ - if (*(unsigned short *)rawp == 0xFFFF) - return htons(ETH_P_802_3); - - /** - * Real 802.2 LLC - */ - return htons(ETH_P_802_2); -} - -#define TS_SZ 188 -#define TS_SYNC 0x47 -#define TS_TEI 0x80 -#define TS_SC 0xC0 -#define TS_PUSI 0x40 -#define TS_AF_A 0x20 -#define TS_AF_D 0x10 - -/* ULE Extension Header handlers. */ - -#define ULE_TEST 0 -#define ULE_BRIDGED 1 - -#define ULE_OPTEXTHDR_PADDING 0 - -static int ule_test_sndu( struct dvb_net_priv *p ) -{ - return -1; -} - -static int ule_bridged_sndu( struct dvb_net_priv *p ) -{ - struct ethhdr *hdr = (struct ethhdr*) p->ule_next_hdr; - if(ntohs(hdr->h_proto) < 1536) { - int framelen = p->ule_sndu_len - ((p->ule_next_hdr+sizeof(struct ethhdr)) - p->ule_skb->data); - /* A frame Type < 1536 for a bridged frame, introduces a LLC Length field. */ - if(framelen != ntohs(hdr->h_proto)) { - return -1; - } - } - /* Note: - * From RFC4326: - * "A bridged SNDU is a Mandatory Extension Header of Type 1. - * It must be the final (or only) extension header specified in the header chain of a SNDU." - * The 'ule_bridged' flag will cause the extension header processing loop to terminate. - */ - p->ule_bridged = 1; - return 0; -} - -static int ule_exthdr_padding(struct dvb_net_priv *p) -{ - return 0; -} - -/** Handle ULE extension headers. - * Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding. - * Returns: >= 0: nr. of bytes consumed by next extension header - * -1: Mandatory extension header that is not recognized or TEST SNDU; discard. - */ -static int handle_one_ule_extension( struct dvb_net_priv *p ) -{ - /* Table of mandatory extension header handlers. The header type is the index. */ - static int (*ule_mandatory_ext_handlers[255])( struct dvb_net_priv *p ) = - { [0] = ule_test_sndu, [1] = ule_bridged_sndu, [2] = NULL, }; - - /* Table of optional extension header handlers. The header type is the index. */ - static int (*ule_optional_ext_handlers[255])( struct dvb_net_priv *p ) = - { [0] = ule_exthdr_padding, [1] = NULL, }; - - int ext_len = 0; - unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; - unsigned char htype = p->ule_sndu_type & 0x00FF; - - /* Discriminate mandatory and optional extension headers. */ - if (hlen == 0) { - /* Mandatory extension header */ - if (ule_mandatory_ext_handlers[htype]) { - ext_len = ule_mandatory_ext_handlers[htype]( p ); - if(ext_len >= 0) { - p->ule_next_hdr += ext_len; - if (!p->ule_bridged) { - p->ule_sndu_type = ntohs(*(__be16 *)p->ule_next_hdr); - p->ule_next_hdr += 2; - } else { - p->ule_sndu_type = ntohs(*(__be16 *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); - /* This assures the extension handling loop will terminate. */ - } - } - // else: extension handler failed or SNDU should be discarded - } else - ext_len = -1; /* SNDU has to be discarded. */ - } else { - /* Optional extension header. Calculate the length. */ - ext_len = hlen << 1; - /* Process the optional extension header according to its type. */ - if (ule_optional_ext_handlers[htype]) - (void)ule_optional_ext_handlers[htype]( p ); - p->ule_next_hdr += ext_len; - p->ule_sndu_type = ntohs( *(__be16 *)(p->ule_next_hdr-2) ); - /* - * note: the length of the next header type is included in the - * length of THIS optional extension header - */ - } - - return ext_len; -} - -static int handle_ule_extensions( struct dvb_net_priv *p ) -{ - int total_ext_len = 0, l; - - p->ule_next_hdr = p->ule_skb->data; - do { - l = handle_one_ule_extension( p ); - if (l < 0) - return l; /* Stop extension header processing and discard SNDU. */ - total_ext_len += l; -#ifdef ULE_DEBUG - dprintk("handle_ule_extensions: ule_next_hdr=%p, ule_sndu_type=%i, " - "l=%i, total_ext_len=%i\n", p->ule_next_hdr, - (int) p->ule_sndu_type, l, total_ext_len); -#endif - - } while (p->ule_sndu_type < 1536); - - return total_ext_len; -} - - -/** Prepare for a new ULE SNDU: reset the decoder state. */ -static inline void reset_ule( struct dvb_net_priv *p ) -{ - p->ule_skb = NULL; - p->ule_next_hdr = NULL; - p->ule_sndu_len = 0; - p->ule_sndu_type = 0; - p->ule_sndu_type_1 = 0; - p->ule_sndu_remain = 0; - p->ule_dbit = 0xFF; - p->ule_bridged = 0; -} - -/** - * Decode ULE SNDUs according to draft-ietf-ipdvb-ule-03.txt from a sequence of - * TS cells of a single PID. - */ -static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - unsigned long skipped = 0L; - const u8 *ts, *ts_end, *from_where = NULL; - u8 ts_remain = 0, how_much = 0, new_ts = 1; - struct ethhdr *ethh = NULL; - -#ifdef ULE_DEBUG - /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ - static unsigned char ule_hist[100*TS_SZ]; - static unsigned char *ule_where = ule_hist, ule_dump; -#endif - - /* For all TS cells in current buffer. - * Appearently, we are called for every single TS cell. - */ - for (ts = buf, ts_end = buf + buf_len; ts < ts_end; /* no default incr. */ ) { - - if (new_ts) { - /* We are about to process a new TS cell. */ - -#ifdef ULE_DEBUG - if (ule_where >= &ule_hist[100*TS_SZ]) ule_where = ule_hist; - memcpy( ule_where, ts, TS_SZ ); - if (ule_dump) { - hexdump( ule_where, TS_SZ ); - ule_dump = 0; - } - ule_where += TS_SZ; -#endif - - /* Check TS error conditions: sync_byte, transport_error_indicator, scrambling_control . */ - if ((ts[0] != TS_SYNC) || (ts[1] & TS_TEI) || ((ts[3] & TS_SC) != 0)) { - printk(KERN_WARNING "%lu: Invalid TS cell: SYNC %#x, TEI %u, SC %#x.\n", - priv->ts_count, ts[0], ts[1] & TS_TEI >> 7, ts[3] & 0xC0 >> 6); - - /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); - /* Prepare for next SNDU. */ - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; - } - reset_ule(priv); - priv->need_pusi = 1; - - /* Continue with next TS cell. */ - ts += TS_SZ; - priv->ts_count++; - continue; - } - - ts_remain = 184; - from_where = ts + 4; - } - /* Synchronize on PUSI, if required. */ - if (priv->need_pusi) { - if (ts[1] & TS_PUSI) { - /* Find beginning of first ULE SNDU in current TS cell. */ - /* Synchronize continuity counter. */ - priv->tscc = ts[3] & 0x0F; - /* There is a pointer field here. */ - if (ts[4] > ts_remain) { - printk(KERN_ERR "%lu: Invalid ULE packet " - "(pointer field %d)\n", priv->ts_count, ts[4]); - ts += TS_SZ; - priv->ts_count++; - continue; - } - /* Skip to destination of pointer field. */ - from_where = &ts[5] + ts[4]; - ts_remain -= 1 + ts[4]; - skipped = 0; - } else { - skipped++; - ts += TS_SZ; - priv->ts_count++; - continue; - } - } - - if (new_ts) { - /* Check continuity counter. */ - if ((ts[3] & 0x0F) == priv->tscc) - priv->tscc = (priv->tscc + 1) & 0x0F; - else { - /* TS discontinuity handling: */ - printk(KERN_WARNING "%lu: TS discontinuity: got %#x, " - "expected %#x.\n", priv->ts_count, ts[3] & 0x0F, priv->tscc); - /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); - /* Prepare for next SNDU. */ - // reset_ule(priv); moved to below. - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; - } - reset_ule(priv); - /* skip to next PUSI. */ - priv->need_pusi = 1; - continue; - } - /* If we still have an incomplete payload, but PUSI is - * set; some TS cells are missing. - * This is only possible here, if we missed exactly 16 TS - * cells (continuity counter wrap). */ - if (ts[1] & TS_PUSI) { - if (! priv->need_pusi) { - if (!(*from_where < (ts_remain-1)) || *from_where != priv->ule_sndu_remain) { - /* Pointer field is invalid. Drop this TS cell and any started ULE SNDU. */ - printk(KERN_WARNING "%lu: Invalid pointer " - "field: %u.\n", priv->ts_count, *from_where); - - /* Drop partly decoded SNDU, reset state, resync on PUSI. */ - if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); - dev->stats.rx_errors++; - dev->stats.rx_frame_errors++; - } - reset_ule(priv); - priv->need_pusi = 1; - continue; - } - /* Skip pointer field (we're processing a - * packed payload). */ - from_where += 1; - ts_remain -= 1; - } else - priv->need_pusi = 0; - - if (priv->ule_sndu_remain > 183) { - /* Current SNDU lacks more data than there could be available in the - * current TS cell. */ - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - printk(KERN_WARNING "%lu: Expected %d more SNDU bytes, but " - "got PUSI (pf %d, ts_remain %d). Flushing incomplete payload.\n", - priv->ts_count, priv->ule_sndu_remain, ts[4], ts_remain); - dev_kfree_skb(priv->ule_skb); - /* Prepare for next SNDU. */ - reset_ule(priv); - /* Resync: go to where pointer field points to: start of next ULE SNDU. */ - from_where += ts[4]; - ts_remain -= ts[4]; - } - } - } - - /* Check if new payload needs to be started. */ - if (priv->ule_skb == NULL) { - /* Start a new payload with skb. - * Find ULE header. It is only guaranteed that the - * length field (2 bytes) is contained in the current - * TS. - * Check ts_remain has to be >= 2 here. */ - if (ts_remain < 2) { - printk(KERN_WARNING "Invalid payload packing: only %d " - "bytes left in TS. Resyncing.\n", ts_remain); - priv->ule_sndu_len = 0; - priv->need_pusi = 1; - continue; - } - - if (! priv->ule_sndu_len) { - /* Got at least two bytes, thus extrace the SNDU length. */ - priv->ule_sndu_len = from_where[0] << 8 | from_where[1]; - if (priv->ule_sndu_len & 0x8000) { - /* D-Bit is set: no dest mac present. */ - priv->ule_sndu_len &= 0x7FFF; - priv->ule_dbit = 1; - } else - priv->ule_dbit = 0; - - if (priv->ule_sndu_len < 5) { - printk(KERN_WARNING "%lu: Invalid ULE SNDU length %u. " - "Resyncing.\n", priv->ts_count, priv->ule_sndu_len); - dev->stats.rx_errors++; - dev->stats.rx_length_errors++; - priv->ule_sndu_len = 0; - priv->need_pusi = 1; - new_ts = 1; - ts += TS_SZ; - priv->ts_count++; - continue; - } - ts_remain -= 2; /* consume the 2 bytes SNDU length. */ - from_where += 2; - } - - /* - * State of current TS: - * ts_remain (remaining bytes in the current TS cell) - * 0 ule_type is not available now, we need the next TS cell - * 1 the first byte of the ule_type is present - * >=2 full ULE header present, maybe some payload data as well. - */ - switch (ts_remain) { - case 1: - priv->ule_sndu_type = from_where[0] << 8; - priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ - ts_remain -= 1; from_where += 1; - /* Continue w/ next TS. */ - case 0: - new_ts = 1; - ts += TS_SZ; - priv->ts_count++; - continue; - - default: /* complete ULE header is present in current TS. */ - /* Extract ULE type field. */ - if (priv->ule_sndu_type_1) { - priv->ule_sndu_type |= from_where[0]; - from_where += 1; /* points to payload start. */ - ts_remain -= 1; - } else { - /* Complete type is present in new TS. */ - priv->ule_sndu_type = from_where[0] << 8 | from_where[1]; - from_where += 2; /* points to payload start. */ - ts_remain -= 2; - } - break; - } - - /* Allocate the skb (decoder target buffer) with the correct size, as follows: - * prepare for the largest case: bridged SNDU with MAC address (dbit = 0). */ - priv->ule_skb = dev_alloc_skb( priv->ule_sndu_len + ETH_HLEN + ETH_ALEN ); - if (priv->ule_skb == NULL) { - printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", - dev->name); - dev->stats.rx_dropped++; - return; - } - - /* This includes the CRC32 _and_ dest mac, if !dbit. */ - priv->ule_sndu_remain = priv->ule_sndu_len; - priv->ule_skb->dev = dev; - /* Leave space for Ethernet or bridged SNDU header (eth hdr plus one MAC addr). */ - skb_reserve( priv->ule_skb, ETH_HLEN + ETH_ALEN ); - } - - /* Copy data into our current skb. */ - how_much = min(priv->ule_sndu_remain, (int)ts_remain); - memcpy(skb_put(priv->ule_skb, how_much), from_where, how_much); - priv->ule_sndu_remain -= how_much; - ts_remain -= how_much; - from_where += how_much; - - /* Check for complete payload. */ - if (priv->ule_sndu_remain <= 0) { - /* Check CRC32, we've got it in our skb already. */ - __be16 ulen = htons(priv->ule_sndu_len); - __be16 utype = htons(priv->ule_sndu_type); - const u8 *tail; - struct kvec iov[3] = { - { &ulen, sizeof ulen }, - { &utype, sizeof utype }, - { priv->ule_skb->data, priv->ule_skb->len - 4 } - }; - u32 ule_crc = ~0L, expected_crc; - if (priv->ule_dbit) { - /* Set D-bit for CRC32 verification, - * if it was set originally. */ - ulen |= htons(0x8000); - } - - ule_crc = iov_crc32(ule_crc, iov, 3); - tail = skb_tail_pointer(priv->ule_skb); - expected_crc = *(tail - 4) << 24 | - *(tail - 3) << 16 | - *(tail - 2) << 8 | - *(tail - 1); - if (ule_crc != expected_crc) { - printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", - priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0); - -#ifdef ULE_DEBUG - hexdump( iov[0].iov_base, iov[0].iov_len ); - hexdump( iov[1].iov_base, iov[1].iov_len ); - hexdump( iov[2].iov_base, iov[2].iov_len ); - - if (ule_where == ule_hist) { - hexdump( &ule_hist[98*TS_SZ], TS_SZ ); - hexdump( &ule_hist[99*TS_SZ], TS_SZ ); - } else if (ule_where == &ule_hist[TS_SZ]) { - hexdump( &ule_hist[99*TS_SZ], TS_SZ ); - hexdump( ule_hist, TS_SZ ); - } else { - hexdump( ule_where - TS_SZ - TS_SZ, TS_SZ ); - hexdump( ule_where - TS_SZ, TS_SZ ); - } - ule_dump = 1; -#endif - - dev->stats.rx_errors++; - dev->stats.rx_crc_errors++; - dev_kfree_skb(priv->ule_skb); - } else { - /* CRC32 verified OK. */ - u8 dest_addr[ETH_ALEN]; - static const u8 bc_addr[ETH_ALEN] = - { [ 0 ... ETH_ALEN-1] = 0xff }; - - /* CRC32 was OK. Remove it from skb. */ - priv->ule_skb->tail -= 4; - priv->ule_skb->len -= 4; - - if (!priv->ule_dbit) { - /* - * The destination MAC address is the - * next data in the skb. It comes - * before any extension headers. - * - * Check if the payload of this SNDU - * should be passed up the stack. - */ - register int drop = 0; - if (priv->rx_mode != RX_MODE_PROMISC) { - if (priv->ule_skb->data[0] & 0x01) { - /* multicast or broadcast */ - if (memcmp(priv->ule_skb->data, bc_addr, ETH_ALEN)) { - /* multicast */ - if (priv->rx_mode == RX_MODE_MULTI) { - int i; - for(i = 0; i < priv->multi_num && memcmp(priv->ule_skb->data, priv->multi_macs[i], ETH_ALEN); i++) - ; - if (i == priv->multi_num) - drop = 1; - } else if (priv->rx_mode != RX_MODE_ALL_MULTI) - drop = 1; /* no broadcast; */ - /* else: all multicast mode: accept all multicast packets */ - } - /* else: broadcast */ - } - else if (memcmp(priv->ule_skb->data, dev->dev_addr, ETH_ALEN)) - drop = 1; - /* else: destination address matches the MAC address of our receiver device */ - } - /* else: promiscuous mode; pass everything up the stack */ - - if (drop) { -#ifdef ULE_DEBUG - dprintk("Dropping SNDU: MAC destination address does not match: dest addr: "MAC_ADDR_PRINTFMT", dev addr: "MAC_ADDR_PRINTFMT"\n", - MAX_ADDR_PRINTFMT_ARGS(priv->ule_skb->data), MAX_ADDR_PRINTFMT_ARGS(dev->dev_addr)); -#endif - dev_kfree_skb(priv->ule_skb); - goto sndu_done; - } - else - { - skb_copy_from_linear_data(priv->ule_skb, - dest_addr, - ETH_ALEN); - skb_pull(priv->ule_skb, ETH_ALEN); - } - } - - /* Handle ULE Extension Headers. */ - if (priv->ule_sndu_type < 1536) { - /* There is an extension header. Handle it accordingly. */ - int l = handle_ule_extensions(priv); - if (l < 0) { - /* Mandatory extension header unknown or TEST SNDU. Drop it. */ - // printk( KERN_WARNING "Dropping SNDU, extension headers.\n" ); - dev_kfree_skb(priv->ule_skb); - goto sndu_done; - } - skb_pull(priv->ule_skb, l); - } - - /* - * Construct/assure correct ethernet header. - * Note: in bridged mode (priv->ule_bridged != - * 0) we already have the (original) ethernet - * header at the start of the payload (after - * optional dest. address and any extension - * headers). - */ - - if (!priv->ule_bridged) { - skb_push(priv->ule_skb, ETH_HLEN); - ethh = (struct ethhdr *)priv->ule_skb->data; - if (!priv->ule_dbit) { - /* dest_addr buffer is only valid if priv->ule_dbit == 0 */ - memcpy(ethh->h_dest, dest_addr, ETH_ALEN); - memset(ethh->h_source, 0, ETH_ALEN); - } - else /* zeroize source and dest */ - memset( ethh, 0, ETH_ALEN*2 ); - - ethh->h_proto = htons(priv->ule_sndu_type); - } - /* else: skb is in correct state; nothing to do. */ - priv->ule_bridged = 0; - - /* Stuff into kernel's protocol stack. */ - priv->ule_skb->protocol = dvb_net_eth_type_trans(priv->ule_skb, dev); - /* If D-bit is set (i.e. destination MAC address not present), - * receive the packet anyhow. */ - /* if (priv->ule_dbit && skb->pkt_type == PACKET_OTHERHOST) - priv->ule_skb->pkt_type = PACKET_HOST; */ - dev->stats.rx_packets++; - dev->stats.rx_bytes += priv->ule_skb->len; - netif_rx(priv->ule_skb); - } - sndu_done: - /* Prepare for next SNDU. */ - reset_ule(priv); - } - - /* More data in current TS (look at the bytes following the CRC32)? */ - if (ts_remain >= 2 && *((unsigned short *)from_where) != 0xFFFF) { - /* Next ULE SNDU starts right there. */ - new_ts = 0; - priv->ule_skb = NULL; - priv->ule_sndu_type_1 = 0; - priv->ule_sndu_len = 0; - // printk(KERN_WARNING "More data in current TS: [%#x %#x %#x %#x]\n", - // *(from_where + 0), *(from_where + 1), - // *(from_where + 2), *(from_where + 3)); - // printk(KERN_WARNING "ts @ %p, stopped @ %p:\n", ts, from_where + 0); - // hexdump(ts, 188); - } else { - new_ts = 1; - ts += TS_SZ; - priv->ts_count++; - if (priv->ule_skb == NULL) { - priv->need_pusi = 1; - priv->ule_sndu_type_1 = 0; - priv->ule_sndu_len = 0; - } - } - } /* for all available TS cells */ -} - -static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_ts_feed *feed, enum dmx_success success) -{ - struct net_device *dev = feed->priv; - - if (buffer2) - printk(KERN_WARNING "buffer2 not NULL: %p.\n", buffer2); - if (buffer1_len > 32768) - printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len); - /* printk("TS callback: %u bytes, %u TS cells @ %p.\n", - buffer1_len, buffer1_len / TS_SZ, buffer1); */ - dvb_net_ule(dev, buffer1, buffer1_len); - return 0; -} - - -static void dvb_net_sec(struct net_device *dev, - const u8 *pkt, int pkt_len) -{ - u8 *eth; - struct sk_buff *skb; - struct net_device_stats *stats = &dev->stats; - int snap = 0; - - /* note: pkt_len includes a 32bit checksum */ - if (pkt_len < 16) { - printk("%s: IP/MPE packet length = %d too small.\n", - dev->name, pkt_len); - stats->rx_errors++; - stats->rx_length_errors++; - return; - } -/* it seems some ISPs manage to screw up here, so we have to - * relax the error checks... */ -#if 0 - if ((pkt[5] & 0xfd) != 0xc1) { - /* drop scrambled or broken packets */ -#else - if ((pkt[5] & 0x3c) != 0x00) { - /* drop scrambled */ -#endif - stats->rx_errors++; - stats->rx_crc_errors++; - return; - } - if (pkt[5] & 0x02) { - /* handle LLC/SNAP, see rfc-1042 */ - if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) { - stats->rx_dropped++; - return; - } - snap = 8; - } - if (pkt[7]) { - /* FIXME: assemble datagram from multiple sections */ - stats->rx_errors++; - stats->rx_frame_errors++; - return; - } - - /* we have 14 byte ethernet header (ip header follows); - * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP - */ - if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) { - //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); - stats->rx_dropped++; - return; - } - skb_reserve(skb, 2); /* longword align L3 header */ - skb->dev = dev; - - /* copy L3 payload */ - eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap); - memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap); - - /* create ethernet header: */ - eth[0]=pkt[0x0b]; - eth[1]=pkt[0x0a]; - eth[2]=pkt[0x09]; - eth[3]=pkt[0x08]; - eth[4]=pkt[0x04]; - eth[5]=pkt[0x03]; - - eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0; - - if (snap) { - eth[12] = pkt[18]; - eth[13] = pkt[19]; - } else { - /* protocol numbers are from rfc-1700 or - * http://www.iana.org/assignments/ethernet-numbers - */ - if (pkt[12] >> 4 == 6) { /* version field from IP header */ - eth[12] = 0x86; /* IPv6 */ - eth[13] = 0xdd; - } else { - eth[12] = 0x08; /* IPv4 */ - eth[13] = 0x00; - } - } - - skb->protocol = dvb_net_eth_type_trans(skb, dev); - - stats->rx_packets++; - stats->rx_bytes+=skb->len; - netif_rx(skb); -} - -static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, - const u8 *buffer2, size_t buffer2_len, - struct dmx_section_filter *filter, - enum dmx_success success) -{ - struct net_device *dev = filter->priv; - - /** - * we rely on the DVB API definition where exactly one complete - * section is delivered in buffer1 - */ - dvb_net_sec (dev, buffer1, buffer1_len); - return 0; -} - -static int dvb_net_tx(struct sk_buff *skb, struct net_device *dev) -{ - dev_kfree_skb(skb); - return 0; -} - -static u8 mask_normal[6]={0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -static u8 mask_allmulti[6]={0xff, 0xff, 0xff, 0x00, 0x00, 0x00}; -static u8 mac_allmulti[6]={0x01, 0x00, 0x5e, 0x00, 0x00, 0x00}; -static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -static int dvb_net_filter_sec_set(struct net_device *dev, - struct dmx_section_filter **secfilter, - u8 *mac, u8 *mac_mask) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - int ret; - - *secfilter=NULL; - ret = priv->secfeed->allocate_filter(priv->secfeed, secfilter); - if (ret<0) { - printk("%s: could not get filter\n", dev->name); - return ret; - } - - (*secfilter)->priv=(void *) dev; - - memset((*secfilter)->filter_value, 0x00, DMX_MAX_FILTER_SIZE); - memset((*secfilter)->filter_mask, 0x00, DMX_MAX_FILTER_SIZE); - memset((*secfilter)->filter_mode, 0xff, DMX_MAX_FILTER_SIZE); - - (*secfilter)->filter_value[0]=0x3e; - (*secfilter)->filter_value[3]=mac[5]; - (*secfilter)->filter_value[4]=mac[4]; - (*secfilter)->filter_value[8]=mac[3]; - (*secfilter)->filter_value[9]=mac[2]; - (*secfilter)->filter_value[10]=mac[1]; - (*secfilter)->filter_value[11]=mac[0]; - - (*secfilter)->filter_mask[0] = 0xff; - (*secfilter)->filter_mask[3] = mac_mask[5]; - (*secfilter)->filter_mask[4] = mac_mask[4]; - (*secfilter)->filter_mask[8] = mac_mask[3]; - (*secfilter)->filter_mask[9] = mac_mask[2]; - (*secfilter)->filter_mask[10] = mac_mask[1]; - (*secfilter)->filter_mask[11]=mac_mask[0]; - - dprintk("%s: filter mac=%02x %02x %02x %02x %02x %02x\n", - dev->name, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - dprintk("%s: filter mask=%02x %02x %02x %02x %02x %02x\n", - dev->name, mac_mask[0], mac_mask[1], mac_mask[2], - mac_mask[3], mac_mask[4], mac_mask[5]); - - return 0; -} - -static int dvb_net_feed_start(struct net_device *dev) -{ - int ret = 0, i; - struct dvb_net_priv *priv = netdev_priv(dev); - struct dmx_demux *demux = priv->demux; - unsigned char *mac = (unsigned char *) dev->dev_addr; - - dprintk("%s: rx_mode %i\n", __func__, priv->rx_mode); - mutex_lock(&priv->mutex); - if (priv->tsfeed || priv->secfeed || priv->secfilter || priv->multi_secfilter[0]) - printk("%s: BUG %d\n", __func__, __LINE__); - - priv->secfeed=NULL; - priv->secfilter=NULL; - priv->tsfeed = NULL; - - if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { - dprintk("%s: alloc secfeed\n", __func__); - ret=demux->allocate_section_feed(demux, &priv->secfeed, - dvb_net_sec_callback); - if (ret<0) { - printk("%s: could not allocate section feed\n", dev->name); - goto error; - } - - ret = priv->secfeed->set(priv->secfeed, priv->pid, 32768, 1); - - if (ret<0) { - printk("%s: could not set section feed\n", dev->name); - priv->demux->release_section_feed(priv->demux, priv->secfeed); - priv->secfeed=NULL; - goto error; - } - - if (priv->rx_mode != RX_MODE_PROMISC) { - dprintk("%s: set secfilter\n", __func__); - dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_normal); - } - - switch (priv->rx_mode) { - case RX_MODE_MULTI: - for (i = 0; i < priv->multi_num; i++) { - dprintk("%s: set multi_secfilter[%d]\n", __func__, i); - dvb_net_filter_sec_set(dev, &priv->multi_secfilter[i], - priv->multi_macs[i], mask_normal); - } - break; - case RX_MODE_ALL_MULTI: - priv->multi_num=1; - dprintk("%s: set multi_secfilter[0]\n", __func__); - dvb_net_filter_sec_set(dev, &priv->multi_secfilter[0], - mac_allmulti, mask_allmulti); - break; - case RX_MODE_PROMISC: - priv->multi_num=0; - dprintk("%s: set secfilter\n", __func__); - dvb_net_filter_sec_set(dev, &priv->secfilter, mac, mask_promisc); - break; - } - - dprintk("%s: start filtering\n", __func__); - priv->secfeed->start_filtering(priv->secfeed); - } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { - struct timespec timeout = { 0, 10000000 }; // 10 msec - - /* we have payloads encapsulated in TS */ - dprintk("%s: alloc tsfeed\n", __func__); - ret = demux->allocate_ts_feed(demux, &priv->tsfeed, dvb_net_ts_callback); - if (ret < 0) { - printk("%s: could not allocate ts feed\n", dev->name); - goto error; - } - - /* Set netdevice pointer for ts decaps callback. */ - priv->tsfeed->priv = (void *)dev; - ret = priv->tsfeed->set(priv->tsfeed, - priv->pid, /* pid */ - TS_PACKET, /* type */ - DMX_TS_PES_OTHER, /* pes type */ - 32768, /* circular buffer size */ - timeout /* timeout */ - ); - - if (ret < 0) { - printk("%s: could not set ts feed\n", dev->name); - priv->demux->release_ts_feed(priv->demux, priv->tsfeed); - priv->tsfeed = NULL; - goto error; - } - - dprintk("%s: start filtering\n", __func__); - priv->tsfeed->start_filtering(priv->tsfeed); - } else - ret = -EINVAL; - -error: - mutex_unlock(&priv->mutex); - return ret; -} - -static int dvb_net_feed_stop(struct net_device *dev) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - int i, ret = 0; - - dprintk("%s\n", __func__); - mutex_lock(&priv->mutex); - if (priv->feedtype == DVB_NET_FEEDTYPE_MPE) { - if (priv->secfeed) { - if (priv->secfeed->is_filtering) { - dprintk("%s: stop secfeed\n", __func__); - priv->secfeed->stop_filtering(priv->secfeed); - } - - if (priv->secfilter) { - dprintk("%s: release secfilter\n", __func__); - priv->secfeed->release_filter(priv->secfeed, - priv->secfilter); - priv->secfilter=NULL; - } - - for (i=0; i<priv->multi_num; i++) { - if (priv->multi_secfilter[i]) { - dprintk("%s: release multi_filter[%d]\n", - __func__, i); - priv->secfeed->release_filter(priv->secfeed, - priv->multi_secfilter[i]); - priv->multi_secfilter[i] = NULL; - } - } - - priv->demux->release_section_feed(priv->demux, priv->secfeed); - priv->secfeed = NULL; - } else - printk("%s: no feed to stop\n", dev->name); - } else if (priv->feedtype == DVB_NET_FEEDTYPE_ULE) { - if (priv->tsfeed) { - if (priv->tsfeed->is_filtering) { - dprintk("%s: stop tsfeed\n", __func__); - priv->tsfeed->stop_filtering(priv->tsfeed); - } - priv->demux->release_ts_feed(priv->demux, priv->tsfeed); - priv->tsfeed = NULL; - } - else - printk("%s: no ts feed to stop\n", dev->name); - } else - ret = -EINVAL; - mutex_unlock(&priv->mutex); - return ret; -} - - -static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - - if (priv->multi_num == DVB_NET_MULTICAST_MAX) - return -ENOMEM; - - memcpy(priv->multi_macs[priv->multi_num], mc->dmi_addr, 6); - - priv->multi_num++; - return 0; -} - - -static void wq_set_multicast_list (struct work_struct *work) -{ - struct dvb_net_priv *priv = - container_of(work, struct dvb_net_priv, set_multicast_list_wq); - struct net_device *dev = priv->net; - - dvb_net_feed_stop(dev); - priv->rx_mode = RX_MODE_UNI; - netif_addr_lock_bh(dev); - - if (dev->flags & IFF_PROMISC) { - dprintk("%s: promiscuous mode\n", dev->name); - priv->rx_mode = RX_MODE_PROMISC; - } else if ((dev->flags & IFF_ALLMULTI)) { - dprintk("%s: allmulti mode\n", dev->name); - priv->rx_mode = RX_MODE_ALL_MULTI; - } else if (dev->mc_count) { - int mci; - struct dev_mc_list *mc; - - dprintk("%s: set_mc_list, %d entries\n", - dev->name, dev->mc_count); - - priv->rx_mode = RX_MODE_MULTI; - priv->multi_num = 0; - - for (mci = 0, mc=dev->mc_list; - mci < dev->mc_count; - mc = mc->next, mci++) { - dvb_set_mc_filter(dev, mc); - } - } - - netif_addr_unlock_bh(dev); - dvb_net_feed_start(dev); -} - - -static void dvb_net_set_multicast_list (struct net_device *dev) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - schedule_work(&priv->set_multicast_list_wq); -} - - -static void wq_restart_net_feed (struct work_struct *work) -{ - struct dvb_net_priv *priv = - container_of(work, struct dvb_net_priv, restart_net_feed_wq); - struct net_device *dev = priv->net; - - if (netif_running(dev)) { - dvb_net_feed_stop(dev); - dvb_net_feed_start(dev); - } -} - - -static int dvb_net_set_mac (struct net_device *dev, void *p) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - struct sockaddr *addr=p; - - memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - - if (netif_running(dev)) - schedule_work(&priv->restart_net_feed_wq); - - return 0; -} - - -static int dvb_net_open(struct net_device *dev) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - - priv->in_use++; - dvb_net_feed_start(dev); - return 0; -} - - -static int dvb_net_stop(struct net_device *dev) -{ - struct dvb_net_priv *priv = netdev_priv(dev); - - priv->in_use--; - return dvb_net_feed_stop(dev); -} - -static const struct header_ops dvb_header_ops = { - .create = eth_header, - .parse = eth_header_parse, - .rebuild = eth_rebuild_header, -}; - - -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_mac_address = dvb_net_set_mac, - .ndo_change_mtu = eth_change_mtu, - .ndo_validate_addr = eth_validate_addr, -}; - -static void dvb_net_setup(struct net_device *dev) -{ - ether_setup(dev); - - dev->header_ops = &dvb_header_ops; - dev->netdev_ops = &dvb_netdev_ops; - dev->mtu = 4096; - dev->mc_count = 0; - - dev->flags |= IFF_NOARP; -} - -static int get_if(struct dvb_net *dvbnet) -{ - int i; - - for (i=0; i<DVB_NET_DEVICES_MAX; i++) - if (!dvbnet->state[i]) - break; - - if (i == DVB_NET_DEVICES_MAX) - return -1; - - dvbnet->state[i]=1; - return i; -} - -static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) -{ - struct net_device *net; - struct dvb_net_priv *priv; - int result; - int if_num; - - if (feedtype != DVB_NET_FEEDTYPE_MPE && feedtype != DVB_NET_FEEDTYPE_ULE) - return -EINVAL; - if ((if_num = get_if(dvbnet)) < 0) - return -EINVAL; - - net = alloc_netdev(sizeof(struct dvb_net_priv), "dvb", dvb_net_setup); - if (!net) - return -ENOMEM; - - if (dvbnet->dvbdev->id) - snprintf(net->name, IFNAMSIZ, "dvb%d%u%d", - dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num); - else - /* compatibility fix to keep dvb0_0 format */ - snprintf(net->name, IFNAMSIZ, "dvb%d_%d", - dvbnet->dvbdev->adapter->num, if_num); - - net->addr_len = 6; - memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6); - - dvbnet->device[if_num] = net; - - priv = netdev_priv(net); - priv->net = net; - priv->demux = dvbnet->demux; - priv->pid = pid; - priv->rx_mode = RX_MODE_UNI; - priv->need_pusi = 1; - priv->tscc = 0; - priv->feedtype = feedtype; - reset_ule(priv); - - INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list); - INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed); - mutex_init(&priv->mutex); - - net->base_addr = pid; - - if ((result = register_netdev(net)) < 0) { - dvbnet->device[if_num] = NULL; - free_netdev(net); - return result; - } - printk("dvb_net: created network interface %s\n", net->name); - - return if_num; -} - -static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) -{ - struct net_device *net = dvbnet->device[num]; - struct dvb_net_priv *priv; - - if (!dvbnet->state[num]) - return -EINVAL; - priv = netdev_priv(net); - if (priv->in_use) - return -EBUSY; - - dvb_net_stop(net); - flush_scheduled_work(); - printk("dvb_net: removed network interface %s\n", net->name); - unregister_netdev(net); - dvbnet->state[num]=0; - dvbnet->device[num] = NULL; - free_netdev(net); - - return 0; -} - -static int dvb_net_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_net *dvbnet = dvbdev->priv; - - if (((file->f_flags&O_ACCMODE)==O_RDONLY)) - return -EPERM; - - switch (cmd) { - case NET_ADD_IF: - { - struct dvb_net_if *dvbnetif = parg; - int result; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!try_module_get(dvbdev->adapter->module)) - return -EPERM; - - result=dvb_net_add_if(dvbnet, dvbnetif->pid, dvbnetif->feedtype); - if (result<0) { - module_put(dvbdev->adapter->module); - return result; - } - dvbnetif->if_num=result; - break; - } - case NET_GET_IF: - { - struct net_device *netdev; - struct dvb_net_priv *priv_data; - struct dvb_net_if *dvbnetif = parg; - - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) - return -EINVAL; - - netdev = dvbnet->device[dvbnetif->if_num]; - - priv_data = netdev_priv(netdev); - dvbnetif->pid=priv_data->pid; - dvbnetif->feedtype=priv_data->feedtype; - break; - } - case NET_REMOVE_IF: - { - int ret; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) - return -EINVAL; - ret = dvb_net_remove_if(dvbnet, (unsigned long) parg); - if (!ret) - module_put(dvbdev->adapter->module); - return ret; - } - - /* binary compatiblity cruft */ - case __NET_ADD_IF_OLD: - { - struct __dvb_net_if_old *dvbnetif = parg; - int result; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!try_module_get(dvbdev->adapter->module)) - return -EPERM; - - result=dvb_net_add_if(dvbnet, dvbnetif->pid, DVB_NET_FEEDTYPE_MPE); - if (result<0) { - module_put(dvbdev->adapter->module); - return result; - } - dvbnetif->if_num=result; - break; - } - case __NET_GET_IF_OLD: - { - struct net_device *netdev; - struct dvb_net_priv *priv_data; - struct __dvb_net_if_old *dvbnetif = parg; - - if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || - !dvbnet->state[dvbnetif->if_num]) - return -EINVAL; - - netdev = dvbnet->device[dvbnetif->if_num]; - - priv_data = netdev_priv(netdev); - dvbnetif->pid=priv_data->pid; - break; - } - default: - return -ENOTTY; - } - return 0; -} - -static int dvb_net_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return dvb_usercopy(inode, file, cmd, arg, dvb_net_do_ioctl); -} - -static int dvb_net_close(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct dvb_net *dvbnet = dvbdev->priv; - - dvb_generic_release(inode, file); - - if(dvbdev->users == 1 && dvbnet->exit == 1) { - fops_put(file->f_op); - file->f_op = NULL; - wake_up(&dvbdev->wait_queue); - } - return 0; -} - - -static struct file_operations dvb_net_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_net_ioctl, - .open = dvb_generic_open, - .release = dvb_net_close, -}; - -static struct dvb_device dvbdev_net = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_net_fops, -}; - - -void dvb_net_release (struct dvb_net *dvbnet) -{ - int i; - - dvbnet->exit = 1; - if (dvbnet->dvbdev->users < 1) - wait_event(dvbnet->dvbdev->wait_queue, - dvbnet->dvbdev->users==1); - - dvb_unregister_device(dvbnet->dvbdev); - - for (i=0; i<DVB_NET_DEVICES_MAX; i++) { - if (!dvbnet->state[i]) - continue; - dvb_net_remove_if(dvbnet, i); - } -} -EXPORT_SYMBOL(dvb_net_release); - - -int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, - struct dmx_demux *dmx) -{ - int i; - - dvbnet->demux = dmx; - - for (i=0; i<DVB_NET_DEVICES_MAX; i++) - dvbnet->state[i] = 0; - - dvb_register_device (adap, &dvbnet->dvbdev, &dvbdev_net, - dvbnet, DVB_DEVICE_NET); - - return 0; -} -EXPORT_SYMBOL(dvb_net_init); diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h deleted file mode 100644 index 3a3126cae03..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_net.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * dvb_net.h - * - * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _DVB_NET_H_ -#define _DVB_NET_H_ - -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/inetdevice.h> -#include <linux/etherdevice.h> -#include <linux/skbuff.h> - -#include "dvbdev.h" - -#define DVB_NET_DEVICES_MAX 10 - -struct dvb_net { - struct dvb_device *dvbdev; - struct net_device *device[DVB_NET_DEVICES_MAX]; - int state[DVB_NET_DEVICES_MAX]; - unsigned int exit:1; - struct dmx_demux *demux; -}; - - -void dvb_net_release(struct dvb_net *); -int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *); - -#endif diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb/dvb-core/dvb_ringbuffer.c deleted file mode 100644 index 584bbd194dc..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * - * dvb_ringbuffer.c: ring buffer implementation for the dvb driver - * - * Copyright (C) 2003 Oliver Endriss - * Copyright (C) 2004 Andrew de Quincey - * - * based on code originally found in av7110.c & dvb_ci.c: - * Copyright (C) 1999-2003 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - - - -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/sched.h> -#include <linux/string.h> -#include <asm/uaccess.h> - -#include "dvb_ringbuffer.h" - -#define PKT_READY 0 -#define PKT_DISPOSED 1 - - -void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) -{ - rbuf->pread=rbuf->pwrite=0; - rbuf->data=data; - rbuf->size=len; - rbuf->error=0; - - init_waitqueue_head(&rbuf->queue); - - spin_lock_init(&(rbuf->lock)); -} - - - -int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf) -{ - return (rbuf->pread==rbuf->pwrite); -} - - - -ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf) -{ - ssize_t free; - - free = rbuf->pread - rbuf->pwrite; - if (free <= 0) - free += rbuf->size; - return free-1; -} - - - -ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) -{ - ssize_t avail; - - avail = rbuf->pwrite - rbuf->pread; - if (avail < 0) - avail += rbuf->size; - return avail; -} - - - -void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) -{ - rbuf->pread = rbuf->pwrite; - rbuf->error = 0; -} - -void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) -{ - rbuf->pread = rbuf->pwrite = 0; - rbuf->error = 0; -} - -void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf) -{ - unsigned long flags; - - spin_lock_irqsave(&rbuf->lock, flags); - dvb_ringbuffer_flush(rbuf); - spin_unlock_irqrestore(&rbuf->lock, flags); - - wake_up(&rbuf->queue); -} - -ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len) -{ - size_t todo = len; - size_t split; - - split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; - if (split > 0) { - if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) - return -EFAULT; - buf += split; - todo -= split; - rbuf->pread = 0; - } - if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) - return -EFAULT; - - rbuf->pread = (rbuf->pread + todo) % rbuf->size; - - return len; -} - -void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len) -{ - size_t todo = len; - size_t split; - - split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; - if (split > 0) { - memcpy(buf, rbuf->data+rbuf->pread, split); - buf += split; - todo -= split; - rbuf->pread = 0; - } - memcpy(buf, rbuf->data+rbuf->pread, todo); - - rbuf->pread = (rbuf->pread + todo) % rbuf->size; -} - - -ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) -{ - size_t todo = len; - size_t split; - - split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0; - - if (split > 0) { - memcpy(rbuf->data+rbuf->pwrite, buf, split); - buf += split; - todo -= split; - rbuf->pwrite = 0; - } - memcpy(rbuf->data+rbuf->pwrite, buf, todo); - rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; - - return len; -} - -ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len) -{ - int status; - ssize_t oldpwrite = rbuf->pwrite; - - DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8); - DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff); - DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY); - status = dvb_ringbuffer_write(rbuf, buf, len); - - if (status < 0) rbuf->pwrite = oldpwrite; - return status; -} - -ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8 __user *buf, size_t len) -{ - size_t todo; - size_t split; - size_t pktlen; - - pktlen = rbuf->data[idx] << 8; - pktlen |= rbuf->data[(idx + 1) % rbuf->size]; - if (offset > pktlen) return -EINVAL; - if ((offset + len) > pktlen) len = pktlen - offset; - - idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size; - todo = len; - split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; - if (split > 0) { - if (copy_to_user(buf, rbuf->data+idx, split)) - return -EFAULT; - buf += split; - todo -= split; - idx = 0; - } - if (copy_to_user(buf, rbuf->data+idx, todo)) - return -EFAULT; - - return len; -} - -ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8* buf, size_t len) -{ - size_t todo; - size_t split; - size_t pktlen; - - pktlen = rbuf->data[idx] << 8; - pktlen |= rbuf->data[(idx + 1) % rbuf->size]; - if (offset > pktlen) return -EINVAL; - if ((offset + len) > pktlen) len = pktlen - offset; - - idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size; - todo = len; - split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; - if (split > 0) { - memcpy(buf, rbuf->data+idx, split); - buf += split; - todo -= split; - idx = 0; - } - memcpy(buf, rbuf->data+idx, todo); - return len; -} - -void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx) -{ - size_t pktlen; - - rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED; - - // clean up disposed packets - while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { - if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { - pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; - pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); - DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); - } else { - // first packet is not disposed, so we stop cleaning now - break; - } - } -} - -ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen) -{ - int consumed; - int curpktlen; - int curpktstatus; - - if (idx == -1) { - idx = rbuf->pread; - } else { - curpktlen = rbuf->data[idx] << 8; - curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; - idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; - } - - consumed = (idx - rbuf->pread) % rbuf->size; - - while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) { - - curpktlen = rbuf->data[idx] << 8; - curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; - curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; - - if (curpktstatus == PKT_READY) { - *pktlen = curpktlen; - return idx; - } - - consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; - idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; - } - - // no packets available - return -1; -} - - - -EXPORT_SYMBOL(dvb_ringbuffer_init); -EXPORT_SYMBOL(dvb_ringbuffer_empty); -EXPORT_SYMBOL(dvb_ringbuffer_free); -EXPORT_SYMBOL(dvb_ringbuffer_avail); -EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); -EXPORT_SYMBOL(dvb_ringbuffer_read_user); -EXPORT_SYMBOL(dvb_ringbuffer_read); -EXPORT_SYMBOL(dvb_ringbuffer_write); diff --git a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb/dvb-core/dvb_ringbuffer.h deleted file mode 100644 index 41f04dae69b..00000000000 --- a/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * - * dvb_ringbuffer.h: ring buffer implementation for the dvb driver - * - * Copyright (C) 2003 Oliver Endriss - * Copyright (C) 2004 Andrew de Quincey - * - * based on code originally found in av7110.c & dvb_ci.c: - * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef _DVB_RINGBUFFER_H_ -#define _DVB_RINGBUFFER_H_ - -#include <linux/spinlock.h> -#include <linux/wait.h> - -struct dvb_ringbuffer { - u8 *data; - ssize_t size; - ssize_t pread; - ssize_t pwrite; - int error; - - wait_queue_head_t queue; - spinlock_t lock; -}; - -#define DVB_RINGBUFFER_PKTHDRSIZE 3 - - -/* -** Notes: -** ------ -** (1) For performance reasons read and write routines don't check buffer sizes -** and/or number of bytes free/available. This has to be done before these -** routines are called. For example: -** -** *** write <buflen> bytes *** -** free = dvb_ringbuffer_free(rbuf); -** if (free >= buflen) -** count = dvb_ringbuffer_write(rbuf, buffer, buflen); -** else -** ... -** -** *** read min. 1000, max. <bufsize> bytes *** -** avail = dvb_ringbuffer_avail(rbuf); -** if (avail >= 1000) -** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); -** else -** ... -** -** (2) If there is exactly one reader and one writer, there is no need -** to lock read or write operations. -** Two or more readers must be locked against each other. -** Flushing the buffer counts as a read operation. -** Resetting the buffer counts as a read and write operation. -** Two or more writers must be locked against each other. -*/ - -/* initialize ring buffer, lock and queue */ -extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len); - -/* test whether buffer is empty */ -extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf); - -/* return the number of free bytes in the buffer */ -extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf); - -/* return the number of bytes waiting in the buffer */ -extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf); - - -/* -** Reset the read and write pointers to zero and flush the buffer -** This counts as a read and write operation -*/ -extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf); - - -/* read routines & macros */ -/* ---------------------- */ -/* flush buffer */ -extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf); - -/* flush buffer protected by spinlock and wake-up waiting task(s) */ -extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); - -/* peek at byte <offs> in the buffer */ -#define DVB_RINGBUFFER_PEEK(rbuf,offs) \ - (rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size] - -/* advance read ptr by <num> bytes */ -#define DVB_RINGBUFFER_SKIP(rbuf,num) \ - (rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size - -/* -** read <len> bytes from ring buffer into <buf> -** <usermem> specifies whether <buf> resides in user space -** returns number of bytes transferred or -EFAULT -*/ -extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, - u8 __user *buf, size_t len); -extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, - u8 *buf, size_t len); - - -/* write routines & macros */ -/* ----------------------- */ -/* write single byte to ring buffer */ -#define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte) \ - { (rbuf)->data[(rbuf)->pwrite]=(byte); \ - (rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; } -/* -** write <len> bytes to ring buffer -** <usermem> specifies whether <buf> resides in user space -** returns number of bytes transferred or -EFAULT -*/ -extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, - size_t len); - - -/** - * Write a packet into the ringbuffer. - * - * <rbuf> Ringbuffer to write to. - * <buf> Buffer to write. - * <len> Length of buffer (currently limited to 65535 bytes max). - * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. - */ -extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, - size_t len); - -/** - * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this - * does NOT update the read pointer in the ringbuffer. You must use - * dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required. - * - * <rbuf> Ringbuffer concerned. - * <idx> Packet index as returned by dvb_ringbuffer_pkt_next(). - * <offset> Offset into packet to read from. - * <buf> Destination buffer for data. - * <len> Size of destination buffer. - * <usermem> Set to 1 if <buf> is in userspace. - * returns Number of bytes read, or -EFAULT. - */ -extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8 __user *buf, size_t len); -extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8 *buf, size_t len); - -/** - * Dispose of a packet in the ring buffer. - * - * <rbuf> Ring buffer concerned. - * <idx> Packet index as returned by dvb_ringbuffer_pkt_next(). - */ -extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx); - -/** - * Get the index of the next packet in a ringbuffer. - * - * <rbuf> Ringbuffer concerned. - * <idx> Previous packet index, or -1 to return the first packet index. - * <pktlen> On success, will be updated to contain the length of the packet in bytes. - * returns Packet index (if >=0), or -1 if no packets available. - */ -extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen); - - -#endif /* _DVB_RINGBUFFER_H_ */ diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c deleted file mode 100644 index 6a32680dbb1..00000000000 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - * dvbdev.c - * - * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> - * & Marcus Metzler <marcus@convergence.de> - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/cdev.h> -#include <linux/mutex.h> -#include <linux/smp_lock.h> -#include "dvbdev.h" - -static int dvbdev_debug; - -module_param(dvbdev_debug, int, 0644); -MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off)."); - -#define dprintk if (dvbdev_debug) printk - -static LIST_HEAD(dvb_adapter_list); -static DEFINE_MUTEX(dvbdev_register_lock); - -static const char * const dnames[] = { - "video", "audio", "sec", "frontend", "demux", "dvr", "ca", - "net", "osd" -}; - -#ifdef CONFIG_DVB_DYNAMIC_MINORS -#define MAX_DVB_MINORS 256 -#define DVB_MAX_IDS MAX_DVB_MINORS -#else -#define DVB_MAX_IDS 4 -#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) -#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) -#endif - -static struct class *dvb_class; - -static struct dvb_device *dvb_minors[MAX_DVB_MINORS]; -static DECLARE_RWSEM(minor_rwsem); - -static int dvb_device_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev; - - lock_kernel(); - down_read(&minor_rwsem); - dvbdev = dvb_minors[iminor(inode)]; - - if (dvbdev && dvbdev->fops) { - int err = 0; - const struct file_operations *old_fops; - - file->private_data = dvbdev; - old_fops = file->f_op; - file->f_op = fops_get(dvbdev->fops); - if (file->f_op == NULL) { - file->f_op = old_fops; - goto fail; - } - if(file->f_op->open) - err = file->f_op->open(inode,file); - if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); - } - fops_put(old_fops); - up_read(&minor_rwsem); - unlock_kernel(); - return err; - } -fail: - up_read(&minor_rwsem); - unlock_kernel(); - return -ENODEV; -} - - -static const struct file_operations dvb_device_fops = -{ - .owner = THIS_MODULE, - .open = dvb_device_open, -}; - -static struct cdev dvb_device_cdev; - -int dvb_generic_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - - if (!dvbdev) - return -ENODEV; - - if (!dvbdev->users) - return -EBUSY; - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - if (!dvbdev->readers) - return -EBUSY; - dvbdev->readers--; - } else { - if (!dvbdev->writers) - return -EBUSY; - dvbdev->writers--; - } - - dvbdev->users--; - return 0; -} -EXPORT_SYMBOL(dvb_generic_open); - - -int dvb_generic_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - - if (!dvbdev) - return -ENODEV; - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - dvbdev->readers++; - } else { - dvbdev->writers++; - } - - dvbdev->users++; - return 0; -} -EXPORT_SYMBOL(dvb_generic_release); - - -int dvb_generic_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct dvb_device *dvbdev = file->private_data; - - if (!dvbdev) - return -ENODEV; - - if (!dvbdev->kernel_ioctl) - return -EINVAL; - - return dvb_usercopy (inode, file, cmd, arg, dvbdev->kernel_ioctl); -} -EXPORT_SYMBOL(dvb_generic_ioctl); - - -static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) -{ - u32 id = 0; - - while (id < DVB_MAX_IDS) { - struct dvb_device *dev; - list_for_each_entry(dev, &adap->device_list, list_head) - if (dev->type == type && dev->id == id) - goto skip; - return id; -skip: - id++; - } - return -ENFILE; -} - - -int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, - const struct dvb_device *template, void *priv, int type) -{ - struct dvb_device *dvbdev; - struct file_operations *dvbdevfops; - struct device *clsdev; - int minor; - int id; - - mutex_lock(&dvbdev_register_lock); - - if ((id = dvbdev_get_free_id (adap, type)) < 0){ - mutex_unlock(&dvbdev_register_lock); - *pdvbdev = NULL; - printk(KERN_ERR "%s: couldn't find free device id\n", __func__); - return -ENFILE; - } - - *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); - - if (!dvbdev){ - mutex_unlock(&dvbdev_register_lock); - return -ENOMEM; - } - - dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); - - if (!dvbdevfops){ - kfree (dvbdev); - mutex_unlock(&dvbdev_register_lock); - return -ENOMEM; - } - - memcpy(dvbdev, template, sizeof(struct dvb_device)); - dvbdev->type = type; - dvbdev->id = id; - dvbdev->adapter = adap; - dvbdev->priv = priv; - dvbdev->fops = dvbdevfops; - init_waitqueue_head (&dvbdev->wait_queue); - - memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations)); - dvbdev->fops->owner = adap->module; - - list_add_tail (&dvbdev->list_head, &adap->device_list); - - down_write(&minor_rwsem); -#ifdef CONFIG_DVB_DYNAMIC_MINORS - for (minor = 0; minor < MAX_DVB_MINORS; minor++) - if (dvb_minors[minor] == NULL) - break; - - if (minor == MAX_DVB_MINORS) { - kfree(dvbdevfops); - kfree(dvbdev); - mutex_unlock(&dvbdev_register_lock); - return -EINVAL; - } -#else - minor = nums2minor(adap->num, type, id); -#endif - - dvbdev->minor = minor; - dvb_minors[minor] = dvbdev; - up_write(&minor_rwsem); - - mutex_unlock(&dvbdev_register_lock); - - clsdev = device_create(dvb_class, adap->device, - MKDEV(DVB_MAJOR, minor), - dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id); - if (IS_ERR(clsdev)) { - printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", - __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); - return PTR_ERR(clsdev); - } - - dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", - adap->num, dnames[type], id, minor, minor); - - return 0; -} -EXPORT_SYMBOL(dvb_register_device); - - -void dvb_unregister_device(struct dvb_device *dvbdev) -{ - if (!dvbdev) - return; - - down_write(&minor_rwsem); - dvb_minors[dvbdev->minor] = NULL; - up_write(&minor_rwsem); - - device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); - - list_del (&dvbdev->list_head); - kfree (dvbdev->fops); - kfree (dvbdev); -} -EXPORT_SYMBOL(dvb_unregister_device); - -static int dvbdev_check_free_adapter_num(int num) -{ - struct list_head *entry; - list_for_each(entry, &dvb_adapter_list) { - struct dvb_adapter *adap; - adap = list_entry(entry, struct dvb_adapter, list_head); - if (adap->num == num) - return 0; - } - return 1; -} - -static int dvbdev_get_free_adapter_num (void) -{ - int num = 0; - - while (num < DVB_MAX_ADAPTERS) { - if (dvbdev_check_free_adapter_num(num)) - return num; - num++; - } - - return -ENFILE; -} - - -int dvb_register_adapter(struct dvb_adapter *adap, const char *name, - struct module *module, struct device *device, - short *adapter_nums) -{ - int i, num; - - mutex_lock(&dvbdev_register_lock); - - for (i = 0; i < DVB_MAX_ADAPTERS; ++i) { - num = adapter_nums[i]; - if (num >= 0 && num < DVB_MAX_ADAPTERS) { - /* use the one the driver asked for */ - if (dvbdev_check_free_adapter_num(num)) - break; - } else { - num = dvbdev_get_free_adapter_num(); - break; - } - num = -1; - } - - if (num < 0) { - mutex_unlock(&dvbdev_register_lock); - return -ENFILE; - } - - memset (adap, 0, sizeof(struct dvb_adapter)); - INIT_LIST_HEAD (&adap->device_list); - - printk(KERN_INFO "DVB: registering new adapter (%s)\n", name); - - adap->num = num; - adap->name = name; - adap->module = module; - adap->device = device; - adap->mfe_shared = 0; - adap->mfe_dvbdev = NULL; - mutex_init (&adap->mfe_lock); - - list_add_tail (&adap->list_head, &dvb_adapter_list); - - mutex_unlock(&dvbdev_register_lock); - - return num; -} -EXPORT_SYMBOL(dvb_register_adapter); - - -int dvb_unregister_adapter(struct dvb_adapter *adap) -{ - mutex_lock(&dvbdev_register_lock); - list_del (&adap->list_head); - mutex_unlock(&dvbdev_register_lock); - return 0; -} -EXPORT_SYMBOL(dvb_unregister_adapter); - -/* if the miracle happens and "generic_usercopy()" is included into - the kernel, then this can vanish. please don't make the mistake and - define this as video_usercopy(). this will introduce a dependecy - to the v4l "videodev.o" module, which is unnecessary for some - cards (ie. the budget dvb-cards don't need the v4l module...) */ -int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)) -{ - char sbuf[128]; - void *mbuf = NULL; - void *parg = NULL; - int err = -EINVAL; - - /* Copy arguments into temp kernel buffer */ - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: - /* - * For this command, the pointer is actually an integer - * argument. - */ - parg = (void *) arg; - break; - case _IOC_READ: /* some v4l ioctls are marked wrong ... */ - case _IOC_WRITE: - case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; - } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; - } - - err = -EFAULT; - if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) - goto out; - break; - } - - /* call driver */ - if ((err = func(inode, file, cmd, parg)) == -ENOIOCTLCMD) - err = -EINVAL; - - if (err < 0) - goto out; - - /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { - case _IOC_READ: - case (_IOC_WRITE | _IOC_READ): - if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; - break; - } - -out: - kfree(mbuf); - return err; -} - -static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - struct dvb_device *dvbdev = dev_get_drvdata(dev); - - add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); - add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); - add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); - return 0; -} - -static int __init init_dvbdev(void) -{ - int retval; - dev_t dev = MKDEV(DVB_MAJOR, 0); - - if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { - printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR); - return retval; - } - - cdev_init(&dvb_device_cdev, &dvb_device_fops); - if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) { - printk(KERN_ERR "dvb-core: unable register character device\n"); - goto error; - } - - dvb_class = class_create(THIS_MODULE, "dvb"); - if (IS_ERR(dvb_class)) { - retval = PTR_ERR(dvb_class); - goto error; - } - dvb_class->dev_uevent = dvb_uevent; - return 0; - -error: - cdev_del(&dvb_device_cdev); - unregister_chrdev_region(dev, MAX_DVB_MINORS); - return retval; -} - - -static void __exit exit_dvbdev(void) -{ - class_destroy(dvb_class); - cdev_del(&dvb_device_cdev); - unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); -} - -subsys_initcall(init_dvbdev); -module_exit(exit_dvbdev); - -MODULE_DESCRIPTION("DVB Core Driver"); -MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h deleted file mode 100644 index dca49cf962e..00000000000 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * dvbdev.h - * - * Copyright (C) 2000 Ralph Metzler & Marcus Metzler - * for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Lesser Public License - * as published by the Free Software Foundation; either version 2.1 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - */ - -#ifndef _DVBDEV_H_ -#define _DVBDEV_H_ - -#include <linux/types.h> -#include <linux/poll.h> -#include <linux/fs.h> -#include <linux/list.h> -#include <linux/smp_lock.h> - -#define DVB_MAJOR 212 - -#define DVB_MAX_ADAPTERS 8 - -#define DVB_UNSET (-1) - -#define DVB_DEVICE_VIDEO 0 -#define DVB_DEVICE_AUDIO 1 -#define DVB_DEVICE_SEC 2 -#define DVB_DEVICE_FRONTEND 3 -#define DVB_DEVICE_DEMUX 4 -#define DVB_DEVICE_DVR 5 -#define DVB_DEVICE_CA 6 -#define DVB_DEVICE_NET 7 -#define DVB_DEVICE_OSD 8 - -#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \ - static short adapter_nr[] = \ - {[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \ - module_param_array(adapter_nr, short, NULL, 0444); \ - MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers") - -struct dvb_adapter { - int num; - struct list_head list_head; - struct list_head device_list; - const char *name; - u8 proposed_mac [6]; - void* priv; - - struct device *device; - - struct module *module; - - int mfe_shared; /* indicates mutually exclusive frontends */ - struct dvb_device *mfe_dvbdev; /* frontend device in use */ - struct mutex mfe_lock; /* access lock for thread creation */ -}; - - -struct dvb_device { - struct list_head list_head; - struct file_operations *fops; - struct dvb_adapter *adapter; - int type; - int minor; - u32 id; - - /* in theory, 'users' can vanish now, - but I don't want to change too much now... */ - int readers; - int writers; - int users; - - wait_queue_head_t wait_queue; - /* don't really need those !? -- FIXME: use video_usercopy */ - int (*kernel_ioctl)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg); - - void *priv; -}; - - -extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name, - struct module *module, struct device *device, - short *adapter_nums); -extern int dvb_unregister_adapter (struct dvb_adapter *adap); - -extern int dvb_register_device (struct dvb_adapter *adap, - struct dvb_device **pdvbdev, - const struct dvb_device *template, - void *priv, - int type); - -extern void dvb_unregister_device (struct dvb_device *dvbdev); - -extern int dvb_generic_open (struct inode *inode, struct file *file); -extern int dvb_generic_release (struct inode *inode, struct file *file); -extern int dvb_generic_ioctl (struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg); - -/* we don't mess with video_usercopy() any more, -we simply define out own dvb_usercopy(), which will hopefully become -generic_usercopy() someday... */ - -extern int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)); - -/** generic DVB attach function. */ -#ifdef CONFIG_MEDIA_ATTACH -#define dvb_attach(FUNCTION, ARGS...) ({ \ - void *__r = NULL; \ - typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ - if (__a) { \ - __r = (void *) __a(ARGS); \ - if (__r == NULL) \ - symbol_put(FUNCTION); \ - } else { \ - printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \ - } \ - __r; \ -}) - -#else -#define dvb_attach(FUNCTION, ARGS...) ({ \ - FUNCTION(ARGS); \ -}) - -#endif - -#endif /* #ifndef _DVBDEV_H_ */ diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig deleted file mode 100644 index 49f7b20c25d..00000000000 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ /dev/null @@ -1,301 +0,0 @@ -config DVB_USB - tristate "Support for various USB DVB devices" - depends on DVB_CORE && USB && I2C && INPUT - help - By enabling this you will be able to choose the various supported - USB1.1 and USB2.0 DVB devices. - - Almost every USB device needs a firmware, please look into - <file:Documentation/dvb/README.dvb-usb>. - - For a complete list of supported USB devices see the LinuxTV DVB Wiki: - <http://www.linuxtv.org/wiki/index.php/DVB_USB> - - Say Y if you own a USB DVB device. - -config DVB_USB_DEBUG - bool "Enable extended debug support for all DVB-USB devices" - depends on DVB_USB - help - Say Y if you want to enable debugging. See modinfo dvb-usb (and the - appropriate drivers) for debug levels. - -config DVB_USB_A800 - tristate "AVerMedia AverTV DVB-T USB 2.0 (A800)" - depends on DVB_USB - select DVB_DIB3000MC - select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver. - -config DVB_USB_DIBUSB_MB - tristate "DiBcom USB DVB-T devices (based on the DiB3000M-B) (see help for device list)" - depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_DIB3000MB - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - help - Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by - DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator. - - For an up-to-date list of devices supported by this driver, have a look - on the Linux-DVB Wiki at www.linuxtv.org. - - Say Y if you own such a device and want to use it. You should build it as - a module. - -config DVB_USB_DIBUSB_MB_FAULTY - bool "Support faulty USB IDs" - depends on DVB_USB_DIBUSB_MB - help - Support for faulty USB IDs due to an invalid EEPROM on some Artec devices. - -config DVB_USB_DIBUSB_MC - tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" - depends on DVB_USB - select DVB_DIB3000MC - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - help - Support for USB2.0 DVB-T receivers based on reference designs made by - DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator. - - For an up-to-date list of devices supported by this driver, have a look - on the Linux-DVB Wiki at www.linuxtv.org. - - Say Y if you own such a device and want to use it. You should build it as - a module. - -config DVB_USB_DIB0700 - tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)" - depends on DVB_USB - select DVB_DIB7000P - select DVB_DIB7000M - select DVB_DIB3000MC - select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_TUNER_DIB0070 - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE - help - Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The - USB bridge is also present in devices having the DiB7700 DVB-T-USB - silicon. This chip can be found in devices offered by Hauppauge, - Avermedia and other big and small companies. - - For an up-to-date list of devices supported by this driver, have a look - on the Linux-DVB Wiki at www.linuxtv.org. - - Say Y if you own such a device and want to use it. You should build it as - a module. - -config DVB_USB_UMT_010 - tristate "HanfTek UMT-010 DVB-T USB2.0 support" - depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_DIB3000MC - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. - -config DVB_USB_CXUSB - tristate "Conexant USB2.0 hybrid reference design support" - depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_CX22702 if !DVB_FE_CUSTOMISE - select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_MT352 if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the Conexant USB2.0 hybrid reference design. - Currently, only DVB and ATSC modes are supported, analog mode - shall be added in the future. Devices that require this module: - - Medion MD95700 hybrid USB2.0 device. - DViCO FusionHDTV (Bluebird) USB2.0 devices - -config DVB_USB_M920X - tristate "Uli m920x DVB-T USB2.0 support" - depends on DVB_USB - select DVB_MT352 if !DVB_FE_CUSTOMISE - select DVB_TDA1004X if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver. - Currently, only devices with a product id of - "DTV USB MINI" (in cold state) are supported. - Firmware required. - -config DVB_USB_GL861 - tristate "Genesys Logic GL861 USB2.0 support" - depends on DVB_USB - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0 - receiver with USB ID 0db0:5581. - -config DVB_USB_AU6610 - tristate "Alcor Micro AU6610 USB2.0 support" - depends on DVB_USB - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver. - -config DVB_USB_DIGITV - tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" - depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_NXT6000 if !DVB_FE_CUSTOMISE - select DVB_MT352 if !DVB_FE_CUSTOMISE - help - Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. - -config DVB_USB_VP7045 - tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support" - depends on DVB_USB - help - Say Y here to support the - - TwinhanDTV Alpha (stick) (VP-7045), - TwinhanDTV MagicBox II (VP-7046), - DigitalNow TinyUSB 2 DVB-t, - DigitalRise USB 2.0 Ter (Beetle) and - TYPHOON DVB-T USB DRIVE - - DVB-T USB2.0 receivers. - -config DVB_USB_VP702X - tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support" - depends on DVB_USB - help - Say Y here to support the - - TwinhanDTV StarBox, - DigitalRise USB Starbox and - TYPHOON DVB-S USB 2.0 BOX - - DVB-S USB2.0 receivers. - -config DVB_USB_GP8PSK - tristate "GENPIX 8PSK->USB module support" - depends on DVB_USB - help - Say Y here to support the - GENPIX 8psk module - - DVB-S USB2.0 receivers. - -config DVB_USB_NOVA_T_USB2 - tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" - depends on DVB_USB - select DVB_DIB3000MC - select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver. - -config DVB_USB_TTUSB2 - tristate "Pinnacle 400e DVB-S USB2.0 support" - depends on DVB_USB - select DVB_TDA10086 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_TDA826X if !DVB_FE_CUSTOMISE - help - Say Y here to support the Pinnacle 400e DVB-S USB2.0 receiver. The - firmware protocol used by this module is similar to the one used by the - old ttusb-driver - that's why the module is called dvb-usb-ttusb2.ko. - -config DVB_USB_DTT200U - tristate "WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)" - depends on DVB_USB - help - Say Y here to support the WideView/Yakumo/Hama/Typhoon/Yuan DVB-T USB2.0 receiver. - - The receivers are also known as DTT200U (Yakumo) and UB300 (Yuan). - - The WT-220U and its clones are pen-sized. - -config DVB_USB_OPERA1 - tristate "Opera1 DVB-S USB2.0 receiver" - depends on DVB_USB - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_PLL if !DVB_FE_CUSTOMISE - help - Say Y here to support the Opera DVB-S USB2.0 receiver. - -config DVB_USB_AF9005 - tristate "Afatech AF9005 DVB-T USB1.1 support" - depends on DVB_USB && EXPERIMENTAL - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver - and the TerraTec Cinergy T USB XE (Rev.1) - -config DVB_USB_AF9005_REMOTE - tristate "Afatech AF9005 default remote control support" - depends on DVB_USB_AF9005 - help - Say Y here to support the default remote control decoding for the - Afatech AF9005 based receiver. - -config DVB_USB_DW2102 - tristate "DvbWorld DVB-S/S2 USB2.0 support" - depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_STV0288 if !DVB_FE_CUSTOMISE - select DVB_STB6000 if !DVB_FE_CUSTOMISE - select DVB_CX24116 if !DVB_FE_CUSTOMISE - select DVB_SI21XX if !DVB_FE_CUSTOMISE - help - Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers - and the TeVii S650. - -config DVB_USB_CINERGY_T2 - tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" - depends on DVB_USB - help - Support for "TerraTec CinergyT2" USB2.0 Highspeed DVB Receivers - - Say Y if you own such a device and want to use it. - -config DVB_USB_ANYSEE - tristate "Anysee DVB-T/C USB2.0 support" - depends on DVB_USB - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_MT352 if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE - help - Say Y here to support the Anysee E30, Anysee E30 Plus or - Anysee E30 C Plus DVB USB2.0 receiver. - -config DVB_USB_DTV5100 - tristate "AME DTV-5100 USB2.0 DVB-T support" - depends on DVB_USB - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver. - -config DVB_USB_AF9015 - tristate "Afatech AF9015 DVB-T USB2.0 support" - depends on DVB_USB && EXPERIMENTAL - select DVB_AF9013 - select DVB_PLL if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE - help - Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile deleted file mode 100644 index 3122b7cc2c2..00000000000 --- a/drivers/media/dvb/dvb-usb/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o -obj-$(CONFIG_DVB_USB) += dvb-usb.o - -dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o -obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o - -dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o -obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o - -dvb-usb-gp8psk-objs = gp8psk.o gp8psk-fe.o -obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.o - -dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o -obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o - -dvb-usb-dibusb-common-objs = dibusb-common.o - -dvb-usb-a800-objs = a800.o -obj-$(CONFIG_DVB_USB_A800) += dvb-usb-dibusb-common.o dvb-usb-a800.o - -dvb-usb-dibusb-mb-objs = dibusb-mb.o -obj-$(CONFIG_DVB_USB_DIBUSB_MB) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mb.o - -dvb-usb-dibusb-mc-objs = dibusb-mc.o -obj-$(CONFIG_DVB_USB_DIBUSB_MC) += dvb-usb-dibusb-common.o dvb-usb-dibusb-mc.o - -dvb-usb-nova-t-usb2-objs = nova-t-usb2.o -obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2.o - -dvb-usb-umt-010-objs = umt-010.o -obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o - -dvb-usb-m920x-objs = m920x.o -obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o - -dvb-usb-gl861-objs = gl861.o -obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o - -dvb-usb-au6610-objs = au6610.o -obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o - -dvb-usb-digitv-objs = digitv.o -obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o - -dvb-usb-cxusb-objs = cxusb.o -obj-$(CONFIG_DVB_USB_CXUSB) += dvb-usb-cxusb.o - -dvb-usb-ttusb2-objs = ttusb2.o -obj-$(CONFIG_DVB_USB_TTUSB2) += dvb-usb-ttusb2.o - -dvb-usb-dib0700-objs = dib0700_core.o dib0700_devices.o -obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o - -dvb-usb-opera-objs = opera1.o -obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o - - -dvb-usb-af9005-objs = af9005.o af9005-fe.o -obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o - -dvb-usb-af9005-remote-objs = af9005-remote.o -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-dw2102-objs = dw2102.o -obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o - -dvb-usb-dtv5100-objs = dtv5100.o -obj-$(CONFIG_DVB_USB_DTV5100) += dvb-usb-dtv5100.o - -dvb-usb-af9015-objs = af9015.o -obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o - -dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o -obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o - - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ -# due to tuner-xc3028 -EXTRA_CFLAGS += -Idrivers/media/common/tuners - diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c deleted file mode 100644 index dc8c8784caa..00000000000 --- a/drivers/media/dvb/dvb-usb/a800.c +++ /dev/null @@ -1,197 +0,0 @@ -/* DVB USB framework compliant Linux driver for the AVerMedia AverTV DVB-T - * USB2.0 (A800) DVB-T receiver. - * - * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) - * - * Thanks to - * - AVerMedia who kindly provided information and - * - Glen Harris who suffered from my mistakes during development. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dibusb.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (rc=1 (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define deb_rc(args...) dprintk(debug,0x01,args) - -static int a800_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - /* do nothing for the AVerMedia */ - return 0; -} - -/* assure to put cold to 0 for iManufacturer == 1 */ -static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, int *cold) -{ - *cold = udev->descriptor.iManufacturer != 1; - return 0; -} - -static struct dvb_usb_rc_key a800_rc_keys[] = { - { 0x02, 0x01, KEY_PROG1 }, /* SOURCE */ - { 0x02, 0x00, KEY_POWER }, /* POWER */ - { 0x02, 0x05, KEY_1 }, /* 1 */ - { 0x02, 0x06, KEY_2 }, /* 2 */ - { 0x02, 0x07, KEY_3 }, /* 3 */ - { 0x02, 0x09, KEY_4 }, /* 4 */ - { 0x02, 0x0a, KEY_5 }, /* 5 */ - { 0x02, 0x0b, KEY_6 }, /* 6 */ - { 0x02, 0x0d, KEY_7 }, /* 7 */ - { 0x02, 0x0e, KEY_8 }, /* 8 */ - { 0x02, 0x0f, KEY_9 }, /* 9 */ - { 0x02, 0x12, KEY_LEFT }, /* L / DISPLAY */ - { 0x02, 0x11, KEY_0 }, /* 0 */ - { 0x02, 0x13, KEY_RIGHT }, /* R / CH RTN */ - { 0x02, 0x17, KEY_PROG2 }, /* SNAP SHOT */ - { 0x02, 0x10, KEY_PROG3 }, /* 16-CH PREV */ - { 0x02, 0x1e, KEY_VOLUMEDOWN }, /* VOL DOWN */ - { 0x02, 0x0c, KEY_ZOOM }, /* FULL SCREEN */ - { 0x02, 0x1f, KEY_VOLUMEUP }, /* VOL UP */ - { 0x02, 0x14, KEY_MUTE }, /* MUTE */ - { 0x02, 0x08, KEY_AUDIO }, /* AUDIO */ - { 0x02, 0x19, KEY_RECORD }, /* RECORD */ - { 0x02, 0x18, KEY_PLAY }, /* PLAY */ - { 0x02, 0x1b, KEY_STOP }, /* STOP */ - { 0x02, 0x1a, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ - { 0x02, 0x1d, KEY_BACK }, /* << / RED */ - { 0x02, 0x1c, KEY_FORWARD }, /* >> / YELLOW */ - { 0x02, 0x03, KEY_TEXT }, /* TELETEXT */ - { 0x02, 0x04, KEY_EPG }, /* EPG */ - { 0x02, 0x15, KEY_MENU }, /* MENU */ - - { 0x03, 0x03, KEY_CHANNELUP }, /* CH UP */ - { 0x03, 0x02, KEY_CHANNELDOWN }, /* CH DOWN */ - { 0x03, 0x01, KEY_FIRST }, /* |<< / GREEN */ - { 0x03, 0x00, KEY_LAST }, /* >>| / BLUE */ - -}; - -static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key[5]; - if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0), - 0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5, - 2000) != 5) - return -ENODEV; - - /* call the universal NEC remote processor, to find out the key's state and event */ - dvb_usb_nec_rc_key_to_event(d,key,event,state); - if (key[0] != 0) - deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); - return 0; -} - -/* USB Driver stuff */ -static struct dvb_usb_device_properties a800_properties; - -static int a800_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &a800_properties, - THIS_MODULE, NULL, adapter_nr); -} - -/* do not change the order of the ID table */ -static struct usb_device_id a800_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_COLD) }, -/* 01 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_DVBT_USB2_WARM) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, a800_table); - -static struct dvb_usb_device_properties a800_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-avertv-a800-02.fw", - - .num_adapters = 1, - .adapter = { - { - .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, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - - .frontend_attach = dibusb_dib3000mc_frontend_attach, - .tuner_attach = dibusb_dib3000mc_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - - .size_of_priv = sizeof(struct dibusb_state), - }, - }, - - .power_ctrl = a800_power_ctrl, - .identify_state = a800_identify_state, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = a800_rc_keys, - .rc_key_map_size = ARRAY_SIZE(a800_rc_keys), - .rc_query = a800_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - .num_device_descs = 1, - .devices = { - { "AVerMedia AverTV DVB-T USB 2.0 (A800)", - { &a800_table[0], NULL }, - { &a800_table[1], NULL }, - }, - } -}; - -static struct usb_driver a800_driver = { - .name = "dvb_usb_a800", - .probe = a800_probe, - .disconnect = dvb_usb_device_exit, - .id_table = a800_table, -}; - -/* module stuff */ -static int __init a800_module_init(void) -{ - int result; - if ((result = usb_register(&a800_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit a800_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&a800_driver); -} - -module_init (a800_module_init); -module_exit (a800_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("AVerMedia AverTV DVB-T USB 2.0 (A800)"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c deleted file mode 100644 index b1a9c4cdec9..00000000000 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ /dev/null @@ -1,1488 +0,0 @@ -/* Frontend part of the Linux driver for the Afatech 9005 - * USB1.1 DVB-T receiver. - * - * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "af9005.h" -#include "af9005-script.h" -#include "mt2060.h" -#include "qt1010.h" -#include <asm/div64.h> - -struct af9005_fe_state { - struct dvb_usb_device *d; - fe_status_t stat; - - /* retraining parameters */ - u32 original_fcw; - u16 original_rf_top; - u16 original_if_top; - u16 original_if_min; - u16 original_aci0_if_top; - u16 original_aci1_if_top; - u16 original_aci0_if_min; - u8 original_if_unplug_th; - u8 original_rf_unplug_th; - u8 original_dtop_if_unplug_th; - u8 original_dtop_rf_unplug_th; - - /* statistics */ - u32 pre_vit_error_count; - u32 pre_vit_bit_count; - u32 ber; - u32 post_vit_error_count; - u32 post_vit_bit_count; - u32 unc; - u16 abort_count; - - int opened; - int strong; - unsigned long next_status_check; - struct dvb_frontend frontend; -}; - -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)); -} - -static int af9005_read_word_agc(struct dvb_usb_device *d, u16 reghi, - u16 reglo, u8 pos, u8 len, u16 * value) -{ - int ret; - u8 temp0, temp1; - - if ((ret = af9005_read_ofdm_register(d, reglo, &temp0))) - return ret; - if ((ret = af9005_read_ofdm_register(d, reghi, &temp1))) - return ret; - switch (pos) { - case 0: - *value = ((u16) (temp1 & 0x03) << 8) + (u16) temp0; - break; - case 2: - *value = ((u16) (temp1 & 0x0C) << 6) + (u16) temp0; - break; - case 4: - *value = ((u16) (temp1 & 0x30) << 4) + (u16) temp0; - break; - case 6: - *value = ((u16) (temp1 & 0xC0) << 2) + (u16) temp0; - break; - default: - err("invalid pos in read word agc"); - return -EINVAL; - } - return 0; - -} - -static int af9005_is_fecmon_available(struct dvb_frontend *fe, int *available) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - u8 temp; - - *available = false; - - ret = af9005_read_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en, - fec_vtb_rsd_mon_en_pos, - fec_vtb_rsd_mon_en_len, &temp); - if (ret) - return ret; - if (temp & 1) { - ret = - af9005_read_register_bits(state->d, - xd_p_reg_ofsm_read_rbc_en, - reg_ofsm_read_rbc_en_pos, - reg_ofsm_read_rbc_en_len, &temp); - if (ret) - return ret; - if ((temp & 1) == 0) - *available = true; - - } - return 0; -} - -static int af9005_get_post_vit_err_cw_count(struct dvb_frontend *fe, - u32 * post_err_count, - u32 * post_cw_count, - u16 * abort_count) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - u32 err_count; - u32 cw_count; - u8 temp, temp0, temp1, temp2; - u16 loc_abort_count; - - *post_err_count = 0; - *post_cw_count = 0; - - /* check if error bit count is ready */ - ret = - af9005_read_register_bits(state->d, xd_r_fec_rsd_ber_rdy, - fec_rsd_ber_rdy_pos, fec_rsd_ber_rdy_len, - &temp); - if (ret) - return ret; - if (!temp) { - deb_info("rsd counter not ready\n"); - return 100; - } - /* get abort count */ - ret = - af9005_read_ofdm_register(state->d, - xd_r_fec_rsd_abort_packet_cnt_7_0, - &temp0); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, - xd_r_fec_rsd_abort_packet_cnt_15_8, - &temp1); - if (ret) - return ret; - loc_abort_count = ((u16) temp1 << 8) + temp0; - - /* get error count */ - ret = - af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_7_0, - &temp0); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_15_8, - &temp1); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_r_fec_rsd_bit_err_cnt_23_16, - &temp2); - if (ret) - return ret; - err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; - *post_err_count = err_count - (u32) loc_abort_count *8 * 8; - - /* get RSD packet number */ - ret = - af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0, - &temp0); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8, - &temp1); - if (ret) - return ret; - cw_count = ((u32) temp1 << 8) + temp0; - if (cw_count == 0) { - err("wrong RSD packet count"); - return -EIO; - } - deb_info("POST abort count %d err count %d rsd packets %d\n", - loc_abort_count, err_count, cw_count); - *post_cw_count = cw_count - (u32) loc_abort_count; - *abort_count = loc_abort_count; - return 0; - -} - -static int af9005_get_post_vit_ber(struct dvb_frontend *fe, - u32 * post_err_count, u32 * post_cw_count, - u16 * abort_count) -{ - u32 loc_cw_count = 0, loc_err_count; - u16 loc_abort_count; - int ret; - - ret = - af9005_get_post_vit_err_cw_count(fe, &loc_err_count, &loc_cw_count, - &loc_abort_count); - if (ret) - return ret; - *post_err_count = loc_err_count; - *post_cw_count = loc_cw_count * 204 * 8; - *abort_count = loc_abort_count; - - return 0; -} - -static int af9005_get_pre_vit_err_bit_count(struct dvb_frontend *fe, - u32 * pre_err_count, - u32 * pre_bit_count) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - u8 temp, temp0, temp1, temp2; - u32 super_frame_count, x, bits; - int ret; - - ret = - af9005_read_register_bits(state->d, xd_r_fec_vtb_ber_rdy, - fec_vtb_ber_rdy_pos, fec_vtb_ber_rdy_len, - &temp); - if (ret) - return ret; - if (!temp) { - deb_info("viterbi counter not ready\n"); - return 101; /* ERR_APO_VTB_COUNTER_NOT_READY; */ - } - ret = - af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_7_0, - &temp0); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_15_8, - &temp1); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_r_fec_vtb_err_bit_cnt_23_16, - &temp2); - if (ret) - return ret; - *pre_err_count = ((u32) temp2 << 16) + ((u32) temp1 << 8) + temp0; - - ret = - af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0, - &temp0); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, - &temp1); - if (ret) - return ret; - super_frame_count = ((u32) temp1 << 8) + temp0; - if (super_frame_count == 0) { - deb_info("super frame count 0\n"); - return 102; - } - - /* read fft mode */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, - reg_tpsd_txmod_pos, reg_tpsd_txmod_len, - &temp); - if (ret) - return ret; - if (temp == 0) { - /* 2K */ - x = 1512; - } else if (temp == 1) { - /* 8k */ - x = 6048; - } else { - err("Invalid fft mode"); - return -EINVAL; - } - - /* read constellation mode */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, - reg_tpsd_const_pos, reg_tpsd_const_len, - &temp); - if (ret) - return ret; - switch (temp) { - case 0: /* QPSK */ - bits = 2; - break; - case 1: /* QAM_16 */ - bits = 4; - break; - case 2: /* QAM_64 */ - bits = 6; - break; - default: - err("invalid constellation mode"); - return -EINVAL; - } - *pre_bit_count = super_frame_count * 68 * 4 * x * bits; - deb_info("PRE err count %d frame count %d bit count %d\n", - *pre_err_count, super_frame_count, *pre_bit_count); - return 0; -} - -static int af9005_reset_pre_viterbi(struct dvb_frontend *fe) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - - /* set super frame count to 1 */ - ret = - af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_7_0, - 1 & 0xff); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, xd_p_fec_super_frm_unit_15_8, - 1 >> 8); - if (ret) - return ret; - /* reset pre viterbi error count */ - ret = - af9005_write_register_bits(state->d, xd_p_fec_vtb_ber_rst, - fec_vtb_ber_rst_pos, fec_vtb_ber_rst_len, - 1); - - return ret; -} - -static int af9005_reset_post_viterbi(struct dvb_frontend *fe) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - - /* set packet unit */ - ret = - af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_7_0, - 10000 & 0xff); - if (ret) - return ret; - ret = - af9005_write_ofdm_register(state->d, xd_p_fec_rsd_packet_unit_15_8, - 10000 >> 8); - if (ret) - return ret; - /* reset post viterbi error count */ - ret = - af9005_write_register_bits(state->d, xd_p_fec_rsd_ber_rst, - fec_rsd_ber_rst_pos, fec_rsd_ber_rst_len, - 1); - - return ret; -} - -static int af9005_get_statistic(struct dvb_frontend *fe) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret, fecavailable; - u64 numerator, denominator; - - deb_info("GET STATISTIC\n"); - ret = af9005_is_fecmon_available(fe, &fecavailable); - if (ret) - return ret; - if (!fecavailable) { - deb_info("fecmon not available\n"); - return 0; - } - - ret = af9005_get_pre_vit_err_bit_count(fe, &state->pre_vit_error_count, - &state->pre_vit_bit_count); - if (ret == 0) { - af9005_reset_pre_viterbi(fe); - if (state->pre_vit_bit_count > 0) { - /* according to v 0.0.4 of the dvb api ber should be a multiple - of 10E-9 so we have to multiply the error count by - 10E9=1000000000 */ - numerator = - (u64) state->pre_vit_error_count * (u64) 1000000000; - denominator = (u64) state->pre_vit_bit_count; - state->ber = do_div(numerator, denominator); - } else { - state->ber = 0xffffffff; - } - } - - ret = af9005_get_post_vit_ber(fe, &state->post_vit_error_count, - &state->post_vit_bit_count, - &state->abort_count); - if (ret == 0) { - ret = af9005_reset_post_viterbi(fe); - state->unc += state->abort_count; - if (ret) - return ret; - } - return 0; -} - -static int af9005_fe_refresh_state(struct dvb_frontend *fe) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - if (time_after(jiffies, state->next_status_check)) { - deb_info("REFRESH STATE\n"); - - /* statistics */ - if (af9005_get_statistic(fe)) - err("get_statistic_failed"); - state->next_status_check = jiffies + 250 * HZ / 1000; - } - return 0; -} - -static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - u8 temp; - int ret; - - if (fe->ops.tuner_ops.release == NULL) - return -ENODEV; - - *stat = 0; - ret = af9005_read_register_bits(state->d, xd_p_agc_lock, - agc_lock_pos, agc_lock_len, &temp); - if (ret) - return ret; - if (temp) - *stat |= FE_HAS_SIGNAL; - - ret = af9005_read_register_bits(state->d, xd_p_fd_tpsd_lock, - fd_tpsd_lock_pos, fd_tpsd_lock_len, - &temp); - if (ret) - return ret; - if (temp) - *stat |= FE_HAS_CARRIER; - - ret = af9005_read_register_bits(state->d, - xd_r_mp2if_sync_byte_locked, - mp2if_sync_byte_locked_pos, - mp2if_sync_byte_locked_pos, &temp); - if (ret) - return ret; - if (temp) - *stat |= FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK; - if (state->opened) - af9005_led_control(state->d, *stat & FE_HAS_LOCK); - - ret = - af9005_read_register_bits(state->d, xd_p_reg_strong_sginal_detected, - reg_strong_sginal_detected_pos, - reg_strong_sginal_detected_len, &temp); - if (ret) - return ret; - if (temp != state->strong) { - deb_info("adjust for strong signal %d\n", temp); - state->strong = temp; - } - return 0; -} - -static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - if (fe->ops.tuner_ops.release == NULL) - return -ENODEV; - af9005_fe_refresh_state(fe); - *ber = state->ber; - return 0; -} - -static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - if (fe->ops.tuner_ops.release == NULL) - return -ENODEV; - af9005_fe_refresh_state(fe); - *unc = state->unc; - return 0; -} - -static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, - u16 * strength) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - u8 if_gain, rf_gain; - - if (fe->ops.tuner_ops.release == NULL) - return -ENODEV; - ret = - af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, - &rf_gain); - if (ret) - return ret; - ret = - af9005_read_ofdm_register(state->d, xd_r_reg_aagc_if_gain, - &if_gain); - if (ret) - return ret; - /* this value has no real meaning, but i don't have the tables that relate - the rf and if gain with the dbm, so I just scale the value */ - *strength = (512 - rf_gain - if_gain) << 7; - return 0; -} - -static int af9005_fe_read_snr(struct dvb_frontend *fe, u16 * snr) -{ - /* the snr can be derived from the ber and the constellation - but I don't think this kind of complex calculations belong - in the driver. I may be wrong.... */ - return -ENOSYS; -} - -static int af9005_fe_program_cfoe(struct dvb_usb_device *d, fe_bandwidth_t bw) -{ - u8 temp0, temp1, temp2, temp3, buf[4]; - int ret; - u32 NS_coeff1_2048Nu; - u32 NS_coeff1_8191Nu; - u32 NS_coeff1_8192Nu; - u32 NS_coeff1_8193Nu; - u32 NS_coeff2_2k; - u32 NS_coeff2_8k; - - switch (bw) { - case BANDWIDTH_6_MHZ: - NS_coeff1_2048Nu = 0x2ADB6DC; - NS_coeff1_8191Nu = 0xAB7313; - NS_coeff1_8192Nu = 0xAB6DB7; - NS_coeff1_8193Nu = 0xAB685C; - NS_coeff2_2k = 0x156DB6E; - NS_coeff2_8k = 0x55B6DC; - break; - - case BANDWIDTH_7_MHZ: - NS_coeff1_2048Nu = 0x3200001; - NS_coeff1_8191Nu = 0xC80640; - NS_coeff1_8192Nu = 0xC80000; - NS_coeff1_8193Nu = 0xC7F9C0; - NS_coeff2_2k = 0x1900000; - NS_coeff2_8k = 0x640000; - break; - - case BANDWIDTH_8_MHZ: - NS_coeff1_2048Nu = 0x3924926; - NS_coeff1_8191Nu = 0xE4996E; - NS_coeff1_8192Nu = 0xE49249; - NS_coeff1_8193Nu = 0xE48B25; - NS_coeff2_2k = 0x1C92493; - NS_coeff2_8k = 0x724925; - break; - default: - err("Invalid bandwith %d.", bw); - return -EINVAL; - } - - /* - * write NS_coeff1_2048Nu - */ - - temp0 = (u8) (NS_coeff1_2048Nu & 0x000000FF); - temp1 = (u8) ((NS_coeff1_2048Nu & 0x0000FF00) >> 8); - temp2 = (u8) ((NS_coeff1_2048Nu & 0x00FF0000) >> 16); - temp3 = (u8) ((NS_coeff1_2048Nu & 0x03000000) >> 24); - - /* big endian to make 8051 happy */ - buf[0] = temp3; - buf[1] = temp2; - buf[2] = temp1; - buf[3] = temp0; - - /* cfoe_NS_2k_coeff1_25_24 */ - ret = af9005_write_ofdm_register(d, 0xAE00, buf[0]); - if (ret) - return ret; - - /* cfoe_NS_2k_coeff1_23_16 */ - ret = af9005_write_ofdm_register(d, 0xAE01, buf[1]); - if (ret) - return ret; - - /* cfoe_NS_2k_coeff1_15_8 */ - ret = af9005_write_ofdm_register(d, 0xAE02, buf[2]); - if (ret) - return ret; - - /* cfoe_NS_2k_coeff1_7_0 */ - ret = af9005_write_ofdm_register(d, 0xAE03, buf[3]); - if (ret) - return ret; - - /* - * write NS_coeff2_2k - */ - - temp0 = (u8) ((NS_coeff2_2k & 0x0000003F)); - temp1 = (u8) ((NS_coeff2_2k & 0x00003FC0) >> 6); - temp2 = (u8) ((NS_coeff2_2k & 0x003FC000) >> 14); - temp3 = (u8) ((NS_coeff2_2k & 0x01C00000) >> 22); - - /* big endian to make 8051 happy */ - buf[0] = temp3; - buf[1] = temp2; - buf[2] = temp1; - buf[3] = temp0; - - ret = af9005_write_ofdm_register(d, 0xAE04, buf[0]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE05, buf[1]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE06, buf[2]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE07, buf[3]); - if (ret) - return ret; - - /* - * write NS_coeff1_8191Nu - */ - - temp0 = (u8) ((NS_coeff1_8191Nu & 0x000000FF)); - temp1 = (u8) ((NS_coeff1_8191Nu & 0x0000FF00) >> 8); - temp2 = (u8) ((NS_coeff1_8191Nu & 0x00FFC000) >> 16); - temp3 = (u8) ((NS_coeff1_8191Nu & 0x03000000) >> 24); - - /* big endian to make 8051 happy */ - buf[0] = temp3; - buf[1] = temp2; - buf[2] = temp1; - buf[3] = temp0; - - ret = af9005_write_ofdm_register(d, 0xAE08, buf[0]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE09, buf[1]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE0A, buf[2]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE0B, buf[3]); - if (ret) - return ret; - - /* - * write NS_coeff1_8192Nu - */ - - temp0 = (u8) (NS_coeff1_8192Nu & 0x000000FF); - temp1 = (u8) ((NS_coeff1_8192Nu & 0x0000FF00) >> 8); - temp2 = (u8) ((NS_coeff1_8192Nu & 0x00FFC000) >> 16); - temp3 = (u8) ((NS_coeff1_8192Nu & 0x03000000) >> 24); - - /* big endian to make 8051 happy */ - buf[0] = temp3; - buf[1] = temp2; - buf[2] = temp1; - buf[3] = temp0; - - ret = af9005_write_ofdm_register(d, 0xAE0C, buf[0]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE0D, buf[1]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE0E, buf[2]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE0F, buf[3]); - if (ret) - return ret; - - /* - * write NS_coeff1_8193Nu - */ - - temp0 = (u8) ((NS_coeff1_8193Nu & 0x000000FF)); - temp1 = (u8) ((NS_coeff1_8193Nu & 0x0000FF00) >> 8); - temp2 = (u8) ((NS_coeff1_8193Nu & 0x00FFC000) >> 16); - temp3 = (u8) ((NS_coeff1_8193Nu & 0x03000000) >> 24); - - /* big endian to make 8051 happy */ - buf[0] = temp3; - buf[1] = temp2; - buf[2] = temp1; - buf[3] = temp0; - - ret = af9005_write_ofdm_register(d, 0xAE10, buf[0]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE11, buf[1]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE12, buf[2]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE13, buf[3]); - if (ret) - return ret; - - /* - * write NS_coeff2_8k - */ - - temp0 = (u8) ((NS_coeff2_8k & 0x0000003F)); - temp1 = (u8) ((NS_coeff2_8k & 0x00003FC0) >> 6); - temp2 = (u8) ((NS_coeff2_8k & 0x003FC000) >> 14); - temp3 = (u8) ((NS_coeff2_8k & 0x01C00000) >> 22); - - /* big endian to make 8051 happy */ - buf[0] = temp3; - buf[1] = temp2; - buf[2] = temp1; - buf[3] = temp0; - - ret = af9005_write_ofdm_register(d, 0xAE14, buf[0]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE15, buf[1]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE16, buf[2]); - if (ret) - return ret; - - ret = af9005_write_ofdm_register(d, 0xAE17, buf[3]); - return ret; - -} - -static int af9005_fe_select_bw(struct dvb_usb_device *d, fe_bandwidth_t bw) -{ - u8 temp; - switch (bw) { - case BANDWIDTH_6_MHZ: - temp = 0; - break; - case BANDWIDTH_7_MHZ: - temp = 1; - break; - case BANDWIDTH_8_MHZ: - temp = 2; - break; - default: - err("Invalid bandwith %d.", bw); - return -EINVAL; - } - return af9005_write_register_bits(d, xd_g_reg_bw, reg_bw_pos, - reg_bw_len, temp); -} - -static int af9005_fe_power(struct dvb_frontend *fe, int on) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - u8 temp = on; - int ret; - deb_info("power %s tuner\n", on ? "on" : "off"); - ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0); - return ret; -} - -static struct mt2060_config af9005_mt2060_config = { - 0xC0 -}; - -static struct qt1010_config af9005_qt1010_config = { - 0xC4 -}; - -static int af9005_fe_init(struct dvb_frontend *fe) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - struct dvb_usb_adapter *adap = fe->dvb->priv; - int ret, i, scriptlen; - u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; - u8 buf[2]; - u16 if1; - - deb_info("in af9005_fe_init\n"); - - /* reset */ - deb_info("reset\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst_en, - 4, 1, 0x01))) - return ret; - if ((ret = af9005_write_ofdm_register(state->d, APO_REG_RESET, 0))) - return ret; - /* clear ofdm reset */ - deb_info("clear ofdm reset\n"); - for (i = 0; i < 150; i++) { - if ((ret = - af9005_read_ofdm_register(state->d, - xd_I2C_reg_ofdm_rst, &temp))) - return ret; - if (temp & (regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos)) - break; - msleep(10); - } - if (i == 150) - return -ETIMEDOUT; - - /*FIXME in the dump - write B200 A9 - write xd_g_reg_ofsm_clk 7 - read eepr c6 (2) - read eepr c7 (2) - misc ctrl 3 -> 1 - read eepr ca (6) - write xd_g_reg_ofsm_clk 0 - write B200 a1 - */ - ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa9); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x07); - if (ret) - return ret; - temp = 0x01; - ret = af9005_send_command(state->d, 0x03, &temp, 1, NULL, 0); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, xd_g_reg_ofsm_clk, 0x00); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, 0xb200, 0xa1); - if (ret) - return ret; - - temp = regmask[reg_ofdm_rst_len - 1] << reg_ofdm_rst_pos; - if ((ret = - af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, - reg_ofdm_rst_pos, reg_ofdm_rst_len, 1))) - return ret; - ret = af9005_write_register_bits(state->d, xd_I2C_reg_ofdm_rst, - reg_ofdm_rst_pos, reg_ofdm_rst_len, 0); - - if (ret) - return ret; - /* don't know what register aefc is, but this is what the windows driver does */ - ret = af9005_write_ofdm_register(state->d, 0xaefc, 0); - if (ret) - return ret; - - /* set stand alone chip */ - deb_info("set stand alone chip\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_p_reg_dca_stand_alone, - reg_dca_stand_alone_pos, - reg_dca_stand_alone_len, 1))) - return ret; - - /* set dca upper & lower chip */ - deb_info("set dca upper & lower chip\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_p_reg_dca_upper_chip, - reg_dca_upper_chip_pos, - reg_dca_upper_chip_len, 0))) - return ret; - if ((ret = - af9005_write_register_bits(state->d, xd_p_reg_dca_lower_chip, - reg_dca_lower_chip_pos, - reg_dca_lower_chip_len, 0))) - return ret; - - /* set 2wire master clock to 0x14 (for 60KHz) */ - deb_info("set 2wire master clock to 0x14 (for 60KHz)\n"); - if ((ret = - af9005_write_ofdm_register(state->d, xd_I2C_i2c_m_period, 0x14))) - return ret; - - /* clear dca enable chip */ - deb_info("clear dca enable chip\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_p_reg_dca_en, - reg_dca_en_pos, reg_dca_en_len, 0))) - return ret; - /* FIXME these are register bits, but I don't know which ones */ - ret = af9005_write_ofdm_register(state->d, 0xa16c, 1); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, 0xa3c1, 0); - if (ret) - return ret; - - /* init other parameters: program cfoe and select bandwith */ - deb_info("program cfoe\n"); - if ((ret = af9005_fe_program_cfoe(state->d, BANDWIDTH_6_MHZ))) - return ret; - /* set read-update bit for constellation */ - deb_info("set read-update bit for constellation\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_p_reg_feq_read_update, - reg_feq_read_update_pos, - reg_feq_read_update_len, 1))) - return ret; - - /* sample code has a set MPEG TS code here - but sniffing reveals that it doesn't do it */ - - /* set read-update bit to 1 for DCA constellation */ - deb_info("set read-update bit 1 for DCA constellation\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_p_reg_dca_read_update, - reg_dca_read_update_pos, - reg_dca_read_update_len, 1))) - return ret; - - /* enable fec monitor */ - deb_info("enable fec monitor\n"); - if ((ret = - af9005_write_register_bits(state->d, xd_p_fec_vtb_rsd_mon_en, - fec_vtb_rsd_mon_en_pos, - fec_vtb_rsd_mon_en_len, 1))) - return ret; - - /* FIXME should be register bits, I don't know which ones */ - ret = af9005_write_ofdm_register(state->d, 0xa601, 0); - - /* set api_retrain_never_freeze */ - deb_info("set api_retrain_never_freeze\n"); - if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) - return ret; - - /* load init script */ - deb_info("load init script\n"); - scriptlen = sizeof(script) / sizeof(RegDesc); - for (i = 0; i < scriptlen; i++) { - if ((ret = - af9005_write_register_bits(state->d, script[i].reg, - script[i].pos, - script[i].len, script[i].val))) - return ret; - /* save 3 bytes of original fcw */ - if (script[i].reg == 0xae18) - temp2 = script[i].val; - if (script[i].reg == 0xae19) - temp1 = script[i].val; - if (script[i].reg == 0xae1a) - temp0 = script[i].val; - - /* save original unplug threshold */ - if (script[i].reg == xd_p_reg_unplug_th) - state->original_if_unplug_th = script[i].val; - if (script[i].reg == xd_p_reg_unplug_rf_gain_th) - state->original_rf_unplug_th = script[i].val; - if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) - state->original_dtop_if_unplug_th = script[i].val; - if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) - state->original_dtop_rf_unplug_th = script[i].val; - - } - state->original_fcw = - ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; - - - /* save original TOPs */ - deb_info("save original TOPs\n"); - - /* RF TOP */ - ret = - af9005_read_word_agc(state->d, - xd_p_reg_aagc_rf_top_numerator_9_8, - xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, - &state->original_rf_top); - if (ret) - return ret; - - /* IF TOP */ - ret = - af9005_read_word_agc(state->d, - xd_p_reg_aagc_if_top_numerator_9_8, - xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, - &state->original_if_top); - if (ret) - return ret; - - /* ACI 0 IF TOP */ - ret = - af9005_read_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, - &state->original_aci0_if_top); - if (ret) - return ret; - - /* ACI 1 IF TOP */ - ret = - af9005_read_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, - &state->original_aci1_if_top); - if (ret) - return ret; - - /* attach tuner and init */ - if (fe->ops.tuner_ops.release == NULL) { - /* read tuner and board id from eeprom */ - ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); - if (ret) { - err("Impossible to read EEPROM\n"); - return ret; - } - deb_info("Tuner id %d, board id %d\n", buf[0], buf[1]); - switch (buf[0]) { - case 2: /* MT2060 */ - /* read if1 from eeprom */ - ret = af9005_read_eeprom(adap->dev, 0xc8, buf, 2); - if (ret) { - err("Impossible to read EEPROM\n"); - return ret; - } - if1 = (u16) (buf[0] << 8) + buf[1]; - if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, - &af9005_mt2060_config, if1) == NULL) { - deb_info("MT2060 attach failed\n"); - return -ENODEV; - } - break; - case 3: /* QT1010 */ - case 9: /* QT1010B */ - if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, - &af9005_qt1010_config) ==NULL) { - deb_info("QT1010 attach failed\n"); - return -ENODEV; - } - break; - default: - err("Unsupported tuner type %d", buf[0]); - return -ENODEV; - } - ret = fe->ops.tuner_ops.init(fe); - if (ret) - return ret; - } - - deb_info("profit!\n"); - return 0; -} - -static int af9005_fe_sleep(struct dvb_frontend *fe) -{ - return af9005_fe_power(fe, 0); -} - -static int af9005_ts_bus_ctrl(struct dvb_frontend *fe, int acquire) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - - if (acquire) { - state->opened++; - } else { - - state->opened--; - if (!state->opened) - af9005_led_control(state->d, 0); - } - return 0; -} - -static int af9005_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - u8 temp, temp0, temp1, temp2; - - deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, - fep->u.ofdm.bandwidth); - if (fe->ops.tuner_ops.release == NULL) { - err("Tuner not attached"); - return -ENODEV; - } - - deb_info("turn off led\n"); - /* not in the log */ - ret = af9005_led_control(state->d, 0); - if (ret) - return ret; - /* not sure about the bits */ - ret = af9005_write_register_bits(state->d, XD_MP2IF_MISC, 2, 1, 0); - if (ret) - return ret; - - /* set FCW to default value */ - deb_info("set FCW to default value\n"); - temp0 = (u8) (state->original_fcw & 0x000000ff); - temp1 = (u8) ((state->original_fcw & 0x0000ff00) >> 8); - temp2 = (u8) ((state->original_fcw & 0x00ff0000) >> 16); - ret = af9005_write_ofdm_register(state->d, 0xae1a, temp0); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, 0xae19, temp1); - if (ret) - return ret; - ret = af9005_write_ofdm_register(state->d, 0xae18, temp2); - if (ret) - return ret; - - /* restore original TOPs */ - deb_info("restore original TOPs\n"); - ret = - af9005_write_word_agc(state->d, - xd_p_reg_aagc_rf_top_numerator_9_8, - xd_p_reg_aagc_rf_top_numerator_7_0, 0, 2, - state->original_rf_top); - if (ret) - return ret; - ret = - af9005_write_word_agc(state->d, - xd_p_reg_aagc_if_top_numerator_9_8, - xd_p_reg_aagc_if_top_numerator_7_0, 0, 2, - state->original_if_top); - if (ret) - return ret; - ret = - af9005_write_word_agc(state->d, 0xA60E, 0xA60A, 4, 2, - state->original_aci0_if_top); - if (ret) - return ret; - ret = - af9005_write_word_agc(state->d, 0xA60E, 0xA60B, 6, 2, - state->original_aci1_if_top); - if (ret) - return ret; - - /* select bandwith */ - deb_info("select bandwidth"); - ret = af9005_fe_select_bw(state->d, fep->u.ofdm.bandwidth); - if (ret) - return ret; - ret = af9005_fe_program_cfoe(state->d, fep->u.ofdm.bandwidth); - if (ret) - return ret; - - /* clear easy mode flag */ - deb_info("clear easy mode flag\n"); - ret = af9005_write_ofdm_register(state->d, 0xaefd, 0); - if (ret) - return ret; - - /* set unplug threshold to original value */ - deb_info("set unplug threshold to original value\n"); - ret = - af9005_write_ofdm_register(state->d, xd_p_reg_unplug_th, - state->original_if_unplug_th); - if (ret) - return ret; - /* set tuner */ - deb_info("set tuner\n"); - ret = fe->ops.tuner_ops.set_params(fe, fep); - if (ret) - return ret; - - /* trigger ofsm */ - deb_info("trigger ofsm\n"); - temp = 0; - ret = af9005_write_tuner_registers(state->d, 0xffff, &temp, 1); - if (ret) - return ret; - - /* clear retrain and freeze flag */ - deb_info("clear retrain and freeze flag\n"); - ret = - af9005_write_register_bits(state->d, - xd_p_reg_api_retrain_request, - reg_api_retrain_request_pos, 2, 0); - if (ret) - return ret; - - /* reset pre viterbi and post viterbi registers and statistics */ - af9005_reset_pre_viterbi(fe); - af9005_reset_post_viterbi(fe); - state->pre_vit_error_count = 0; - state->pre_vit_bit_count = 0; - state->ber = 0; - state->post_vit_error_count = 0; - /* state->unc = 0; commented out since it should be ever increasing */ - state->abort_count = 0; - - state->next_status_check = jiffies; - state->strong = -1; - - return 0; -} - -static int af9005_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct af9005_fe_state *state = fe->demodulator_priv; - int ret; - u8 temp; - - /* mode */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_const, - reg_tpsd_const_pos, reg_tpsd_const_len, - &temp); - if (ret) - return ret; - deb_info("===== fe_get_frontend ==============\n"); - deb_info("CONSTELLATION "); - switch (temp) { - case 0: - fep->u.ofdm.constellation = QPSK; - deb_info("QPSK\n"); - break; - case 1: - fep->u.ofdm.constellation = QAM_16; - deb_info("QAM_16\n"); - break; - case 2: - fep->u.ofdm.constellation = QAM_64; - deb_info("QAM_64\n"); - break; - } - - /* tps hierarchy and alpha value */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_hier, - reg_tpsd_hier_pos, reg_tpsd_hier_len, - &temp); - if (ret) - return ret; - deb_info("HIERARCHY "); - switch (temp) { - case 0: - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - deb_info("NONE\n"); - break; - case 1: - fep->u.ofdm.hierarchy_information = HIERARCHY_1; - deb_info("1\n"); - break; - case 2: - fep->u.ofdm.hierarchy_information = HIERARCHY_2; - deb_info("2\n"); - break; - case 3: - fep->u.ofdm.hierarchy_information = HIERARCHY_4; - deb_info("4\n"); - break; - } - - /* high/low priority */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_dec_pri, - reg_dec_pri_pos, reg_dec_pri_len, &temp); - if (ret) - return ret; - /* if temp is set = high priority */ - deb_info("PRIORITY %s\n", temp ? "high" : "low"); - - /* high coderate */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_hpcr, - reg_tpsd_hpcr_pos, reg_tpsd_hpcr_len, - &temp); - if (ret) - return ret; - deb_info("CODERATE HP "); - switch (temp) { - case 0: - fep->u.ofdm.code_rate_HP = FEC_1_2; - deb_info("FEC_1_2\n"); - break; - case 1: - fep->u.ofdm.code_rate_HP = FEC_2_3; - deb_info("FEC_2_3\n"); - break; - case 2: - fep->u.ofdm.code_rate_HP = FEC_3_4; - deb_info("FEC_3_4\n"); - break; - case 3: - fep->u.ofdm.code_rate_HP = FEC_5_6; - deb_info("FEC_5_6\n"); - break; - case 4: - fep->u.ofdm.code_rate_HP = FEC_7_8; - deb_info("FEC_7_8\n"); - break; - } - - /* low coderate */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_lpcr, - reg_tpsd_lpcr_pos, reg_tpsd_lpcr_len, - &temp); - if (ret) - return ret; - deb_info("CODERATE LP "); - switch (temp) { - case 0: - fep->u.ofdm.code_rate_LP = FEC_1_2; - deb_info("FEC_1_2\n"); - break; - case 1: - fep->u.ofdm.code_rate_LP = FEC_2_3; - deb_info("FEC_2_3\n"); - break; - case 2: - fep->u.ofdm.code_rate_LP = FEC_3_4; - deb_info("FEC_3_4\n"); - break; - case 3: - fep->u.ofdm.code_rate_LP = FEC_5_6; - deb_info("FEC_5_6\n"); - break; - case 4: - fep->u.ofdm.code_rate_LP = FEC_7_8; - deb_info("FEC_7_8\n"); - break; - } - - /* guard interval */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_gi, - reg_tpsd_gi_pos, reg_tpsd_gi_len, &temp); - if (ret) - return ret; - deb_info("GUARD INTERVAL "); - switch (temp) { - case 0: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - deb_info("1_32\n"); - break; - case 1: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - deb_info("1_16\n"); - break; - case 2: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - deb_info("1_8\n"); - break; - case 3: - fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - deb_info("1_4\n"); - break; - } - - /* fft */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_tpsd_txmod, - reg_tpsd_txmod_pos, reg_tpsd_txmod_len, - &temp); - if (ret) - return ret; - deb_info("TRANSMISSION MODE "); - switch (temp) { - case 0: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - deb_info("2K\n"); - break; - case 1: - fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - deb_info("8K\n"); - break; - } - - /* bandwidth */ - ret = - af9005_read_register_bits(state->d, xd_g_reg_bw, reg_bw_pos, - reg_bw_len, &temp); - deb_info("BANDWIDTH "); - switch (temp) { - case 0: - fep->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - deb_info("6\n"); - break; - case 1: - fep->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - deb_info("7\n"); - break; - case 2: - fep->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - deb_info("8\n"); - break; - } - return 0; -} - -static void af9005_fe_release(struct dvb_frontend *fe) -{ - struct af9005_fe_state *state = - (struct af9005_fe_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops af9005_fe_ops; - -struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) -{ - struct af9005_fe_state *state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL); - if (state == NULL) - goto error; - - deb_info("attaching frontend af9005\n"); - - state->d = d; - state->opened = 0; - - memcpy(&state->frontend.ops, &af9005_fe_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; - error: - return NULL; -} - -static struct dvb_frontend_ops af9005_fe_ops = { - .info = { - .name = "AF9005 USB DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = af9005_fe_release, - - .init = af9005_fe_init, - .sleep = af9005_fe_sleep, - .ts_bus_ctrl = af9005_ts_bus_ctrl, - - .set_frontend = af9005_fe_set_frontend, - .get_frontend = af9005_fe_get_frontend, - - .read_status = af9005_fe_read_status, - .read_ber = af9005_fe_read_ber, - .read_signal_strength = af9005_fe_read_signal_strength, - .read_snr = af9005_fe_read_snr, - .read_ucblocks = af9005_fe_read_unc_blocks, -}; diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c deleted file mode 100644 index 7c596f92676..00000000000 --- a/drivers/media/dvb/dvb-usb/af9005-remote.c +++ /dev/null @@ -1,157 +0,0 @@ -/* DVB USB compliant Linux driver for the Afatech 9005 - * USB1.1 DVB-T receiver. - * - * Standard remote decode function - * - * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * see Documentation/dvb/REDME.dvb-usb for more information - */ -#include "af9005.h" -/* debug */ -static int dvb_usb_af9005_remote_debug; -module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644); -MODULE_PARM_DESC(debug, - "enable (1) or disable (0) debug messages." - DVB_USB_DEBUG_STATUS); - -#define deb_decode(args...) dprintk(dvb_usb_af9005_remote_debug,0x01,args) - -struct dvb_usb_rc_key af9005_rc_keys[] = { - - {0x01, 0xb7, KEY_POWER}, - {0x01, 0xa7, KEY_VOLUMEUP}, - {0x01, 0x87, KEY_CHANNELUP}, - {0x01, 0x7f, KEY_MUTE}, - {0x01, 0xbf, KEY_VOLUMEDOWN}, - {0x01, 0x3f, KEY_CHANNELDOWN}, - {0x01, 0xdf, KEY_1}, - {0x01, 0x5f, KEY_2}, - {0x01, 0x9f, KEY_3}, - {0x01, 0x1f, KEY_4}, - {0x01, 0xef, KEY_5}, - {0x01, 0x6f, KEY_6}, - {0x01, 0xaf, KEY_7}, - {0x01, 0x27, KEY_8}, - {0x01, 0x07, KEY_9}, - {0x01, 0xcf, KEY_ZOOM}, - {0x01, 0x4f, KEY_0}, - {0x01, 0x8f, KEY_GOTO}, /* marked jump on the remote */ - - {0x00, 0xbd, KEY_POWER}, - {0x00, 0x7d, KEY_VOLUMEUP}, - {0x00, 0xfd, KEY_CHANNELUP}, - {0x00, 0x9d, KEY_MUTE}, - {0x00, 0x5d, KEY_VOLUMEDOWN}, - {0x00, 0xdd, KEY_CHANNELDOWN}, - {0x00, 0xad, KEY_1}, - {0x00, 0x6d, KEY_2}, - {0x00, 0xed, KEY_3}, - {0x00, 0x8d, KEY_4}, - {0x00, 0x4d, KEY_5}, - {0x00, 0xcd, KEY_6}, - {0x00, 0xb5, KEY_7}, - {0x00, 0x75, KEY_8}, - {0x00, 0xf5, KEY_9}, - {0x00, 0x95, KEY_ZOOM}, - {0x00, 0x55, KEY_0}, - {0x00, 0xd5, KEY_GOTO}, /* marked jump on the remote */ -}; - -int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys); - -static int repeatable_keys[] = { - KEY_VOLUMEUP, - KEY_VOLUMEDOWN, - KEY_CHANNELUP, - KEY_CHANNELDOWN -}; - -int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event, - int *state) -{ - u16 mark, space; - u32 result; - u8 cust, dat, invdat; - int i; - - if (len >= 6) { - mark = (u16) (data[0] << 8) + data[1]; - space = (u16) (data[2] << 8) + data[3]; - if (space * 3 < mark) { - for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) { - if (d->last_event == repeatable_keys[i]) { - *state = REMOTE_KEY_REPEAT; - *event = d->last_event; - deb_decode("repeat key, event %x\n", - *event); - return 0; - } - } - deb_decode("repeated key ignored (non repeatable)\n"); - return 0; - } else if (len >= 33 * 4) { /*32 bits + start code */ - result = 0; - for (i = 4; i < 4 + 32 * 4; i += 4) { - result <<= 1; - mark = (u16) (data[i] << 8) + data[i + 1]; - mark >>= 1; - space = (u16) (data[i + 2] << 8) + data[i + 3]; - space >>= 1; - if (mark * 2 > space) - result += 1; - } - deb_decode("key pressed, raw value %x\n", result); - if ((result & 0xff000000) != 0xfe000000) { - deb_decode - ("doesn't start with 0xfe, ignored\n"); - return 0; - } - cust = (result >> 16) & 0xff; - dat = (result >> 8) & 0xff; - invdat = (~result) & 0xff; - if (dat != invdat) { - deb_decode("code != inverted code\n"); - return 0; - } - for (i = 0; i < af9005_rc_keys_size; i++) { - if (af9005_rc_keys[i].custom == cust - && af9005_rc_keys[i].data == dat) { - *event = af9005_rc_keys[i].event; - *state = REMOTE_KEY_PRESSED; - deb_decode - ("key pressed, event %x\n", *event); - return 0; - } - } - deb_decode("not found in table\n"); - } - } - return 0; -} - -EXPORT_SYMBOL(af9005_rc_keys); -EXPORT_SYMBOL(af9005_rc_keys_size); -EXPORT_SYMBOL(af9005_rc_decode); - -MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); -MODULE_DESCRIPTION - ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/af9005-script.h b/drivers/media/dvb/dvb-usb/af9005-script.h deleted file mode 100644 index 4d69045426d..00000000000 --- a/drivers/media/dvb/dvb-usb/af9005-script.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -File automatically generated by createinit.py using data -extracted from AF05BDA.sys (windows driver): - -dd if=AF05BDA.sys of=initsequence bs=1 skip=88316 count=1110 -python createinit.py > af9005-script.h - -*/ - -typedef struct { - u16 reg; - u8 pos; - u8 len; - u8 val; -} RegDesc; - -static RegDesc script[] = { - {0xa180, 0x0, 0x8, 0xa}, - {0xa181, 0x0, 0x8, 0xd7}, - {0xa182, 0x0, 0x8, 0xa3}, - {0xa0a0, 0x0, 0x8, 0x0}, - {0xa0a1, 0x0, 0x5, 0x0}, - {0xa0a1, 0x5, 0x1, 0x1}, - {0xa0c0, 0x0, 0x4, 0x1}, - {0xa20e, 0x4, 0x4, 0xa}, - {0xa20f, 0x0, 0x8, 0x40}, - {0xa210, 0x0, 0x8, 0x8}, - {0xa32a, 0x0, 0x4, 0xa}, - {0xa32c, 0x0, 0x8, 0x20}, - {0xa32b, 0x0, 0x8, 0x15}, - {0xa1a0, 0x1, 0x1, 0x1}, - {0xa000, 0x0, 0x1, 0x1}, - {0xa000, 0x1, 0x1, 0x0}, - {0xa001, 0x1, 0x1, 0x1}, - {0xa001, 0x0, 0x1, 0x0}, - {0xa001, 0x5, 0x1, 0x0}, - {0xa00e, 0x0, 0x5, 0x10}, - {0xa00f, 0x0, 0x3, 0x4}, - {0xa00f, 0x3, 0x3, 0x5}, - {0xa010, 0x0, 0x3, 0x4}, - {0xa010, 0x3, 0x3, 0x5}, - {0xa016, 0x4, 0x4, 0x3}, - {0xa01f, 0x0, 0x6, 0xa}, - {0xa020, 0x0, 0x6, 0xa}, - {0xa2bc, 0x0, 0x1, 0x1}, - {0xa2bc, 0x5, 0x1, 0x1}, - {0xa015, 0x0, 0x8, 0x50}, - {0xa016, 0x0, 0x1, 0x0}, - {0xa02a, 0x0, 0x8, 0x50}, - {0xa029, 0x0, 0x8, 0x4b}, - {0xa614, 0x0, 0x8, 0x46}, - {0xa002, 0x0, 0x5, 0x19}, - {0xa003, 0x0, 0x5, 0x1a}, - {0xa004, 0x0, 0x5, 0x19}, - {0xa005, 0x0, 0x5, 0x1a}, - {0xa008, 0x0, 0x8, 0x69}, - {0xa009, 0x0, 0x2, 0x2}, - {0xae1b, 0x0, 0x8, 0x69}, - {0xae1c, 0x0, 0x8, 0x2}, - {0xae1d, 0x0, 0x8, 0x2a}, - {0xa022, 0x0, 0x8, 0xaa}, - {0xa006, 0x0, 0x8, 0xc8}, - {0xa007, 0x0, 0x2, 0x0}, - {0xa00c, 0x0, 0x8, 0xba}, - {0xa00d, 0x0, 0x2, 0x2}, - {0xa608, 0x0, 0x8, 0xba}, - {0xa60e, 0x0, 0x2, 0x2}, - {0xa609, 0x0, 0x8, 0x80}, - {0xa60e, 0x2, 0x2, 0x3}, - {0xa00a, 0x0, 0x8, 0xb6}, - {0xa00b, 0x0, 0x2, 0x0}, - {0xa011, 0x0, 0x8, 0xb9}, - {0xa012, 0x0, 0x2, 0x0}, - {0xa013, 0x0, 0x8, 0xbd}, - {0xa014, 0x0, 0x2, 0x2}, - {0xa366, 0x0, 0x1, 0x1}, - {0xa2bc, 0x3, 0x1, 0x0}, - {0xa2bd, 0x0, 0x8, 0xa}, - {0xa2be, 0x0, 0x8, 0x14}, - {0xa2bf, 0x0, 0x8, 0x8}, - {0xa60a, 0x0, 0x8, 0xbd}, - {0xa60e, 0x4, 0x2, 0x2}, - {0xa60b, 0x0, 0x8, 0x86}, - {0xa60e, 0x6, 0x2, 0x3}, - {0xa001, 0x2, 0x2, 0x1}, - {0xa1c7, 0x0, 0x8, 0xf5}, - {0xa03d, 0x0, 0x8, 0xb1}, - {0xa616, 0x0, 0x8, 0xff}, - {0xa617, 0x0, 0x8, 0xad}, - {0xa618, 0x0, 0x8, 0xad}, - {0xa61e, 0x3, 0x1, 0x1}, - {0xae1a, 0x0, 0x8, 0x0}, - {0xae19, 0x0, 0x8, 0xc8}, - {0xae18, 0x0, 0x8, 0x61}, - {0xa140, 0x0, 0x8, 0x0}, - {0xa141, 0x0, 0x8, 0xc8}, - {0xa142, 0x0, 0x7, 0x61}, - {0xa023, 0x0, 0x8, 0xff}, - {0xa021, 0x0, 0x8, 0xad}, - {0xa026, 0x0, 0x1, 0x0}, - {0xa024, 0x0, 0x8, 0xff}, - {0xa025, 0x0, 0x8, 0xff}, - {0xa1c8, 0x0, 0x8, 0xf}, - {0xa2bc, 0x1, 0x1, 0x0}, - {0xa60c, 0x0, 0x4, 0x5}, - {0xa60c, 0x4, 0x4, 0x6}, - {0xa60d, 0x0, 0x8, 0xa}, - {0xa371, 0x0, 0x1, 0x1}, - {0xa366, 0x1, 0x3, 0x7}, - {0xa338, 0x0, 0x8, 0x10}, - {0xa339, 0x0, 0x6, 0x7}, - {0xa33a, 0x0, 0x6, 0x1f}, - {0xa33b, 0x0, 0x8, 0xf6}, - {0xa33c, 0x3, 0x5, 0x4}, - {0xa33d, 0x4, 0x4, 0x0}, - {0xa33d, 0x1, 0x1, 0x1}, - {0xa33d, 0x2, 0x1, 0x1}, - {0xa33d, 0x3, 0x1, 0x1}, - {0xa16d, 0x0, 0x4, 0xf}, - {0xa161, 0x0, 0x5, 0x5}, - {0xa162, 0x0, 0x4, 0x5}, - {0xa165, 0x0, 0x8, 0xff}, - {0xa166, 0x0, 0x8, 0x9c}, - {0xa2c3, 0x0, 0x4, 0x5}, - {0xa61a, 0x0, 0x6, 0xf}, - {0xb200, 0x0, 0x8, 0xa1}, - {0xb201, 0x0, 0x8, 0x7}, - {0xa093, 0x0, 0x1, 0x0}, - {0xa093, 0x1, 0x5, 0xf}, - {0xa094, 0x0, 0x8, 0xff}, - {0xa095, 0x0, 0x8, 0xf}, - {0xa080, 0x2, 0x5, 0x3}, - {0xa081, 0x0, 0x4, 0x0}, - {0xa081, 0x4, 0x4, 0x9}, - {0xa082, 0x0, 0x5, 0x1f}, - {0xa08d, 0x0, 0x8, 0x1}, - {0xa083, 0x0, 0x8, 0x32}, - {0xa084, 0x0, 0x1, 0x0}, - {0xa08e, 0x0, 0x8, 0x3}, - {0xa085, 0x0, 0x8, 0x32}, - {0xa086, 0x0, 0x3, 0x0}, - {0xa087, 0x0, 0x8, 0x6e}, - {0xa088, 0x0, 0x5, 0x15}, - {0xa089, 0x0, 0x8, 0x0}, - {0xa08a, 0x0, 0x5, 0x19}, - {0xa08b, 0x0, 0x8, 0x92}, - {0xa08c, 0x0, 0x5, 0x1c}, - {0xa120, 0x0, 0x8, 0x0}, - {0xa121, 0x0, 0x5, 0x10}, - {0xa122, 0x0, 0x8, 0x0}, - {0xa123, 0x0, 0x7, 0x40}, - {0xa123, 0x7, 0x1, 0x0}, - {0xa124, 0x0, 0x8, 0x13}, - {0xa125, 0x0, 0x7, 0x10}, - {0xa1c0, 0x0, 0x8, 0x0}, - {0xa1c1, 0x0, 0x5, 0x4}, - {0xa1c2, 0x0, 0x8, 0x0}, - {0xa1c3, 0x0, 0x5, 0x10}, - {0xa1c3, 0x5, 0x3, 0x0}, - {0xa1c4, 0x0, 0x6, 0x0}, - {0xa1c5, 0x0, 0x7, 0x10}, - {0xa100, 0x0, 0x8, 0x0}, - {0xa101, 0x0, 0x5, 0x10}, - {0xa102, 0x0, 0x8, 0x0}, - {0xa103, 0x0, 0x7, 0x40}, - {0xa103, 0x7, 0x1, 0x0}, - {0xa104, 0x0, 0x8, 0x18}, - {0xa105, 0x0, 0x7, 0xa}, - {0xa106, 0x0, 0x8, 0x20}, - {0xa107, 0x0, 0x8, 0x40}, - {0xa108, 0x0, 0x4, 0x0}, - {0xa38c, 0x0, 0x8, 0xfc}, - {0xa38d, 0x0, 0x8, 0x0}, - {0xa38e, 0x0, 0x8, 0x7e}, - {0xa38f, 0x0, 0x8, 0x0}, - {0xa390, 0x0, 0x8, 0x2f}, - {0xa60f, 0x5, 0x1, 0x1}, - {0xa170, 0x0, 0x8, 0xdc}, - {0xa171, 0x0, 0x2, 0x0}, - {0xa2ae, 0x0, 0x1, 0x1}, - {0xa2ae, 0x1, 0x1, 0x1}, - {0xa392, 0x0, 0x1, 0x1}, - {0xa391, 0x2, 0x1, 0x0}, - {0xabc1, 0x0, 0x8, 0xff}, - {0xabc2, 0x0, 0x8, 0x0}, - {0xabc8, 0x0, 0x8, 0x8}, - {0xabca, 0x0, 0x8, 0x10}, - {0xabcb, 0x0, 0x1, 0x0}, - {0xabc3, 0x5, 0x3, 0x7}, - {0xabc0, 0x6, 0x1, 0x0}, - {0xabc0, 0x4, 0x2, 0x0}, - {0xa344, 0x4, 0x4, 0x1}, - {0xabc0, 0x7, 0x1, 0x1}, - {0xabc0, 0x2, 0x1, 0x1}, - {0xa345, 0x0, 0x8, 0x66}, - {0xa346, 0x0, 0x8, 0x66}, - {0xa347, 0x0, 0x4, 0x0}, - {0xa343, 0x0, 0x4, 0xa}, - {0xa347, 0x4, 0x4, 0x2}, - {0xa348, 0x0, 0x4, 0xc}, - {0xa348, 0x4, 0x4, 0x7}, - {0xa349, 0x0, 0x6, 0x2}, -}; diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c deleted file mode 100644 index ca5a0a4d2a4..00000000000 --- a/drivers/media/dvb/dvb-usb/af9005.c +++ /dev/null @@ -1,1144 +0,0 @@ -/* DVB USB compliant Linux driver for the Afatech 9005 - * USB1.1 DVB-T receiver. - * - * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * see Documentation/dvb/REDME.dvb-usb for more information - */ -#include "af9005.h" - -/* debug */ -int dvb_usb_af9005_debug; -module_param_named(debug, dvb_usb_af9005_debug, int, 0644); -MODULE_PARM_DESC(debug, - "set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))." - DVB_USB_DEBUG_STATUS); -/* enable obnoxious led */ -int dvb_usb_af9005_led = 1; -module_param_named(led, dvb_usb_af9005_led, bool, 0644); -MODULE_PARM_DESC(led, "enable led (default: 1)."); - -/* eeprom dump */ -static int dvb_usb_af9005_dump_eeprom; -module_param_named(dump_eeprom, dvb_usb_af9005_dump_eeprom, int, 0); -MODULE_PARM_DESC(dump_eeprom, "dump contents of the eeprom."); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -/* remote control decoder */ -static int (*rc_decode) (struct dvb_usb_device *d, u8 *data, int len, - u32 *event, int *state); -static void *rc_keys; -static int *rc_keys_size; - -u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -struct af9005_device_state { - u8 sequence; - int led_state; -}; - -static int af9005_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, - u8 *rbuf, u16 rlen, int delay_ms) -{ - int actlen, ret = -ENOMEM; - - if (wbuf == NULL || wlen == 0) - return -EINVAL; - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - deb_xfer(">>> "); - debug_dump(wbuf, wlen, deb_xfer); - - ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, - 2), wbuf, wlen, - &actlen, 2000); - - if (ret) - err("bulk message failed: %d (%d/%d)", ret, wlen, actlen); - else - ret = actlen != wlen ? -1 : 0; - - /* an answer is expected, and no error before */ - if (!ret && rbuf && rlen) { - if (delay_ms) - msleep(delay_ms); - - ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, - 0x01), rbuf, - rlen, &actlen, 2000); - - if (ret) - err("recv bulk message failed: %d", ret); - else { - deb_xfer("<<< "); - debug_dump(rbuf, actlen, deb_xfer); - } - } - - mutex_unlock(&d->usb_mutex); - return ret; -} - -static int af9005_generic_read_write(struct dvb_usb_device *d, u16 reg, - int readwrite, int type, u8 * values, int len) -{ - struct af9005_device_state *st = d->priv; - u8 obuf[16] = { 0 }; - u8 ibuf[17] = { 0 }; - u8 command; - int i; - int ret; - - if (len < 1) { - err("generic read/write, less than 1 byte. Makes no sense."); - return -EINVAL; - } - if (len > 8) { - err("generic read/write, more than 8 bytes. Not supported."); - return -EINVAL; - } - - obuf[0] = 14; /* rest of buffer length low */ - obuf[1] = 0; /* rest of buffer length high */ - - obuf[2] = AF9005_REGISTER_RW; /* register operation */ - obuf[3] = 12; /* rest of buffer length */ - - obuf[4] = st->sequence++; /* sequence number */ - - obuf[5] = (u8) (reg >> 8); /* register address */ - obuf[6] = (u8) (reg & 0xff); - - if (type == AF9005_OFDM_REG) { - command = AF9005_CMD_OFDM_REG; - } else { - command = AF9005_CMD_TUNER; - } - - if (len > 1) - command |= - AF9005_CMD_BURST | AF9005_CMD_AUTOINC | (len - 1) << 3; - command |= readwrite; - if (readwrite == AF9005_CMD_WRITE) - for (i = 0; i < len; i++) - obuf[8 + i] = values[i]; - else if (type == AF9005_TUNER_REG) - /* read command for tuner, the first byte contains the i2c address */ - obuf[8] = values[0]; - obuf[7] = command; - - ret = af9005_usb_generic_rw(d, obuf, 16, ibuf, 17, 0); - if (ret) - return ret; - - /* sanity check */ - if (ibuf[2] != AF9005_REGISTER_RW_ACK) { - err("generic read/write, wrong reply code."); - return -EIO; - } - if (ibuf[3] != 0x0d) { - err("generic read/write, wrong length in reply."); - return -EIO; - } - if (ibuf[4] != obuf[4]) { - err("generic read/write, wrong sequence in reply."); - return -EIO; - } - /* - Windows driver doesn't check these fields, in fact sometimes - the register in the reply is different that what has been sent - - if (ibuf[5] != obuf[5] || ibuf[6] != obuf[6]) { - err("generic read/write, wrong register in reply."); - return -EIO; - } - if (ibuf[7] != command) { - err("generic read/write wrong command in reply."); - return -EIO; - } - */ - if (ibuf[16] != 0x01) { - err("generic read/write wrong status code in reply."); - return -EIO; - } - if (readwrite == AF9005_CMD_READ) - for (i = 0; i < len; i++) - values[i] = ibuf[8 + i]; - - return 0; - -} - -int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 * value) -{ - int ret; - deb_reg("read register %x ", reg); - ret = af9005_generic_read_write(d, reg, - AF9005_CMD_READ, AF9005_OFDM_REG, - value, 1); - if (ret) - deb_reg("failed\n"); - else - deb_reg("value %x\n", *value); - return ret; -} - -int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg, - u8 * values, int len) -{ - int ret; - deb_reg("read %d registers %x ", len, reg); - ret = af9005_generic_read_write(d, reg, - AF9005_CMD_READ, AF9005_OFDM_REG, - values, len); - if (ret) - deb_reg("failed\n"); - else - debug_dump(values, len, deb_reg); - return ret; -} - -int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, u8 value) -{ - int ret; - u8 temp = value; - deb_reg("write register %x value %x ", reg, value); - ret = af9005_generic_read_write(d, reg, - AF9005_CMD_WRITE, AF9005_OFDM_REG, - &temp, 1); - if (ret) - deb_reg("failed\n"); - else - deb_reg("ok\n"); - return ret; -} - -int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg, - u8 * values, int len) -{ - int ret; - deb_reg("write %d registers %x values ", len, reg); - debug_dump(values, len, deb_reg); - - ret = af9005_generic_read_write(d, reg, - AF9005_CMD_WRITE, AF9005_OFDM_REG, - values, len); - if (ret) - deb_reg("failed\n"); - else - deb_reg("ok\n"); - return ret; -} - -int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos, - u8 len, u8 * value) -{ - u8 temp; - int ret; - deb_reg("read bits %x %x %x", reg, pos, len); - ret = af9005_read_ofdm_register(d, reg, &temp); - if (ret) { - deb_reg(" failed\n"); - return ret; - } - *value = (temp >> pos) & regmask[len - 1]; - deb_reg(" value %x\n", *value); - return 0; - -} - -int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, u8 pos, - u8 len, u8 value) -{ - u8 temp, mask; - int ret; - deb_reg("write bits %x %x %x value %x\n", reg, pos, len, value); - if (pos == 0 && len == 8) - return af9005_write_ofdm_register(d, reg, value); - ret = af9005_read_ofdm_register(d, reg, &temp); - if (ret) - return ret; - mask = regmask[len - 1] << pos; - temp = (temp & ~mask) | ((value << pos) & mask); - return af9005_write_ofdm_register(d, reg, temp); - -} - -static int af9005_usb_read_tuner_registers(struct dvb_usb_device *d, - u16 reg, u8 * values, int len) -{ - return af9005_generic_read_write(d, reg, - AF9005_CMD_READ, AF9005_TUNER_REG, - values, len); -} - -static int af9005_usb_write_tuner_registers(struct dvb_usb_device *d, - u16 reg, u8 * values, int len) -{ - return af9005_generic_read_write(d, reg, - AF9005_CMD_WRITE, - AF9005_TUNER_REG, values, len); -} - -int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg, - u8 * values, int len) -{ - /* don't let the name of this function mislead you: it's just used - as an interface from the firmware to the i2c bus. The actual - i2c addresses are contained in the data */ - int ret, i, done = 0, fail = 0; - u8 temp; - ret = af9005_usb_write_tuner_registers(d, reg, values, len); - if (ret) - return ret; - if (reg != 0xffff) { - /* check if write done (0xa40d bit 1) or fail (0xa40d bit 2) */ - for (i = 0; i < 200; i++) { - ret = - af9005_read_ofdm_register(d, - xd_I2C_i2c_m_status_wdat_done, - &temp); - if (ret) - return ret; - done = temp & (regmask[i2c_m_status_wdat_done_len - 1] - << i2c_m_status_wdat_done_pos); - if (done) - break; - fail = temp & (regmask[i2c_m_status_wdat_fail_len - 1] - << i2c_m_status_wdat_fail_pos); - if (fail) - break; - msleep(50); - } - if (i == 200) - return -ETIMEDOUT; - if (fail) { - /* clear write fail bit */ - af9005_write_register_bits(d, - xd_I2C_i2c_m_status_wdat_fail, - i2c_m_status_wdat_fail_pos, - i2c_m_status_wdat_fail_len, - 1); - return -EIO; - } - /* clear write done bit */ - ret = - af9005_write_register_bits(d, - xd_I2C_i2c_m_status_wdat_fail, - i2c_m_status_wdat_done_pos, - i2c_m_status_wdat_done_len, 1); - if (ret) - return ret; - } - return 0; -} - -int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, u8 addr, - u8 * values, int len) -{ - /* don't let the name of this function mislead you: it's just used - as an interface from the firmware to the i2c bus. The actual - i2c addresses are contained in the data */ - int ret, i; - u8 temp, buf[2]; - - buf[0] = addr; /* tuner i2c address */ - buf[1] = values[0]; /* tuner register */ - - values[0] = addr + 0x01; /* i2c read address */ - - if (reg == APO_REG_I2C_RW_SILICON_TUNER) { - /* write tuner i2c address to tuner, 0c00c0 undocumented, found by sniffing */ - ret = af9005_write_tuner_registers(d, 0x00c0, buf, 2); - if (ret) - return ret; - } - - /* send read command to ofsm */ - ret = af9005_usb_read_tuner_registers(d, reg, values, 1); - if (ret) - return ret; - - /* check if read done */ - for (i = 0; i < 200; i++) { - ret = af9005_read_ofdm_register(d, 0xa408, &temp); - if (ret) - return ret; - if (temp & 0x01) - break; - msleep(50); - } - if (i == 200) - return -ETIMEDOUT; - - /* clear read done bit (by writing 1) */ - ret = af9005_write_ofdm_register(d, xd_I2C_i2c_m_data8, 1); - if (ret) - return ret; - - /* get read data (available from 0xa400) */ - for (i = 0; i < len; i++) { - ret = af9005_read_ofdm_register(d, 0xa400 + i, &temp); - if (ret) - return ret; - values[i] = temp; - } - return 0; -} - -static int af9005_i2c_write(struct dvb_usb_device *d, u8 i2caddr, u8 reg, - u8 * data, int len) -{ - int ret, i; - u8 buf[3]; - deb_i2c("i2c_write i2caddr %x, reg %x, len %d data ", i2caddr, - reg, len); - debug_dump(data, len, deb_i2c); - - for (i = 0; i < len; i++) { - buf[0] = i2caddr; - buf[1] = reg + (u8) i; - buf[2] = data[i]; - ret = - af9005_write_tuner_registers(d, - APO_REG_I2C_RW_SILICON_TUNER, - buf, 3); - if (ret) { - deb_i2c("i2c_write failed\n"); - return ret; - } - } - deb_i2c("i2c_write ok\n"); - return 0; -} - -static int af9005_i2c_read(struct dvb_usb_device *d, u8 i2caddr, u8 reg, - u8 * data, int len) -{ - int ret, i; - u8 temp; - deb_i2c("i2c_read i2caddr %x, reg %x, len %d\n ", i2caddr, reg, len); - for (i = 0; i < len; i++) { - temp = reg + i; - ret = - af9005_read_tuner_registers(d, - APO_REG_I2C_RW_SILICON_TUNER, - i2caddr, &temp, 1); - if (ret) { - deb_i2c("i2c_read failed\n"); - return ret; - } - data[i] = temp; - } - deb_i2c("i2c data read: "); - debug_dump(data, len, deb_i2c); - return 0; -} - -static int af9005_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - /* only implements what the mt2060 module does, don't know how - to make it really generic */ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret; - u8 reg, addr; - u8 *value; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - if (num > 2) - warn("more than 2 i2c messages at a time is not handled yet. TODO."); - - if (num == 2) { - /* reads a single register */ - reg = *msg[0].buf; - addr = msg[0].addr; - value = msg[1].buf; - ret = af9005_i2c_read(d, addr, reg, value, 1); - if (ret == 0) - ret = 2; - } else { - /* write one or more registers */ - reg = msg[0].buf[0]; - addr = msg[0].addr; - value = &msg[0].buf[1]; - ret = af9005_i2c_write(d, addr, reg, value, msg[0].len - 1); - if (ret == 0) - ret = 1; - } - - mutex_unlock(&d->i2c_mutex); - return ret; -} - -static u32 af9005_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm af9005_i2c_algo = { - .master_xfer = af9005_i2c_xfer, - .functionality = af9005_i2c_func, -}; - -int af9005_send_command(struct dvb_usb_device *d, u8 command, u8 * wbuf, - int wlen, u8 * rbuf, int rlen) -{ - struct af9005_device_state *st = d->priv; - - int ret, i, packet_len; - u8 buf[64]; - u8 ibuf[64]; - - if (wlen < 0) { - err("send command, wlen less than 0 bytes. Makes no sense."); - return -EINVAL; - } - if (wlen > 54) { - err("send command, wlen more than 54 bytes. Not supported."); - return -EINVAL; - } - if (rlen > 54) { - err("send command, rlen more than 54 bytes. Not supported."); - return -EINVAL; - } - packet_len = wlen + 5; - buf[0] = (u8) (packet_len & 0xff); - buf[1] = (u8) ((packet_len & 0xff00) >> 8); - - buf[2] = 0x26; /* packet type */ - buf[3] = wlen + 3; - buf[4] = st->sequence++; - buf[5] = command; - buf[6] = wlen; - for (i = 0; i < wlen; i++) - buf[7 + i] = wbuf[i]; - ret = af9005_usb_generic_rw(d, buf, wlen + 7, ibuf, rlen + 7, 0); - if (ret) - return ret; - if (ibuf[2] != 0x27) { - err("send command, wrong reply code."); - return -EIO; - } - if (ibuf[4] != buf[4]) { - err("send command, wrong sequence in reply."); - return -EIO; - } - if (ibuf[5] != 0x01) { - err("send command, wrong status code in reply."); - return -EIO; - } - if (ibuf[6] != rlen) { - err("send command, invalid data length in reply."); - return -EIO; - } - for (i = 0; i < rlen; i++) - rbuf[i] = ibuf[i + 7]; - return 0; -} - -int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, u8 * values, - int len) -{ - struct af9005_device_state *st = d->priv; - u8 obuf[16], ibuf[14]; - int ret, i; - - memset(obuf, 0, sizeof(obuf)); - memset(ibuf, 0, sizeof(ibuf)); - - obuf[0] = 14; /* length of rest of packet low */ - obuf[1] = 0; /* length of rest of packer high */ - - obuf[2] = 0x2a; /* read/write eeprom */ - - obuf[3] = 12; /* size */ - - obuf[4] = st->sequence++; - - obuf[5] = 0; /* read */ - - obuf[6] = len; - obuf[7] = address; - ret = af9005_usb_generic_rw(d, obuf, 16, ibuf, 14, 0); - if (ret) - return ret; - if (ibuf[2] != 0x2b) { - err("Read eeprom, invalid reply code"); - return -EIO; - } - if (ibuf[3] != 10) { - err("Read eeprom, invalid reply length"); - return -EIO; - } - if (ibuf[4] != obuf[4]) { - err("Read eeprom, wrong sequence in reply "); - return -EIO; - } - if (ibuf[5] != 1) { - err("Read eeprom, wrong status in reply "); - return -EIO; - } - for (i = 0; i < len; i++) { - values[i] = ibuf[6 + i]; - } - return 0; -} - -static int af9005_boot_packet(struct usb_device *udev, int type, u8 * reply) -{ - u8 buf[FW_BULKOUT_SIZE + 2]; - u16 checksum; - int act_len, i, ret; - memset(buf, 0, sizeof(buf)); - buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); - buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff); - switch (type) { - case FW_CONFIG: - buf[2] = 0x11; - buf[3] = 0x04; - buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ - buf[5] = 0x03; - checksum = buf[4] + buf[5]; - buf[6] = (u8) ((checksum >> 8) & 0xff); - buf[7] = (u8) (checksum & 0xff); - break; - case FW_CONFIRM: - buf[2] = 0x11; - buf[3] = 0x04; - buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ - buf[5] = 0x01; - checksum = buf[4] + buf[5]; - buf[6] = (u8) ((checksum >> 8) & 0xff); - buf[7] = (u8) (checksum & 0xff); - break; - case FW_BOOT: - buf[2] = 0x10; - buf[3] = 0x08; - buf[4] = 0x00; /* sequence number, original driver doesn't increment it here */ - buf[5] = 0x97; - buf[6] = 0xaa; - buf[7] = 0x55; - buf[8] = 0xa5; - buf[9] = 0x5a; - checksum = 0; - for (i = 4; i <= 9; i++) - checksum += buf[i]; - buf[10] = (u8) ((checksum >> 8) & 0xff); - buf[11] = (u8) (checksum & 0xff); - break; - default: - err("boot packet invalid boot packet type"); - return -EINVAL; - } - deb_fw(">>> "); - debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw); - - ret = usb_bulk_msg(udev, - usb_sndbulkpipe(udev, 0x02), - buf, FW_BULKOUT_SIZE + 2, &act_len, 2000); - if (ret) - err("boot packet bulk message failed: %d (%d/%d)", ret, - FW_BULKOUT_SIZE + 2, act_len); - else - ret = act_len != FW_BULKOUT_SIZE + 2 ? -1 : 0; - if (ret) - return ret; - memset(buf, 0, 9); - ret = usb_bulk_msg(udev, - usb_rcvbulkpipe(udev, 0x01), buf, 9, &act_len, 2000); - if (ret) { - err("boot packet recv bulk message failed: %d", ret); - return ret; - } - deb_fw("<<< "); - debug_dump(buf, act_len, deb_fw); - checksum = 0; - switch (type) { - case FW_CONFIG: - if (buf[2] != 0x11) { - err("boot bad config header."); - return -EIO; - } - if (buf[3] != 0x05) { - err("boot bad config size."); - return -EIO; - } - if (buf[4] != 0x00) { - err("boot bad config sequence."); - return -EIO; - } - if (buf[5] != 0x04) { - err("boot bad config subtype."); - return -EIO; - } - for (i = 4; i <= 6; i++) - checksum += buf[i]; - if (buf[7] * 256 + buf[8] != checksum) { - err("boot bad config checksum."); - return -EIO; - } - *reply = buf[6]; - break; - case FW_CONFIRM: - if (buf[2] != 0x11) { - err("boot bad confirm header."); - return -EIO; - } - if (buf[3] != 0x05) { - err("boot bad confirm size."); - return -EIO; - } - if (buf[4] != 0x00) { - err("boot bad confirm sequence."); - return -EIO; - } - if (buf[5] != 0x02) { - err("boot bad confirm subtype."); - return -EIO; - } - for (i = 4; i <= 6; i++) - checksum += buf[i]; - if (buf[7] * 256 + buf[8] != checksum) { - err("boot bad confirm checksum."); - return -EIO; - } - *reply = buf[6]; - break; - case FW_BOOT: - if (buf[2] != 0x10) { - err("boot bad boot header."); - return -EIO; - } - if (buf[3] != 0x05) { - err("boot bad boot size."); - return -EIO; - } - if (buf[4] != 0x00) { - err("boot bad boot sequence."); - return -EIO; - } - if (buf[5] != 0x01) { - err("boot bad boot pattern 01."); - return -EIO; - } - if (buf[6] != 0x10) { - err("boot bad boot pattern 10."); - return -EIO; - } - for (i = 4; i <= 6; i++) - checksum += buf[i]; - if (buf[7] * 256 + buf[8] != checksum) { - err("boot bad boot checksum."); - return -EIO; - } - break; - - } - - return 0; -} - -static int af9005_download_firmware(struct usb_device *udev, const struct firmware *fw) -{ - int i, packets, ret, act_len; - - u8 buf[FW_BULKOUT_SIZE + 2]; - u8 reply; - - ret = af9005_boot_packet(udev, FW_CONFIG, &reply); - if (ret) - return ret; - if (reply != 0x01) { - err("before downloading firmware, FW_CONFIG expected 0x01, received 0x%x", reply); - return -EIO; - } - packets = fw->size / FW_BULKOUT_SIZE; - buf[0] = (u8) (FW_BULKOUT_SIZE & 0xff); - buf[1] = (u8) ((FW_BULKOUT_SIZE >> 8) & 0xff); - for (i = 0; i < packets; i++) { - memcpy(&buf[2], fw->data + i * FW_BULKOUT_SIZE, - FW_BULKOUT_SIZE); - deb_fw(">>> "); - debug_dump(buf, FW_BULKOUT_SIZE + 2, deb_fw); - ret = usb_bulk_msg(udev, - usb_sndbulkpipe(udev, 0x02), - buf, FW_BULKOUT_SIZE + 2, &act_len, 1000); - if (ret) { - err("firmware download failed at packet %d with code %d", i, ret); - return ret; - } - } - ret = af9005_boot_packet(udev, FW_CONFIRM, &reply); - if (ret) - return ret; - if (reply != (u8) (packets & 0xff)) { - err("after downloading firmware, FW_CONFIRM expected 0x%x, received 0x%x", packets & 0xff, reply); - return -EIO; - } - ret = af9005_boot_packet(udev, FW_BOOT, &reply); - if (ret) - return ret; - ret = af9005_boot_packet(udev, FW_CONFIG, &reply); - if (ret) - return ret; - if (reply != 0x02) { - err("after downloading firmware, FW_CONFIG expected 0x02, received 0x%x", reply); - return -EIO; - } - - return 0; - -} - -int af9005_led_control(struct dvb_usb_device *d, int onoff) -{ - struct af9005_device_state *st = d->priv; - int temp, ret; - - if (onoff && dvb_usb_af9005_led) - temp = 1; - else - temp = 0; - if (st->led_state != temp) { - ret = - af9005_write_register_bits(d, xd_p_reg_top_locken1, - reg_top_locken1_pos, - reg_top_locken1_len, temp); - if (ret) - return ret; - ret = - af9005_write_register_bits(d, xd_p_reg_top_lock1, - reg_top_lock1_pos, - reg_top_lock1_len, temp); - if (ret) - return ret; - st->led_state = temp; - } - return 0; -} - -static int af9005_frontend_attach(struct dvb_usb_adapter *adap) -{ - u8 buf[8]; - int i; - - /* without these calls the first commands after downloading - the firmware fail. I put these calls here to simulate - what it is done in dvb-usb-init.c. - */ - struct usb_device *udev = adap->dev->udev; - usb_clear_halt(udev, usb_sndbulkpipe(udev, 2)); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 1)); - if (dvb_usb_af9005_dump_eeprom) { - printk("EEPROM DUMP\n"); - for (i = 0; i < 255; i += 8) { - af9005_read_eeprom(adap->dev, i, buf, 8); - printk("ADDR %x ", i); - debug_dump(buf, 8, printk); - } - } - adap->fe = af9005_fe_attach(adap->dev); - return 0; -} - -static int af9005_rc_query(struct dvb_usb_device *d, u32 * event, int *state) -{ - struct af9005_device_state *st = d->priv; - int ret, len; - - u8 obuf[5]; - u8 ibuf[256]; - - *state = REMOTE_NO_KEY_PRESSED; - if (rc_decode == NULL) { - /* it shouldn't never come here */ - return 0; - } - /* deb_info("rc_query\n"); */ - obuf[0] = 3; /* rest of packet length low */ - obuf[1] = 0; /* rest of packet lentgh high */ - obuf[2] = 0x40; /* read remote */ - obuf[3] = 1; /* rest of packet length */ - obuf[4] = st->sequence++; /* sequence number */ - ret = af9005_usb_generic_rw(d, obuf, 5, ibuf, 256, 0); - if (ret) { - err("rc query failed"); - return ret; - } - if (ibuf[2] != 0x41) { - err("rc query bad header."); - return -EIO; - } - if (ibuf[4] != obuf[4]) { - err("rc query bad sequence."); - return -EIO; - } - len = ibuf[5]; - if (len > 246) { - err("rc query invalid length"); - return -EIO; - } - if (len > 0) { - deb_rc("rc data (%d) ", len); - debug_dump((ibuf + 6), len, deb_rc); - ret = rc_decode(d, &ibuf[6], len, event, state); - if (ret) { - err("rc_decode failed"); - return ret; - } else { - deb_rc("rc_decode state %x event %x\n", *state, *event); - if (*state == REMOTE_KEY_REPEAT) - *event = d->last_event; - } - } - return 0; -} - -static int af9005_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - - return 0; -} - -static int af9005_pid_filter_control(struct dvb_usb_adapter *adap, int onoff) -{ - int ret; - deb_info("pid filter control onoff %d\n", onoff); - if (onoff) { - ret = - af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1); - if (ret) - return ret; - ret = - af9005_write_register_bits(adap->dev, - XD_MP2IF_DMX_CTRL, 1, 1, 1); - if (ret) - return ret; - ret = - af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 1); - } else - ret = - af9005_write_ofdm_register(adap->dev, XD_MP2IF_DMX_CTRL, 0); - if (ret) - return ret; - deb_info("pid filter control ok\n"); - return 0; -} - -static int af9005_pid_filter(struct dvb_usb_adapter *adap, int index, - u16 pid, int onoff) -{ - u8 cmd = index & 0x1f; - int ret; - deb_info("set pid filter, index %d, pid %x, onoff %d\n", index, - pid, onoff); - if (onoff) { - /* cannot use it as pid_filter_ctrl since it has to be done - before setting the first pid */ - if (adap->feedcount == 1) { - deb_info("first pid set, enable pid table\n"); - ret = af9005_pid_filter_control(adap, onoff); - if (ret) - return ret; - } - ret = - af9005_write_ofdm_register(adap->dev, - XD_MP2IF_PID_DATA_L, - (u8) (pid & 0xff)); - if (ret) - return ret; - ret = - af9005_write_ofdm_register(adap->dev, - XD_MP2IF_PID_DATA_H, - (u8) (pid >> 8)); - if (ret) - return ret; - cmd |= 0x20 | 0x40; - } else { - if (adap->feedcount == 0) { - deb_info("last pid unset, disable pid table\n"); - ret = af9005_pid_filter_control(adap, onoff); - if (ret) - return ret; - } - } - ret = af9005_write_ofdm_register(adap->dev, XD_MP2IF_PID_IDX, cmd); - if (ret) - return ret; - deb_info("set pid ok\n"); - return 0; -} - -static int af9005_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - int ret; - u8 reply; - ret = af9005_boot_packet(udev, FW_CONFIG, &reply); - if (ret) - return ret; - deb_info("result of FW_CONFIG in identify state %d\n", reply); - if (reply == 0x01) - *cold = 1; - else if (reply == 0x02) - *cold = 0; - else - return -EIO; - deb_info("Identify state cold = %d\n", *cold); - return 0; -} - -static struct dvb_usb_device_properties af9005_properties; - -static int af9005_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &af9005_properties, - THIS_MODULE, NULL, adapter_nr); -} - -static struct usb_device_id af9005_usb_table[] = { - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9005)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE)}, - {USB_DEVICE(USB_VID_ANSONIC, USB_PID_ANSONIC_DVBT_USB)}, - {0}, -}; - -MODULE_DEVICE_TABLE(usb, af9005_usb_table); - -static struct dvb_usb_device_properties af9005_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "af9005.fw", - .download_firmware = af9005_download_firmware, - .no_reconnect = 1, - - .size_of_priv = sizeof(struct af9005_device_state), - - .num_adapters = 1, - .adapter = { - { - .caps = - DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter_count = 32, - .pid_filter = af9005_pid_filter, - /* .pid_filter_ctrl = af9005_pid_filter_control, */ - .frontend_attach = af9005_frontend_attach, - /* .tuner_attach = af9005_tuner_attach, */ - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 10, - .endpoint = 0x04, - .u = { - .bulk = { - .buffersize = 4096, /* actual size seen is 3948 */ - } - } - }, - } - }, - .power_ctrl = af9005_power_ctrl, - .identify_state = af9005_identify_state, - - .i2c_algo = &af9005_i2c_algo, - - .rc_interval = 200, - .rc_key_map = NULL, - .rc_key_map_size = 0, - .rc_query = af9005_rc_query, - - .num_device_descs = 3, - .devices = { - {.name = "Afatech DVB-T USB1.1 stick", - .cold_ids = {&af9005_usb_table[0], NULL}, - .warm_ids = {NULL}, - }, - {.name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9005_usb_table[1], NULL}, - .warm_ids = {NULL}, - }, - {.name = "Ansonic DVB-T USB1.1 stick", - .cold_ids = {&af9005_usb_table[2], NULL}, - .warm_ids = {NULL}, - }, - {NULL}, - } -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver af9005_usb_driver = { - .name = "dvb_usb_af9005", - .probe = af9005_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = af9005_usb_table, -}; - -/* module stuff */ -static int __init af9005_usb_module_init(void) -{ - int result; - if ((result = usb_register(&af9005_usb_driver))) { - err("usb_register failed. (%d)", result); - return result; - } - rc_decode = symbol_request(af9005_rc_decode); - rc_keys = symbol_request(af9005_rc_keys); - rc_keys_size = symbol_request(af9005_rc_keys_size); - if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { - err("af9005_rc_decode function not found, disabling remote"); - af9005_properties.rc_query = NULL; - } else { - af9005_properties.rc_key_map = rc_keys; - af9005_properties.rc_key_map_size = *rc_keys_size; - } - - return 0; -} - -static void __exit af9005_usb_module_exit(void) -{ - /* release rc decode symbols */ - if (rc_decode != NULL) - symbol_put(af9005_rc_decode); - if (rc_keys != NULL) - symbol_put(af9005_rc_keys); - if (rc_keys_size != NULL) - symbol_put(af9005_rc_keys_size); - /* deregister this driver from the USB subsystem */ - usb_deregister(&af9005_usb_driver); -} - -module_init(af9005_usb_module_init); -module_exit(af9005_usb_module_exit); - -MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>"); -MODULE_DESCRIPTION("Driver for Afatech 9005 DVB-T USB1.1 stick"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h deleted file mode 100644 index 0bc48a01218..00000000000 --- a/drivers/media/dvb/dvb-usb/af9005.h +++ /dev/null @@ -1,3496 +0,0 @@ -/* Common header-file of the Linux driver for the Afatech 9005 - * USB1.1 DVB-T receiver. - * - * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org) - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_AF9005_H_ -#define _DVB_USB_AF9005_H_ - -#define DVB_USB_LOG_PREFIX "af9005" -#include "dvb-usb.h" - -extern int dvb_usb_af9005_debug; -#define deb_info(args...) dprintk(dvb_usb_af9005_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_af9005_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_af9005_debug,0x04,args) -#define deb_reg(args...) dprintk(dvb_usb_af9005_debug,0x08,args) -#define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args) -#define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args) - -extern int dvb_usb_af9005_led; - -/* firmware */ -#define FW_BULKOUT_SIZE 250 -enum { - FW_CONFIG, - FW_CONFIRM, - FW_BOOT -}; - -/* af9005 commands */ -#define AF9005_OFDM_REG 0 -#define AF9005_TUNER_REG 1 - -#define AF9005_REGISTER_RW 0x20 -#define AF9005_REGISTER_RW_ACK 0x21 - -#define AF9005_CMD_OFDM_REG 0x00 -#define AF9005_CMD_TUNER 0x80 -#define AF9005_CMD_BURST 0x02 -#define AF9005_CMD_AUTOINC 0x04 -#define AF9005_CMD_READ 0x00 -#define AF9005_CMD_WRITE 0x01 - -/* af9005 registers */ -#define APO_REG_RESET 0xAEFF - -#define APO_REG_I2C_RW_CAN_TUNER 0xF000 -#define APO_REG_I2C_RW_SILICON_TUNER 0xF001 -#define APO_REG_GPIO_RW_SILICON_TUNER 0xFFFE /* also for OFSM */ -#define APO_REG_TRIGGER_OFSM 0xFFFF /* also for OFSM */ - -/*********************************************************************** - * Apollo Registers from VLSI * - ***********************************************************************/ -#define xd_p_reg_aagc_inverted_agc 0xA000 -#define reg_aagc_inverted_agc_pos 0 -#define reg_aagc_inverted_agc_len 1 -#define reg_aagc_inverted_agc_lsb 0 -#define xd_p_reg_aagc_sign_only 0xA000 -#define reg_aagc_sign_only_pos 1 -#define reg_aagc_sign_only_len 1 -#define reg_aagc_sign_only_lsb 0 -#define xd_p_reg_aagc_slow_adc_en 0xA000 -#define reg_aagc_slow_adc_en_pos 2 -#define reg_aagc_slow_adc_en_len 1 -#define reg_aagc_slow_adc_en_lsb 0 -#define xd_p_reg_aagc_slow_adc_scale 0xA000 -#define reg_aagc_slow_adc_scale_pos 3 -#define reg_aagc_slow_adc_scale_len 5 -#define reg_aagc_slow_adc_scale_lsb 0 -#define xd_p_reg_aagc_check_slow_adc_lock 0xA001 -#define reg_aagc_check_slow_adc_lock_pos 0 -#define reg_aagc_check_slow_adc_lock_len 1 -#define reg_aagc_check_slow_adc_lock_lsb 0 -#define xd_p_reg_aagc_init_control 0xA001 -#define reg_aagc_init_control_pos 1 -#define reg_aagc_init_control_len 1 -#define reg_aagc_init_control_lsb 0 -#define xd_p_reg_aagc_total_gain_sel 0xA001 -#define reg_aagc_total_gain_sel_pos 2 -#define reg_aagc_total_gain_sel_len 2 -#define reg_aagc_total_gain_sel_lsb 0 -#define xd_p_reg_aagc_out_inv 0xA001 -#define reg_aagc_out_inv_pos 5 -#define reg_aagc_out_inv_len 1 -#define reg_aagc_out_inv_lsb 0 -#define xd_p_reg_aagc_int_en 0xA001 -#define reg_aagc_int_en_pos 6 -#define reg_aagc_int_en_len 1 -#define reg_aagc_int_en_lsb 0 -#define xd_p_reg_aagc_lock_change_flag 0xA001 -#define reg_aagc_lock_change_flag_pos 7 -#define reg_aagc_lock_change_flag_len 1 -#define reg_aagc_lock_change_flag_lsb 0 -#define xd_p_reg_aagc_rf_loop_bw_scale_acquire 0xA002 -#define reg_aagc_rf_loop_bw_scale_acquire_pos 0 -#define reg_aagc_rf_loop_bw_scale_acquire_len 5 -#define reg_aagc_rf_loop_bw_scale_acquire_lsb 0 -#define xd_p_reg_aagc_rf_loop_bw_scale_track 0xA003 -#define reg_aagc_rf_loop_bw_scale_track_pos 0 -#define reg_aagc_rf_loop_bw_scale_track_len 5 -#define reg_aagc_rf_loop_bw_scale_track_lsb 0 -#define xd_p_reg_aagc_if_loop_bw_scale_acquire 0xA004 -#define reg_aagc_if_loop_bw_scale_acquire_pos 0 -#define reg_aagc_if_loop_bw_scale_acquire_len 5 -#define reg_aagc_if_loop_bw_scale_acquire_lsb 0 -#define xd_p_reg_aagc_if_loop_bw_scale_track 0xA005 -#define reg_aagc_if_loop_bw_scale_track_pos 0 -#define reg_aagc_if_loop_bw_scale_track_len 5 -#define reg_aagc_if_loop_bw_scale_track_lsb 0 -#define xd_p_reg_aagc_max_rf_agc_7_0 0xA006 -#define reg_aagc_max_rf_agc_7_0_pos 0 -#define reg_aagc_max_rf_agc_7_0_len 8 -#define reg_aagc_max_rf_agc_7_0_lsb 0 -#define xd_p_reg_aagc_max_rf_agc_9_8 0xA007 -#define reg_aagc_max_rf_agc_9_8_pos 0 -#define reg_aagc_max_rf_agc_9_8_len 2 -#define reg_aagc_max_rf_agc_9_8_lsb 8 -#define xd_p_reg_aagc_min_rf_agc_7_0 0xA008 -#define reg_aagc_min_rf_agc_7_0_pos 0 -#define reg_aagc_min_rf_agc_7_0_len 8 -#define reg_aagc_min_rf_agc_7_0_lsb 0 -#define xd_p_reg_aagc_min_rf_agc_9_8 0xA009 -#define reg_aagc_min_rf_agc_9_8_pos 0 -#define reg_aagc_min_rf_agc_9_8_len 2 -#define reg_aagc_min_rf_agc_9_8_lsb 8 -#define xd_p_reg_aagc_max_if_agc_7_0 0xA00A -#define reg_aagc_max_if_agc_7_0_pos 0 -#define reg_aagc_max_if_agc_7_0_len 8 -#define reg_aagc_max_if_agc_7_0_lsb 0 -#define xd_p_reg_aagc_max_if_agc_9_8 0xA00B -#define reg_aagc_max_if_agc_9_8_pos 0 -#define reg_aagc_max_if_agc_9_8_len 2 -#define reg_aagc_max_if_agc_9_8_lsb 8 -#define xd_p_reg_aagc_min_if_agc_7_0 0xA00C -#define reg_aagc_min_if_agc_7_0_pos 0 -#define reg_aagc_min_if_agc_7_0_len 8 -#define reg_aagc_min_if_agc_7_0_lsb 0 -#define xd_p_reg_aagc_min_if_agc_9_8 0xA00D -#define reg_aagc_min_if_agc_9_8_pos 0 -#define reg_aagc_min_if_agc_9_8_len 2 -#define reg_aagc_min_if_agc_9_8_lsb 8 -#define xd_p_reg_aagc_lock_sample_scale 0xA00E -#define reg_aagc_lock_sample_scale_pos 0 -#define reg_aagc_lock_sample_scale_len 5 -#define reg_aagc_lock_sample_scale_lsb 0 -#define xd_p_reg_aagc_rf_agc_lock_scale_acquire 0xA00F -#define reg_aagc_rf_agc_lock_scale_acquire_pos 0 -#define reg_aagc_rf_agc_lock_scale_acquire_len 3 -#define reg_aagc_rf_agc_lock_scale_acquire_lsb 0 -#define xd_p_reg_aagc_rf_agc_lock_scale_track 0xA00F -#define reg_aagc_rf_agc_lock_scale_track_pos 3 -#define reg_aagc_rf_agc_lock_scale_track_len 3 -#define reg_aagc_rf_agc_lock_scale_track_lsb 0 -#define xd_p_reg_aagc_if_agc_lock_scale_acquire 0xA010 -#define reg_aagc_if_agc_lock_scale_acquire_pos 0 -#define reg_aagc_if_agc_lock_scale_acquire_len 3 -#define reg_aagc_if_agc_lock_scale_acquire_lsb 0 -#define xd_p_reg_aagc_if_agc_lock_scale_track 0xA010 -#define reg_aagc_if_agc_lock_scale_track_pos 3 -#define reg_aagc_if_agc_lock_scale_track_len 3 -#define reg_aagc_if_agc_lock_scale_track_lsb 0 -#define xd_p_reg_aagc_rf_top_numerator_7_0 0xA011 -#define reg_aagc_rf_top_numerator_7_0_pos 0 -#define reg_aagc_rf_top_numerator_7_0_len 8 -#define reg_aagc_rf_top_numerator_7_0_lsb 0 -#define xd_p_reg_aagc_rf_top_numerator_9_8 0xA012 -#define reg_aagc_rf_top_numerator_9_8_pos 0 -#define reg_aagc_rf_top_numerator_9_8_len 2 -#define reg_aagc_rf_top_numerator_9_8_lsb 8 -#define xd_p_reg_aagc_if_top_numerator_7_0 0xA013 -#define reg_aagc_if_top_numerator_7_0_pos 0 -#define reg_aagc_if_top_numerator_7_0_len 8 -#define reg_aagc_if_top_numerator_7_0_lsb 0 -#define xd_p_reg_aagc_if_top_numerator_9_8 0xA014 -#define reg_aagc_if_top_numerator_9_8_pos 0 -#define reg_aagc_if_top_numerator_9_8_len 2 -#define reg_aagc_if_top_numerator_9_8_lsb 8 -#define xd_p_reg_aagc_adc_out_desired_7_0 0xA015 -#define reg_aagc_adc_out_desired_7_0_pos 0 -#define reg_aagc_adc_out_desired_7_0_len 8 -#define reg_aagc_adc_out_desired_7_0_lsb 0 -#define xd_p_reg_aagc_adc_out_desired_8 0xA016 -#define reg_aagc_adc_out_desired_8_pos 0 -#define reg_aagc_adc_out_desired_8_len 1 -#define reg_aagc_adc_out_desired_8_lsb 0 -#define xd_p_reg_aagc_fixed_gain 0xA016 -#define reg_aagc_fixed_gain_pos 3 -#define reg_aagc_fixed_gain_len 1 -#define reg_aagc_fixed_gain_lsb 0 -#define xd_p_reg_aagc_lock_count_th 0xA016 -#define reg_aagc_lock_count_th_pos 4 -#define reg_aagc_lock_count_th_len 4 -#define reg_aagc_lock_count_th_lsb 0 -#define xd_p_reg_aagc_fixed_rf_agc_control_7_0 0xA017 -#define reg_aagc_fixed_rf_agc_control_7_0_pos 0 -#define reg_aagc_fixed_rf_agc_control_7_0_len 8 -#define reg_aagc_fixed_rf_agc_control_7_0_lsb 0 -#define xd_p_reg_aagc_fixed_rf_agc_control_15_8 0xA018 -#define reg_aagc_fixed_rf_agc_control_15_8_pos 0 -#define reg_aagc_fixed_rf_agc_control_15_8_len 8 -#define reg_aagc_fixed_rf_agc_control_15_8_lsb 8 -#define xd_p_reg_aagc_fixed_rf_agc_control_23_16 0xA019 -#define reg_aagc_fixed_rf_agc_control_23_16_pos 0 -#define reg_aagc_fixed_rf_agc_control_23_16_len 8 -#define reg_aagc_fixed_rf_agc_control_23_16_lsb 16 -#define xd_p_reg_aagc_fixed_rf_agc_control_30_24 0xA01A -#define reg_aagc_fixed_rf_agc_control_30_24_pos 0 -#define reg_aagc_fixed_rf_agc_control_30_24_len 7 -#define reg_aagc_fixed_rf_agc_control_30_24_lsb 24 -#define xd_p_reg_aagc_fixed_if_agc_control_7_0 0xA01B -#define reg_aagc_fixed_if_agc_control_7_0_pos 0 -#define reg_aagc_fixed_if_agc_control_7_0_len 8 -#define reg_aagc_fixed_if_agc_control_7_0_lsb 0 -#define xd_p_reg_aagc_fixed_if_agc_control_15_8 0xA01C -#define reg_aagc_fixed_if_agc_control_15_8_pos 0 -#define reg_aagc_fixed_if_agc_control_15_8_len 8 -#define reg_aagc_fixed_if_agc_control_15_8_lsb 8 -#define xd_p_reg_aagc_fixed_if_agc_control_23_16 0xA01D -#define reg_aagc_fixed_if_agc_control_23_16_pos 0 -#define reg_aagc_fixed_if_agc_control_23_16_len 8 -#define reg_aagc_fixed_if_agc_control_23_16_lsb 16 -#define xd_p_reg_aagc_fixed_if_agc_control_30_24 0xA01E -#define reg_aagc_fixed_if_agc_control_30_24_pos 0 -#define reg_aagc_fixed_if_agc_control_30_24_len 7 -#define reg_aagc_fixed_if_agc_control_30_24_lsb 24 -#define xd_p_reg_aagc_rf_agc_unlock_numerator 0xA01F -#define reg_aagc_rf_agc_unlock_numerator_pos 0 -#define reg_aagc_rf_agc_unlock_numerator_len 6 -#define reg_aagc_rf_agc_unlock_numerator_lsb 0 -#define xd_p_reg_aagc_if_agc_unlock_numerator 0xA020 -#define reg_aagc_if_agc_unlock_numerator_pos 0 -#define reg_aagc_if_agc_unlock_numerator_len 6 -#define reg_aagc_if_agc_unlock_numerator_lsb 0 -#define xd_p_reg_unplug_th 0xA021 -#define reg_unplug_th_pos 0 -#define reg_unplug_th_len 8 -#define reg_aagc_rf_x0_lsb 0 -#define xd_p_reg_weak_signal_rfagc_thr 0xA022 -#define reg_weak_signal_rfagc_thr_pos 0 -#define reg_weak_signal_rfagc_thr_len 8 -#define reg_weak_signal_rfagc_thr_lsb 0 -#define xd_p_reg_unplug_rf_gain_th 0xA023 -#define reg_unplug_rf_gain_th_pos 0 -#define reg_unplug_rf_gain_th_len 8 -#define reg_unplug_rf_gain_th_lsb 0 -#define xd_p_reg_unplug_dtop_rf_gain_th 0xA024 -#define reg_unplug_dtop_rf_gain_th_pos 0 -#define reg_unplug_dtop_rf_gain_th_len 8 -#define reg_unplug_dtop_rf_gain_th_lsb 0 -#define xd_p_reg_unplug_dtop_if_gain_th 0xA025 -#define reg_unplug_dtop_if_gain_th_pos 0 -#define reg_unplug_dtop_if_gain_th_len 8 -#define reg_unplug_dtop_if_gain_th_lsb 0 -#define xd_p_reg_top_recover_at_unplug_en 0xA026 -#define reg_top_recover_at_unplug_en_pos 0 -#define reg_top_recover_at_unplug_en_len 1 -#define reg_top_recover_at_unplug_en_lsb 0 -#define xd_p_reg_aagc_rf_x6 0xA027 -#define reg_aagc_rf_x6_pos 0 -#define reg_aagc_rf_x6_len 8 -#define reg_aagc_rf_x6_lsb 0 -#define xd_p_reg_aagc_rf_x7 0xA028 -#define reg_aagc_rf_x7_pos 0 -#define reg_aagc_rf_x7_len 8 -#define reg_aagc_rf_x7_lsb 0 -#define xd_p_reg_aagc_rf_x8 0xA029 -#define reg_aagc_rf_x8_pos 0 -#define reg_aagc_rf_x8_len 8 -#define reg_aagc_rf_x8_lsb 0 -#define xd_p_reg_aagc_rf_x9 0xA02A -#define reg_aagc_rf_x9_pos 0 -#define reg_aagc_rf_x9_len 8 -#define reg_aagc_rf_x9_lsb 0 -#define xd_p_reg_aagc_rf_x10 0xA02B -#define reg_aagc_rf_x10_pos 0 -#define reg_aagc_rf_x10_len 8 -#define reg_aagc_rf_x10_lsb 0 -#define xd_p_reg_aagc_rf_x11 0xA02C -#define reg_aagc_rf_x11_pos 0 -#define reg_aagc_rf_x11_len 8 -#define reg_aagc_rf_x11_lsb 0 -#define xd_p_reg_aagc_rf_x12 0xA02D -#define reg_aagc_rf_x12_pos 0 -#define reg_aagc_rf_x12_len 8 -#define reg_aagc_rf_x12_lsb 0 -#define xd_p_reg_aagc_rf_x13 0xA02E -#define reg_aagc_rf_x13_pos 0 -#define reg_aagc_rf_x13_len 8 -#define reg_aagc_rf_x13_lsb 0 -#define xd_p_reg_aagc_if_x0 0xA02F -#define reg_aagc_if_x0_pos 0 -#define reg_aagc_if_x0_len 8 -#define reg_aagc_if_x0_lsb 0 -#define xd_p_reg_aagc_if_x1 0xA030 -#define reg_aagc_if_x1_pos 0 -#define reg_aagc_if_x1_len 8 -#define reg_aagc_if_x1_lsb 0 -#define xd_p_reg_aagc_if_x2 0xA031 -#define reg_aagc_if_x2_pos 0 -#define reg_aagc_if_x2_len 8 -#define reg_aagc_if_x2_lsb 0 -#define xd_p_reg_aagc_if_x3 0xA032 -#define reg_aagc_if_x3_pos 0 -#define reg_aagc_if_x3_len 8 -#define reg_aagc_if_x3_lsb 0 -#define xd_p_reg_aagc_if_x4 0xA033 -#define reg_aagc_if_x4_pos 0 -#define reg_aagc_if_x4_len 8 -#define reg_aagc_if_x4_lsb 0 -#define xd_p_reg_aagc_if_x5 0xA034 -#define reg_aagc_if_x5_pos 0 -#define reg_aagc_if_x5_len 8 -#define reg_aagc_if_x5_lsb 0 -#define xd_p_reg_aagc_if_x6 0xA035 -#define reg_aagc_if_x6_pos 0 -#define reg_aagc_if_x6_len 8 -#define reg_aagc_if_x6_lsb 0 -#define xd_p_reg_aagc_if_x7 0xA036 -#define reg_aagc_if_x7_pos 0 -#define reg_aagc_if_x7_len 8 -#define reg_aagc_if_x7_lsb 0 -#define xd_p_reg_aagc_if_x8 0xA037 -#define reg_aagc_if_x8_pos 0 -#define reg_aagc_if_x8_len 8 -#define reg_aagc_if_x8_lsb 0 -#define xd_p_reg_aagc_if_x9 0xA038 -#define reg_aagc_if_x9_pos 0 -#define reg_aagc_if_x9_len 8 -#define reg_aagc_if_x9_lsb 0 -#define xd_p_reg_aagc_if_x10 0xA039 -#define reg_aagc_if_x10_pos 0 -#define reg_aagc_if_x10_len 8 -#define reg_aagc_if_x10_lsb 0 -#define xd_p_reg_aagc_if_x11 0xA03A -#define reg_aagc_if_x11_pos 0 -#define reg_aagc_if_x11_len 8 -#define reg_aagc_if_x11_lsb 0 -#define xd_p_reg_aagc_if_x12 0xA03B -#define reg_aagc_if_x12_pos 0 -#define reg_aagc_if_x12_len 8 -#define reg_aagc_if_x12_lsb 0 -#define xd_p_reg_aagc_if_x13 0xA03C -#define reg_aagc_if_x13_pos 0 -#define reg_aagc_if_x13_len 8 -#define reg_aagc_if_x13_lsb 0 -#define xd_p_reg_aagc_min_rf_ctl_8bit_for_dca 0xA03D -#define reg_aagc_min_rf_ctl_8bit_for_dca_pos 0 -#define reg_aagc_min_rf_ctl_8bit_for_dca_len 8 -#define reg_aagc_min_rf_ctl_8bit_for_dca_lsb 0 -#define xd_p_reg_aagc_min_if_ctl_8bit_for_dca 0xA03E -#define reg_aagc_min_if_ctl_8bit_for_dca_pos 0 -#define reg_aagc_min_if_ctl_8bit_for_dca_len 8 -#define reg_aagc_min_if_ctl_8bit_for_dca_lsb 0 -#define xd_r_reg_aagc_total_gain_7_0 0xA070 -#define reg_aagc_total_gain_7_0_pos 0 -#define reg_aagc_total_gain_7_0_len 8 -#define reg_aagc_total_gain_7_0_lsb 0 -#define xd_r_reg_aagc_total_gain_15_8 0xA071 -#define reg_aagc_total_gain_15_8_pos 0 -#define reg_aagc_total_gain_15_8_len 8 -#define reg_aagc_total_gain_15_8_lsb 8 -#define xd_p_reg_aagc_in_sat_cnt_7_0 0xA074 -#define reg_aagc_in_sat_cnt_7_0_pos 0 -#define reg_aagc_in_sat_cnt_7_0_len 8 -#define reg_aagc_in_sat_cnt_7_0_lsb 0 -#define xd_p_reg_aagc_in_sat_cnt_15_8 0xA075 -#define reg_aagc_in_sat_cnt_15_8_pos 0 -#define reg_aagc_in_sat_cnt_15_8_len 8 -#define reg_aagc_in_sat_cnt_15_8_lsb 8 -#define xd_p_reg_aagc_in_sat_cnt_23_16 0xA076 -#define reg_aagc_in_sat_cnt_23_16_pos 0 -#define reg_aagc_in_sat_cnt_23_16_len 8 -#define reg_aagc_in_sat_cnt_23_16_lsb 16 -#define xd_p_reg_aagc_in_sat_cnt_31_24 0xA077 -#define reg_aagc_in_sat_cnt_31_24_pos 0 -#define reg_aagc_in_sat_cnt_31_24_len 8 -#define reg_aagc_in_sat_cnt_31_24_lsb 24 -#define xd_r_reg_aagc_digital_rf_volt_7_0 0xA078 -#define reg_aagc_digital_rf_volt_7_0_pos 0 -#define reg_aagc_digital_rf_volt_7_0_len 8 -#define reg_aagc_digital_rf_volt_7_0_lsb 0 -#define xd_r_reg_aagc_digital_rf_volt_9_8 0xA079 -#define reg_aagc_digital_rf_volt_9_8_pos 0 -#define reg_aagc_digital_rf_volt_9_8_len 2 -#define reg_aagc_digital_rf_volt_9_8_lsb 8 -#define xd_r_reg_aagc_digital_if_volt_7_0 0xA07A -#define reg_aagc_digital_if_volt_7_0_pos 0 -#define reg_aagc_digital_if_volt_7_0_len 8 -#define reg_aagc_digital_if_volt_7_0_lsb 0 -#define xd_r_reg_aagc_digital_if_volt_9_8 0xA07B -#define reg_aagc_digital_if_volt_9_8_pos 0 -#define reg_aagc_digital_if_volt_9_8_len 2 -#define reg_aagc_digital_if_volt_9_8_lsb 8 -#define xd_r_reg_aagc_rf_gain 0xA07C -#define reg_aagc_rf_gain_pos 0 -#define reg_aagc_rf_gain_len 8 -#define reg_aagc_rf_gain_lsb 0 -#define xd_r_reg_aagc_if_gain 0xA07D -#define reg_aagc_if_gain_pos 0 -#define reg_aagc_if_gain_len 8 -#define reg_aagc_if_gain_lsb 0 -#define xd_p_tinr_imp_indicator 0xA080 -#define tinr_imp_indicator_pos 0 -#define tinr_imp_indicator_len 2 -#define tinr_imp_indicator_lsb 0 -#define xd_p_reg_tinr_fifo_size 0xA080 -#define reg_tinr_fifo_size_pos 2 -#define reg_tinr_fifo_size_len 5 -#define reg_tinr_fifo_size_lsb 0 -#define xd_p_reg_tinr_saturation_cnt_th 0xA081 -#define reg_tinr_saturation_cnt_th_pos 0 -#define reg_tinr_saturation_cnt_th_len 4 -#define reg_tinr_saturation_cnt_th_lsb 0 -#define xd_p_reg_tinr_saturation_th_3_0 0xA081 -#define reg_tinr_saturation_th_3_0_pos 4 -#define reg_tinr_saturation_th_3_0_len 4 -#define reg_tinr_saturation_th_3_0_lsb 0 -#define xd_p_reg_tinr_saturation_th_8_4 0xA082 -#define reg_tinr_saturation_th_8_4_pos 0 -#define reg_tinr_saturation_th_8_4_len 5 -#define reg_tinr_saturation_th_8_4_lsb 4 -#define xd_p_reg_tinr_imp_duration_th_2k_7_0 0xA083 -#define reg_tinr_imp_duration_th_2k_7_0_pos 0 -#define reg_tinr_imp_duration_th_2k_7_0_len 8 -#define reg_tinr_imp_duration_th_2k_7_0_lsb 0 -#define xd_p_reg_tinr_imp_duration_th_2k_8 0xA084 -#define reg_tinr_imp_duration_th_2k_8_pos 0 -#define reg_tinr_imp_duration_th_2k_8_len 1 -#define reg_tinr_imp_duration_th_2k_8_lsb 0 -#define xd_p_reg_tinr_imp_duration_th_8k_7_0 0xA085 -#define reg_tinr_imp_duration_th_8k_7_0_pos 0 -#define reg_tinr_imp_duration_th_8k_7_0_len 8 -#define reg_tinr_imp_duration_th_8k_7_0_lsb 0 -#define xd_p_reg_tinr_imp_duration_th_8k_10_8 0xA086 -#define reg_tinr_imp_duration_th_8k_10_8_pos 0 -#define reg_tinr_imp_duration_th_8k_10_8_len 3 -#define reg_tinr_imp_duration_th_8k_10_8_lsb 8 -#define xd_p_reg_tinr_freq_ratio_6m_7_0 0xA087 -#define reg_tinr_freq_ratio_6m_7_0_pos 0 -#define reg_tinr_freq_ratio_6m_7_0_len 8 -#define reg_tinr_freq_ratio_6m_7_0_lsb 0 -#define xd_p_reg_tinr_freq_ratio_6m_12_8 0xA088 -#define reg_tinr_freq_ratio_6m_12_8_pos 0 -#define reg_tinr_freq_ratio_6m_12_8_len 5 -#define reg_tinr_freq_ratio_6m_12_8_lsb 8 -#define xd_p_reg_tinr_freq_ratio_7m_7_0 0xA089 -#define reg_tinr_freq_ratio_7m_7_0_pos 0 -#define reg_tinr_freq_ratio_7m_7_0_len 8 -#define reg_tinr_freq_ratio_7m_7_0_lsb 0 -#define xd_p_reg_tinr_freq_ratio_7m_12_8 0xA08A -#define reg_tinr_freq_ratio_7m_12_8_pos 0 -#define reg_tinr_freq_ratio_7m_12_8_len 5 -#define reg_tinr_freq_ratio_7m_12_8_lsb 8 -#define xd_p_reg_tinr_freq_ratio_8m_7_0 0xA08B -#define reg_tinr_freq_ratio_8m_7_0_pos 0 -#define reg_tinr_freq_ratio_8m_7_0_len 8 -#define reg_tinr_freq_ratio_8m_7_0_lsb 0 -#define xd_p_reg_tinr_freq_ratio_8m_12_8 0xA08C -#define reg_tinr_freq_ratio_8m_12_8_pos 0 -#define reg_tinr_freq_ratio_8m_12_8_len 5 -#define reg_tinr_freq_ratio_8m_12_8_lsb 8 -#define xd_p_reg_tinr_imp_duration_th_low_2k 0xA08D -#define reg_tinr_imp_duration_th_low_2k_pos 0 -#define reg_tinr_imp_duration_th_low_2k_len 8 -#define reg_tinr_imp_duration_th_low_2k_lsb 0 -#define xd_p_reg_tinr_imp_duration_th_low_8k 0xA08E -#define reg_tinr_imp_duration_th_low_8k_pos 0 -#define reg_tinr_imp_duration_th_low_8k_len 8 -#define reg_tinr_imp_duration_th_low_8k_lsb 0 -#define xd_r_reg_tinr_counter_7_0 0xA090 -#define reg_tinr_counter_7_0_pos 0 -#define reg_tinr_counter_7_0_len 8 -#define reg_tinr_counter_7_0_lsb 0 -#define xd_r_reg_tinr_counter_15_8 0xA091 -#define reg_tinr_counter_15_8_pos 0 -#define reg_tinr_counter_15_8_len 8 -#define reg_tinr_counter_15_8_lsb 8 -#define xd_p_reg_tinr_adative_tinr_en 0xA093 -#define reg_tinr_adative_tinr_en_pos 0 -#define reg_tinr_adative_tinr_en_len 1 -#define reg_tinr_adative_tinr_en_lsb 0 -#define xd_p_reg_tinr_peak_fifo_size 0xA093 -#define reg_tinr_peak_fifo_size_pos 1 -#define reg_tinr_peak_fifo_size_len 5 -#define reg_tinr_peak_fifo_size_lsb 0 -#define xd_p_reg_tinr_counter_rst 0xA093 -#define reg_tinr_counter_rst_pos 6 -#define reg_tinr_counter_rst_len 1 -#define reg_tinr_counter_rst_lsb 0 -#define xd_p_reg_tinr_search_period_7_0 0xA094 -#define reg_tinr_search_period_7_0_pos 0 -#define reg_tinr_search_period_7_0_len 8 -#define reg_tinr_search_period_7_0_lsb 0 -#define xd_p_reg_tinr_search_period_15_8 0xA095 -#define reg_tinr_search_period_15_8_pos 0 -#define reg_tinr_search_period_15_8_len 8 -#define reg_tinr_search_period_15_8_lsb 8 -#define xd_p_reg_ccifs_fcw_7_0 0xA0A0 -#define reg_ccifs_fcw_7_0_pos 0 -#define reg_ccifs_fcw_7_0_len 8 -#define reg_ccifs_fcw_7_0_lsb 0 -#define xd_p_reg_ccifs_fcw_12_8 0xA0A1 -#define reg_ccifs_fcw_12_8_pos 0 -#define reg_ccifs_fcw_12_8_len 5 -#define reg_ccifs_fcw_12_8_lsb 8 -#define xd_p_reg_ccifs_spec_inv 0xA0A1 -#define reg_ccifs_spec_inv_pos 5 -#define reg_ccifs_spec_inv_len 1 -#define reg_ccifs_spec_inv_lsb 0 -#define xd_p_reg_gp_trigger 0xA0A2 -#define reg_gp_trigger_pos 0 -#define reg_gp_trigger_len 1 -#define reg_gp_trigger_lsb 0 -#define xd_p_reg_trigger_sel 0xA0A2 -#define reg_trigger_sel_pos 1 -#define reg_trigger_sel_len 2 -#define reg_trigger_sel_lsb 0 -#define xd_p_reg_debug_ofdm 0xA0A2 -#define reg_debug_ofdm_pos 3 -#define reg_debug_ofdm_len 2 -#define reg_debug_ofdm_lsb 0 -#define xd_p_reg_trigger_module_sel 0xA0A3 -#define reg_trigger_module_sel_pos 0 -#define reg_trigger_module_sel_len 6 -#define reg_trigger_module_sel_lsb 0 -#define xd_p_reg_trigger_set_sel 0xA0A4 -#define reg_trigger_set_sel_pos 0 -#define reg_trigger_set_sel_len 6 -#define reg_trigger_set_sel_lsb 0 -#define xd_p_reg_fw_int_mask_n 0xA0A4 -#define reg_fw_int_mask_n_pos 6 -#define reg_fw_int_mask_n_len 1 -#define reg_fw_int_mask_n_lsb 0 -#define xd_p_reg_debug_group 0xA0A5 -#define reg_debug_group_pos 0 -#define reg_debug_group_len 4 -#define reg_debug_group_lsb 0 -#define xd_p_reg_odbg_clk_sel 0xA0A5 -#define reg_odbg_clk_sel_pos 4 -#define reg_odbg_clk_sel_len 2 -#define reg_odbg_clk_sel_lsb 0 -#define xd_p_reg_ccif_sc 0xA0C0 -#define reg_ccif_sc_pos 0 -#define reg_ccif_sc_len 4 -#define reg_ccif_sc_lsb 0 -#define xd_r_reg_ccif_saturate 0xA0C1 -#define reg_ccif_saturate_pos 0 -#define reg_ccif_saturate_len 2 -#define reg_ccif_saturate_lsb 0 -#define xd_r_reg_antif_saturate 0xA0C1 -#define reg_antif_saturate_pos 2 -#define reg_antif_saturate_len 4 -#define reg_antif_saturate_lsb 0 -#define xd_r_reg_acif_saturate 0xA0C2 -#define reg_acif_saturate_pos 0 -#define reg_acif_saturate_len 8 -#define reg_acif_saturate_lsb 0 -#define xd_p_reg_tmr_timer0_threshold_7_0 0xA0C8 -#define reg_tmr_timer0_threshold_7_0_pos 0 -#define reg_tmr_timer0_threshold_7_0_len 8 -#define reg_tmr_timer0_threshold_7_0_lsb 0 -#define xd_p_reg_tmr_timer0_threshold_15_8 0xA0C9 -#define reg_tmr_timer0_threshold_15_8_pos 0 -#define reg_tmr_timer0_threshold_15_8_len 8 -#define reg_tmr_timer0_threshold_15_8_lsb 8 -#define xd_p_reg_tmr_timer0_enable 0xA0CA -#define reg_tmr_timer0_enable_pos 0 -#define reg_tmr_timer0_enable_len 1 -#define reg_tmr_timer0_enable_lsb 0 -#define xd_p_reg_tmr_timer0_clk_sel 0xA0CA -#define reg_tmr_timer0_clk_sel_pos 1 -#define reg_tmr_timer0_clk_sel_len 1 -#define reg_tmr_timer0_clk_sel_lsb 0 -#define xd_p_reg_tmr_timer0_int 0xA0CA -#define reg_tmr_timer0_int_pos 2 -#define reg_tmr_timer0_int_len 1 -#define reg_tmr_timer0_int_lsb 0 -#define xd_p_reg_tmr_timer0_rst 0xA0CA -#define reg_tmr_timer0_rst_pos 3 -#define reg_tmr_timer0_rst_len 1 -#define reg_tmr_timer0_rst_lsb 0 -#define xd_r_reg_tmr_timer0_count_7_0 0xA0CB -#define reg_tmr_timer0_count_7_0_pos 0 -#define reg_tmr_timer0_count_7_0_len 8 -#define reg_tmr_timer0_count_7_0_lsb 0 -#define xd_r_reg_tmr_timer0_count_15_8 0xA0CC -#define reg_tmr_timer0_count_15_8_pos 0 -#define reg_tmr_timer0_count_15_8_len 8 -#define reg_tmr_timer0_count_15_8_lsb 8 -#define xd_p_reg_suspend 0xA0CD -#define reg_suspend_pos 0 -#define reg_suspend_len 1 -#define reg_suspend_lsb 0 -#define xd_p_reg_suspend_rdy 0xA0CD -#define reg_suspend_rdy_pos 1 -#define reg_suspend_rdy_len 1 -#define reg_suspend_rdy_lsb 0 -#define xd_p_reg_resume 0xA0CD -#define reg_resume_pos 2 -#define reg_resume_len 1 -#define reg_resume_lsb 0 -#define xd_p_reg_resume_rdy 0xA0CD -#define reg_resume_rdy_pos 3 -#define reg_resume_rdy_len 1 -#define reg_resume_rdy_lsb 0 -#define xd_p_reg_fmf 0xA0CE -#define reg_fmf_pos 0 -#define reg_fmf_len 8 -#define reg_fmf_lsb 0 -#define xd_p_ccid_accumulate_num_2k_7_0 0xA100 -#define ccid_accumulate_num_2k_7_0_pos 0 -#define ccid_accumulate_num_2k_7_0_len 8 -#define ccid_accumulate_num_2k_7_0_lsb 0 -#define xd_p_ccid_accumulate_num_2k_12_8 0xA101 -#define ccid_accumulate_num_2k_12_8_pos 0 -#define ccid_accumulate_num_2k_12_8_len 5 -#define ccid_accumulate_num_2k_12_8_lsb 8 -#define xd_p_ccid_accumulate_num_8k_7_0 0xA102 -#define ccid_accumulate_num_8k_7_0_pos 0 -#define ccid_accumulate_num_8k_7_0_len 8 -#define ccid_accumulate_num_8k_7_0_lsb 0 -#define xd_p_ccid_accumulate_num_8k_14_8 0xA103 -#define ccid_accumulate_num_8k_14_8_pos 0 -#define ccid_accumulate_num_8k_14_8_len 7 -#define ccid_accumulate_num_8k_14_8_lsb 8 -#define xd_p_ccid_desired_level_0 0xA103 -#define ccid_desired_level_0_pos 7 -#define ccid_desired_level_0_len 1 -#define ccid_desired_level_0_lsb 0 -#define xd_p_ccid_desired_level_8_1 0xA104 -#define ccid_desired_level_8_1_pos 0 -#define ccid_desired_level_8_1_len 8 -#define ccid_desired_level_8_1_lsb 1 -#define xd_p_ccid_apply_delay 0xA105 -#define ccid_apply_delay_pos 0 -#define ccid_apply_delay_len 7 -#define ccid_apply_delay_lsb 0 -#define xd_p_ccid_CCID_Threshold1 0xA106 -#define ccid_CCID_Threshold1_pos 0 -#define ccid_CCID_Threshold1_len 8 -#define ccid_CCID_Threshold1_lsb 0 -#define xd_p_ccid_CCID_Threshold2 0xA107 -#define ccid_CCID_Threshold2_pos 0 -#define ccid_CCID_Threshold2_len 8 -#define ccid_CCID_Threshold2_lsb 0 -#define xd_p_reg_ccid_gain_scale 0xA108 -#define reg_ccid_gain_scale_pos 0 -#define reg_ccid_gain_scale_len 4 -#define reg_ccid_gain_scale_lsb 0 -#define xd_p_reg_ccid2_passband_gain_set 0xA108 -#define reg_ccid2_passband_gain_set_pos 4 -#define reg_ccid2_passband_gain_set_len 4 -#define reg_ccid2_passband_gain_set_lsb 0 -#define xd_r_ccid_multiplier_7_0 0xA109 -#define ccid_multiplier_7_0_pos 0 -#define ccid_multiplier_7_0_len 8 -#define ccid_multiplier_7_0_lsb 0 -#define xd_r_ccid_multiplier_15_8 0xA10A -#define ccid_multiplier_15_8_pos 0 -#define ccid_multiplier_15_8_len 8 -#define ccid_multiplier_15_8_lsb 8 -#define xd_r_ccid_right_shift_bits 0xA10B -#define ccid_right_shift_bits_pos 0 -#define ccid_right_shift_bits_len 4 -#define ccid_right_shift_bits_lsb 0 -#define xd_r_reg_ccid_sx_7_0 0xA10C -#define reg_ccid_sx_7_0_pos 0 -#define reg_ccid_sx_7_0_len 8 -#define reg_ccid_sx_7_0_lsb 0 -#define xd_r_reg_ccid_sx_15_8 0xA10D -#define reg_ccid_sx_15_8_pos 0 -#define reg_ccid_sx_15_8_len 8 -#define reg_ccid_sx_15_8_lsb 8 -#define xd_r_reg_ccid_sx_21_16 0xA10E -#define reg_ccid_sx_21_16_pos 0 -#define reg_ccid_sx_21_16_len 6 -#define reg_ccid_sx_21_16_lsb 16 -#define xd_r_reg_ccid_sy_7_0 0xA110 -#define reg_ccid_sy_7_0_pos 0 -#define reg_ccid_sy_7_0_len 8 -#define reg_ccid_sy_7_0_lsb 0 -#define xd_r_reg_ccid_sy_15_8 0xA111 -#define reg_ccid_sy_15_8_pos 0 -#define reg_ccid_sy_15_8_len 8 -#define reg_ccid_sy_15_8_lsb 8 -#define xd_r_reg_ccid_sy_23_16 0xA112 -#define reg_ccid_sy_23_16_pos 0 -#define reg_ccid_sy_23_16_len 8 -#define reg_ccid_sy_23_16_lsb 16 -#define xd_r_reg_ccid2_sz_7_0 0xA114 -#define reg_ccid2_sz_7_0_pos 0 -#define reg_ccid2_sz_7_0_len 8 -#define reg_ccid2_sz_7_0_lsb 0 -#define xd_r_reg_ccid2_sz_15_8 0xA115 -#define reg_ccid2_sz_15_8_pos 0 -#define reg_ccid2_sz_15_8_len 8 -#define reg_ccid2_sz_15_8_lsb 8 -#define xd_r_reg_ccid2_sz_23_16 0xA116 -#define reg_ccid2_sz_23_16_pos 0 -#define reg_ccid2_sz_23_16_len 8 -#define reg_ccid2_sz_23_16_lsb 16 -#define xd_r_reg_ccid2_sz_25_24 0xA117 -#define reg_ccid2_sz_25_24_pos 0 -#define reg_ccid2_sz_25_24_len 2 -#define reg_ccid2_sz_25_24_lsb 24 -#define xd_r_reg_ccid2_sy_7_0 0xA118 -#define reg_ccid2_sy_7_0_pos 0 -#define reg_ccid2_sy_7_0_len 8 -#define reg_ccid2_sy_7_0_lsb 0 -#define xd_r_reg_ccid2_sy_15_8 0xA119 -#define reg_ccid2_sy_15_8_pos 0 -#define reg_ccid2_sy_15_8_len 8 -#define reg_ccid2_sy_15_8_lsb 8 -#define xd_r_reg_ccid2_sy_23_16 0xA11A -#define reg_ccid2_sy_23_16_pos 0 -#define reg_ccid2_sy_23_16_len 8 -#define reg_ccid2_sy_23_16_lsb 16 -#define xd_r_reg_ccid2_sy_25_24 0xA11B -#define reg_ccid2_sy_25_24_pos 0 -#define reg_ccid2_sy_25_24_len 2 -#define reg_ccid2_sy_25_24_lsb 24 -#define xd_p_dagc1_accumulate_num_2k_7_0 0xA120 -#define dagc1_accumulate_num_2k_7_0_pos 0 -#define dagc1_accumulate_num_2k_7_0_len 8 -#define dagc1_accumulate_num_2k_7_0_lsb 0 -#define xd_p_dagc1_accumulate_num_2k_12_8 0xA121 -#define dagc1_accumulate_num_2k_12_8_pos 0 -#define dagc1_accumulate_num_2k_12_8_len 5 -#define dagc1_accumulate_num_2k_12_8_lsb 8 -#define xd_p_dagc1_accumulate_num_8k_7_0 0xA122 -#define dagc1_accumulate_num_8k_7_0_pos 0 -#define dagc1_accumulate_num_8k_7_0_len 8 -#define dagc1_accumulate_num_8k_7_0_lsb 0 -#define xd_p_dagc1_accumulate_num_8k_14_8 0xA123 -#define dagc1_accumulate_num_8k_14_8_pos 0 -#define dagc1_accumulate_num_8k_14_8_len 7 -#define dagc1_accumulate_num_8k_14_8_lsb 8 -#define xd_p_dagc1_desired_level_0 0xA123 -#define dagc1_desired_level_0_pos 7 -#define dagc1_desired_level_0_len 1 -#define dagc1_desired_level_0_lsb 0 -#define xd_p_dagc1_desired_level_8_1 0xA124 -#define dagc1_desired_level_8_1_pos 0 -#define dagc1_desired_level_8_1_len 8 -#define dagc1_desired_level_8_1_lsb 1 -#define xd_p_dagc1_apply_delay 0xA125 -#define dagc1_apply_delay_pos 0 -#define dagc1_apply_delay_len 7 -#define dagc1_apply_delay_lsb 0 -#define xd_p_dagc1_bypass_scale_ctl 0xA126 -#define dagc1_bypass_scale_ctl_pos 0 -#define dagc1_bypass_scale_ctl_len 2 -#define dagc1_bypass_scale_ctl_lsb 0 -#define xd_p_reg_dagc1_in_sat_cnt_7_0 0xA127 -#define reg_dagc1_in_sat_cnt_7_0_pos 0 -#define reg_dagc1_in_sat_cnt_7_0_len 8 -#define reg_dagc1_in_sat_cnt_7_0_lsb 0 -#define xd_p_reg_dagc1_in_sat_cnt_15_8 0xA128 -#define reg_dagc1_in_sat_cnt_15_8_pos 0 -#define reg_dagc1_in_sat_cnt_15_8_len 8 -#define reg_dagc1_in_sat_cnt_15_8_lsb 8 -#define xd_p_reg_dagc1_in_sat_cnt_23_16 0xA129 -#define reg_dagc1_in_sat_cnt_23_16_pos 0 -#define reg_dagc1_in_sat_cnt_23_16_len 8 -#define reg_dagc1_in_sat_cnt_23_16_lsb 16 -#define xd_p_reg_dagc1_in_sat_cnt_31_24 0xA12A -#define reg_dagc1_in_sat_cnt_31_24_pos 0 -#define reg_dagc1_in_sat_cnt_31_24_len 8 -#define reg_dagc1_in_sat_cnt_31_24_lsb 24 -#define xd_p_reg_dagc1_out_sat_cnt_7_0 0xA12B -#define reg_dagc1_out_sat_cnt_7_0_pos 0 -#define reg_dagc1_out_sat_cnt_7_0_len 8 -#define reg_dagc1_out_sat_cnt_7_0_lsb 0 -#define xd_p_reg_dagc1_out_sat_cnt_15_8 0xA12C -#define reg_dagc1_out_sat_cnt_15_8_pos 0 -#define reg_dagc1_out_sat_cnt_15_8_len 8 -#define reg_dagc1_out_sat_cnt_15_8_lsb 8 -#define xd_p_reg_dagc1_out_sat_cnt_23_16 0xA12D -#define reg_dagc1_out_sat_cnt_23_16_pos 0 -#define reg_dagc1_out_sat_cnt_23_16_len 8 -#define reg_dagc1_out_sat_cnt_23_16_lsb 16 -#define xd_p_reg_dagc1_out_sat_cnt_31_24 0xA12E -#define reg_dagc1_out_sat_cnt_31_24_pos 0 -#define reg_dagc1_out_sat_cnt_31_24_len 8 -#define reg_dagc1_out_sat_cnt_31_24_lsb 24 -#define xd_r_dagc1_multiplier_7_0 0xA136 -#define dagc1_multiplier_7_0_pos 0 -#define dagc1_multiplier_7_0_len 8 -#define dagc1_multiplier_7_0_lsb 0 -#define xd_r_dagc1_multiplier_15_8 0xA137 -#define dagc1_multiplier_15_8_pos 0 -#define dagc1_multiplier_15_8_len 8 -#define dagc1_multiplier_15_8_lsb 8 -#define xd_r_dagc1_right_shift_bits 0xA138 -#define dagc1_right_shift_bits_pos 0 -#define dagc1_right_shift_bits_len 4 -#define dagc1_right_shift_bits_lsb 0 -#define xd_p_reg_bfs_fcw_7_0 0xA140 -#define reg_bfs_fcw_7_0_pos 0 -#define reg_bfs_fcw_7_0_len 8 -#define reg_bfs_fcw_7_0_lsb 0 -#define xd_p_reg_bfs_fcw_15_8 0xA141 -#define reg_bfs_fcw_15_8_pos 0 -#define reg_bfs_fcw_15_8_len 8 -#define reg_bfs_fcw_15_8_lsb 8 -#define xd_p_reg_bfs_fcw_22_16 0xA142 -#define reg_bfs_fcw_22_16_pos 0 -#define reg_bfs_fcw_22_16_len 7 -#define reg_bfs_fcw_22_16_lsb 16 -#define xd_p_reg_antif_sf_7_0 0xA144 -#define reg_antif_sf_7_0_pos 0 -#define reg_antif_sf_7_0_len 8 -#define reg_antif_sf_7_0_lsb 0 -#define xd_p_reg_antif_sf_11_8 0xA145 -#define reg_antif_sf_11_8_pos 0 -#define reg_antif_sf_11_8_len 4 -#define reg_antif_sf_11_8_lsb 8 -#define xd_r_bfs_fcw_q_7_0 0xA150 -#define bfs_fcw_q_7_0_pos 0 -#define bfs_fcw_q_7_0_len 8 -#define bfs_fcw_q_7_0_lsb 0 -#define xd_r_bfs_fcw_q_15_8 0xA151 -#define bfs_fcw_q_15_8_pos 0 -#define bfs_fcw_q_15_8_len 8 -#define bfs_fcw_q_15_8_lsb 8 -#define xd_r_bfs_fcw_q_22_16 0xA152 -#define bfs_fcw_q_22_16_pos 0 -#define bfs_fcw_q_22_16_len 7 -#define bfs_fcw_q_22_16_lsb 16 -#define xd_p_reg_dca_enu 0xA160 -#define reg_dca_enu_pos 0 -#define reg_dca_enu_len 1 -#define reg_dca_enu_lsb 0 -#define xd_p_reg_dca_enl 0xA160 -#define reg_dca_enl_pos 1 -#define reg_dca_enl_len 1 -#define reg_dca_enl_lsb 0 -#define xd_p_reg_dca_lower_chip 0xA160 -#define reg_dca_lower_chip_pos 2 -#define reg_dca_lower_chip_len 1 -#define reg_dca_lower_chip_lsb 0 -#define xd_p_reg_dca_upper_chip 0xA160 -#define reg_dca_upper_chip_pos 3 -#define reg_dca_upper_chip_len 1 -#define reg_dca_upper_chip_lsb 0 -#define xd_p_reg_dca_platch 0xA160 -#define reg_dca_platch_pos 4 -#define reg_dca_platch_len 1 -#define reg_dca_platch_lsb 0 -#define xd_p_reg_dca_th 0xA161 -#define reg_dca_th_pos 0 -#define reg_dca_th_len 5 -#define reg_dca_th_lsb 0 -#define xd_p_reg_dca_scale 0xA162 -#define reg_dca_scale_pos 0 -#define reg_dca_scale_len 4 -#define reg_dca_scale_lsb 0 -#define xd_p_reg_dca_tone_7_0 0xA163 -#define reg_dca_tone_7_0_pos 0 -#define reg_dca_tone_7_0_len 8 -#define reg_dca_tone_7_0_lsb 0 -#define xd_p_reg_dca_tone_12_8 0xA164 -#define reg_dca_tone_12_8_pos 0 -#define reg_dca_tone_12_8_len 5 -#define reg_dca_tone_12_8_lsb 8 -#define xd_p_reg_dca_time_7_0 0xA165 -#define reg_dca_time_7_0_pos 0 -#define reg_dca_time_7_0_len 8 -#define reg_dca_time_7_0_lsb 0 -#define xd_p_reg_dca_time_15_8 0xA166 -#define reg_dca_time_15_8_pos 0 -#define reg_dca_time_15_8_len 8 -#define reg_dca_time_15_8_lsb 8 -#define xd_r_dcasm 0xA167 -#define dcasm_pos 0 -#define dcasm_len 3 -#define dcasm_lsb 0 -#define xd_p_reg_qnt_valuew_7_0 0xA168 -#define reg_qnt_valuew_7_0_pos 0 -#define reg_qnt_valuew_7_0_len 8 -#define reg_qnt_valuew_7_0_lsb 0 -#define xd_p_reg_qnt_valuew_10_8 0xA169 -#define reg_qnt_valuew_10_8_pos 0 -#define reg_qnt_valuew_10_8_len 3 -#define reg_qnt_valuew_10_8_lsb 8 -#define xd_p_dca_sbx_gain_diff_7_0 0xA16A -#define dca_sbx_gain_diff_7_0_pos 0 -#define dca_sbx_gain_diff_7_0_len 8 -#define dca_sbx_gain_diff_7_0_lsb 0 -#define xd_p_dca_sbx_gain_diff_9_8 0xA16B -#define dca_sbx_gain_diff_9_8_pos 0 -#define dca_sbx_gain_diff_9_8_len 2 -#define dca_sbx_gain_diff_9_8_lsb 8 -#define xd_p_reg_dca_stand_alone 0xA16C -#define reg_dca_stand_alone_pos 0 -#define reg_dca_stand_alone_len 1 -#define reg_dca_stand_alone_lsb 0 -#define xd_p_reg_dca_upper_out_en 0xA16C -#define reg_dca_upper_out_en_pos 1 -#define reg_dca_upper_out_en_len 1 -#define reg_dca_upper_out_en_lsb 0 -#define xd_p_reg_dca_rc_en 0xA16C -#define reg_dca_rc_en_pos 2 -#define reg_dca_rc_en_len 1 -#define reg_dca_rc_en_lsb 0 -#define xd_p_reg_dca_retrain_send 0xA16C -#define reg_dca_retrain_send_pos 3 -#define reg_dca_retrain_send_len 1 -#define reg_dca_retrain_send_lsb 0 -#define xd_p_reg_dca_retrain_rec 0xA16C -#define reg_dca_retrain_rec_pos 4 -#define reg_dca_retrain_rec_len 1 -#define reg_dca_retrain_rec_lsb 0 -#define xd_p_reg_dca_api_tpsrdy 0xA16C -#define reg_dca_api_tpsrdy_pos 5 -#define reg_dca_api_tpsrdy_len 1 -#define reg_dca_api_tpsrdy_lsb 0 -#define xd_p_reg_dca_symbol_gap 0xA16D -#define reg_dca_symbol_gap_pos 0 -#define reg_dca_symbol_gap_len 4 -#define reg_dca_symbol_gap_lsb 0 -#define xd_p_reg_qnt_nfvaluew_7_0 0xA16E -#define reg_qnt_nfvaluew_7_0_pos 0 -#define reg_qnt_nfvaluew_7_0_len 8 -#define reg_qnt_nfvaluew_7_0_lsb 0 -#define xd_p_reg_qnt_nfvaluew_10_8 0xA16F -#define reg_qnt_nfvaluew_10_8_pos 0 -#define reg_qnt_nfvaluew_10_8_len 3 -#define reg_qnt_nfvaluew_10_8_lsb 8 -#define xd_p_reg_qnt_flatness_thr_7_0 0xA170 -#define reg_qnt_flatness_thr_7_0_pos 0 -#define reg_qnt_flatness_thr_7_0_len 8 -#define reg_qnt_flatness_thr_7_0_lsb 0 -#define xd_p_reg_qnt_flatness_thr_9_8 0xA171 -#define reg_qnt_flatness_thr_9_8_pos 0 -#define reg_qnt_flatness_thr_9_8_len 2 -#define reg_qnt_flatness_thr_9_8_lsb 8 -#define xd_p_reg_dca_tone_idx_5_0 0xA171 -#define reg_dca_tone_idx_5_0_pos 2 -#define reg_dca_tone_idx_5_0_len 6 -#define reg_dca_tone_idx_5_0_lsb 0 -#define xd_p_reg_dca_tone_idx_12_6 0xA172 -#define reg_dca_tone_idx_12_6_pos 0 -#define reg_dca_tone_idx_12_6_len 7 -#define reg_dca_tone_idx_12_6_lsb 6 -#define xd_p_reg_dca_data_vld 0xA173 -#define reg_dca_data_vld_pos 0 -#define reg_dca_data_vld_len 1 -#define reg_dca_data_vld_lsb 0 -#define xd_p_reg_dca_read_update 0xA173 -#define reg_dca_read_update_pos 1 -#define reg_dca_read_update_len 1 -#define reg_dca_read_update_lsb 0 -#define xd_r_reg_dca_data_re_5_0 0xA173 -#define reg_dca_data_re_5_0_pos 2 -#define reg_dca_data_re_5_0_len 6 -#define reg_dca_data_re_5_0_lsb 0 -#define xd_r_reg_dca_data_re_10_6 0xA174 -#define reg_dca_data_re_10_6_pos 0 -#define reg_dca_data_re_10_6_len 5 -#define reg_dca_data_re_10_6_lsb 6 -#define xd_r_reg_dca_data_im_7_0 0xA175 -#define reg_dca_data_im_7_0_pos 0 -#define reg_dca_data_im_7_0_len 8 -#define reg_dca_data_im_7_0_lsb 0 -#define xd_r_reg_dca_data_im_10_8 0xA176 -#define reg_dca_data_im_10_8_pos 0 -#define reg_dca_data_im_10_8_len 3 -#define reg_dca_data_im_10_8_lsb 8 -#define xd_r_reg_dca_data_h2_7_0 0xA178 -#define reg_dca_data_h2_7_0_pos 0 -#define reg_dca_data_h2_7_0_len 8 -#define reg_dca_data_h2_7_0_lsb 0 -#define xd_r_reg_dca_data_h2_9_8 0xA179 -#define reg_dca_data_h2_9_8_pos 0 -#define reg_dca_data_h2_9_8_len 2 -#define reg_dca_data_h2_9_8_lsb 8 -#define xd_p_reg_f_adc_7_0 0xA180 -#define reg_f_adc_7_0_pos 0 -#define reg_f_adc_7_0_len 8 -#define reg_f_adc_7_0_lsb 0 -#define xd_p_reg_f_adc_15_8 0xA181 -#define reg_f_adc_15_8_pos 0 -#define reg_f_adc_15_8_len 8 -#define reg_f_adc_15_8_lsb 8 -#define xd_p_reg_f_adc_23_16 0xA182 -#define reg_f_adc_23_16_pos 0 -#define reg_f_adc_23_16_len 8 -#define reg_f_adc_23_16_lsb 16 -#define xd_r_intp_mu_7_0 0xA190 -#define intp_mu_7_0_pos 0 -#define intp_mu_7_0_len 8 -#define intp_mu_7_0_lsb 0 -#define xd_r_intp_mu_15_8 0xA191 -#define intp_mu_15_8_pos 0 -#define intp_mu_15_8_len 8 -#define intp_mu_15_8_lsb 8 -#define xd_r_intp_mu_19_16 0xA192 -#define intp_mu_19_16_pos 0 -#define intp_mu_19_16_len 4 -#define intp_mu_19_16_lsb 16 -#define xd_p_reg_agc_rst 0xA1A0 -#define reg_agc_rst_pos 0 -#define reg_agc_rst_len 1 -#define reg_agc_rst_lsb 0 -#define xd_p_rf_agc_en 0xA1A0 -#define rf_agc_en_pos 1 -#define rf_agc_en_len 1 -#define rf_agc_en_lsb 0 -#define xd_p_rf_agc_dis 0xA1A0 -#define rf_agc_dis_pos 2 -#define rf_agc_dis_len 1 -#define rf_agc_dis_lsb 0 -#define xd_p_if_agc_rst 0xA1A0 -#define if_agc_rst_pos 3 -#define if_agc_rst_len 1 -#define if_agc_rst_lsb 0 -#define xd_p_if_agc_en 0xA1A0 -#define if_agc_en_pos 4 -#define if_agc_en_len 1 -#define if_agc_en_lsb 0 -#define xd_p_if_agc_dis 0xA1A0 -#define if_agc_dis_pos 5 -#define if_agc_dis_len 1 -#define if_agc_dis_lsb 0 -#define xd_p_agc_lock 0xA1A0 -#define agc_lock_pos 6 -#define agc_lock_len 1 -#define agc_lock_lsb 0 -#define xd_p_reg_tinr_rst 0xA1A1 -#define reg_tinr_rst_pos 0 -#define reg_tinr_rst_len 1 -#define reg_tinr_rst_lsb 0 -#define xd_p_reg_tinr_en 0xA1A1 -#define reg_tinr_en_pos 1 -#define reg_tinr_en_len 1 -#define reg_tinr_en_lsb 0 -#define xd_p_reg_ccifs_en 0xA1A2 -#define reg_ccifs_en_pos 0 -#define reg_ccifs_en_len 1 -#define reg_ccifs_en_lsb 0 -#define xd_p_reg_ccifs_dis 0xA1A2 -#define reg_ccifs_dis_pos 1 -#define reg_ccifs_dis_len 1 -#define reg_ccifs_dis_lsb 0 -#define xd_p_reg_ccifs_rst 0xA1A2 -#define reg_ccifs_rst_pos 2 -#define reg_ccifs_rst_len 1 -#define reg_ccifs_rst_lsb 0 -#define xd_p_reg_ccifs_byp 0xA1A2 -#define reg_ccifs_byp_pos 3 -#define reg_ccifs_byp_len 1 -#define reg_ccifs_byp_lsb 0 -#define xd_p_reg_ccif_en 0xA1A3 -#define reg_ccif_en_pos 0 -#define reg_ccif_en_len 1 -#define reg_ccif_en_lsb 0 -#define xd_p_reg_ccif_dis 0xA1A3 -#define reg_ccif_dis_pos 1 -#define reg_ccif_dis_len 1 -#define reg_ccif_dis_lsb 0 -#define xd_p_reg_ccif_rst 0xA1A3 -#define reg_ccif_rst_pos 2 -#define reg_ccif_rst_len 1 -#define reg_ccif_rst_lsb 0 -#define xd_p_reg_ccif_byp 0xA1A3 -#define reg_ccif_byp_pos 3 -#define reg_ccif_byp_len 1 -#define reg_ccif_byp_lsb 0 -#define xd_p_dagc1_rst 0xA1A4 -#define dagc1_rst_pos 0 -#define dagc1_rst_len 1 -#define dagc1_rst_lsb 0 -#define xd_p_dagc1_en 0xA1A4 -#define dagc1_en_pos 1 -#define dagc1_en_len 1 -#define dagc1_en_lsb 0 -#define xd_p_dagc1_mode 0xA1A4 -#define dagc1_mode_pos 2 -#define dagc1_mode_len 2 -#define dagc1_mode_lsb 0 -#define xd_p_dagc1_done 0xA1A4 -#define dagc1_done_pos 4 -#define dagc1_done_len 1 -#define dagc1_done_lsb 0 -#define xd_p_ccid_rst 0xA1A5 -#define ccid_rst_pos 0 -#define ccid_rst_len 1 -#define ccid_rst_lsb 0 -#define xd_p_ccid_en 0xA1A5 -#define ccid_en_pos 1 -#define ccid_en_len 1 -#define ccid_en_lsb 0 -#define xd_p_ccid_mode 0xA1A5 -#define ccid_mode_pos 2 -#define ccid_mode_len 2 -#define ccid_mode_lsb 0 -#define xd_p_ccid_done 0xA1A5 -#define ccid_done_pos 4 -#define ccid_done_len 1 -#define ccid_done_lsb 0 -#define xd_r_ccid_deted 0xA1A5 -#define ccid_deted_pos 5 -#define ccid_deted_len 1 -#define ccid_deted_lsb 0 -#define xd_p_ccid2_en 0xA1A5 -#define ccid2_en_pos 6 -#define ccid2_en_len 1 -#define ccid2_en_lsb 0 -#define xd_p_ccid2_done 0xA1A5 -#define ccid2_done_pos 7 -#define ccid2_done_len 1 -#define ccid2_done_lsb 0 -#define xd_p_reg_bfs_en 0xA1A6 -#define reg_bfs_en_pos 0 -#define reg_bfs_en_len 1 -#define reg_bfs_en_lsb 0 -#define xd_p_reg_bfs_dis 0xA1A6 -#define reg_bfs_dis_pos 1 -#define reg_bfs_dis_len 1 -#define reg_bfs_dis_lsb 0 -#define xd_p_reg_bfs_rst 0xA1A6 -#define reg_bfs_rst_pos 2 -#define reg_bfs_rst_len 1 -#define reg_bfs_rst_lsb 0 -#define xd_p_reg_bfs_byp 0xA1A6 -#define reg_bfs_byp_pos 3 -#define reg_bfs_byp_len 1 -#define reg_bfs_byp_lsb 0 -#define xd_p_reg_antif_en 0xA1A7 -#define reg_antif_en_pos 0 -#define reg_antif_en_len 1 -#define reg_antif_en_lsb 0 -#define xd_p_reg_antif_dis 0xA1A7 -#define reg_antif_dis_pos 1 -#define reg_antif_dis_len 1 -#define reg_antif_dis_lsb 0 -#define xd_p_reg_antif_rst 0xA1A7 -#define reg_antif_rst_pos 2 -#define reg_antif_rst_len 1 -#define reg_antif_rst_lsb 0 -#define xd_p_reg_antif_byp 0xA1A7 -#define reg_antif_byp_pos 3 -#define reg_antif_byp_len 1 -#define reg_antif_byp_lsb 0 -#define xd_p_intp_en 0xA1A8 -#define intp_en_pos 0 -#define intp_en_len 1 -#define intp_en_lsb 0 -#define xd_p_intp_dis 0xA1A8 -#define intp_dis_pos 1 -#define intp_dis_len 1 -#define intp_dis_lsb 0 -#define xd_p_intp_rst 0xA1A8 -#define intp_rst_pos 2 -#define intp_rst_len 1 -#define intp_rst_lsb 0 -#define xd_p_intp_byp 0xA1A8 -#define intp_byp_pos 3 -#define intp_byp_len 1 -#define intp_byp_lsb 0 -#define xd_p_reg_acif_en 0xA1A9 -#define reg_acif_en_pos 0 -#define reg_acif_en_len 1 -#define reg_acif_en_lsb 0 -#define xd_p_reg_acif_dis 0xA1A9 -#define reg_acif_dis_pos 1 -#define reg_acif_dis_len 1 -#define reg_acif_dis_lsb 0 -#define xd_p_reg_acif_rst 0xA1A9 -#define reg_acif_rst_pos 2 -#define reg_acif_rst_len 1 -#define reg_acif_rst_lsb 0 -#define xd_p_reg_acif_byp 0xA1A9 -#define reg_acif_byp_pos 3 -#define reg_acif_byp_len 1 -#define reg_acif_byp_lsb 0 -#define xd_p_reg_acif_sync_mode 0xA1A9 -#define reg_acif_sync_mode_pos 4 -#define reg_acif_sync_mode_len 1 -#define reg_acif_sync_mode_lsb 0 -#define xd_p_dagc2_rst 0xA1AA -#define dagc2_rst_pos 0 -#define dagc2_rst_len 1 -#define dagc2_rst_lsb 0 -#define xd_p_dagc2_en 0xA1AA -#define dagc2_en_pos 1 -#define dagc2_en_len 1 -#define dagc2_en_lsb 0 -#define xd_p_dagc2_mode 0xA1AA -#define dagc2_mode_pos 2 -#define dagc2_mode_len 2 -#define dagc2_mode_lsb 0 -#define xd_p_dagc2_done 0xA1AA -#define dagc2_done_pos 4 -#define dagc2_done_len 1 -#define dagc2_done_lsb 0 -#define xd_p_reg_dca_en 0xA1AB -#define reg_dca_en_pos 0 -#define reg_dca_en_len 1 -#define reg_dca_en_lsb 0 -#define xd_p_dagc2_accumulate_num_2k_7_0 0xA1C0 -#define dagc2_accumulate_num_2k_7_0_pos 0 -#define dagc2_accumulate_num_2k_7_0_len 8 -#define dagc2_accumulate_num_2k_7_0_lsb 0 -#define xd_p_dagc2_accumulate_num_2k_12_8 0xA1C1 -#define dagc2_accumulate_num_2k_12_8_pos 0 -#define dagc2_accumulate_num_2k_12_8_len 5 -#define dagc2_accumulate_num_2k_12_8_lsb 8 -#define xd_p_dagc2_accumulate_num_8k_7_0 0xA1C2 -#define dagc2_accumulate_num_8k_7_0_pos 0 -#define dagc2_accumulate_num_8k_7_0_len 8 -#define dagc2_accumulate_num_8k_7_0_lsb 0 -#define xd_p_dagc2_accumulate_num_8k_12_8 0xA1C3 -#define dagc2_accumulate_num_8k_12_8_pos 0 -#define dagc2_accumulate_num_8k_12_8_len 5 -#define dagc2_accumulate_num_8k_12_8_lsb 8 -#define xd_p_dagc2_desired_level_2_0 0xA1C3 -#define dagc2_desired_level_2_0_pos 5 -#define dagc2_desired_level_2_0_len 3 -#define dagc2_desired_level_2_0_lsb 0 -#define xd_p_dagc2_desired_level_8_3 0xA1C4 -#define dagc2_desired_level_8_3_pos 0 -#define dagc2_desired_level_8_3_len 6 -#define dagc2_desired_level_8_3_lsb 3 -#define xd_p_dagc2_apply_delay 0xA1C5 -#define dagc2_apply_delay_pos 0 -#define dagc2_apply_delay_len 7 -#define dagc2_apply_delay_lsb 0 -#define xd_p_dagc2_bypass_scale_ctl 0xA1C6 -#define dagc2_bypass_scale_ctl_pos 0 -#define dagc2_bypass_scale_ctl_len 3 -#define dagc2_bypass_scale_ctl_lsb 0 -#define xd_p_dagc2_programmable_shift1 0xA1C7 -#define dagc2_programmable_shift1_pos 0 -#define dagc2_programmable_shift1_len 8 -#define dagc2_programmable_shift1_lsb 0 -#define xd_p_dagc2_programmable_shift2 0xA1C8 -#define dagc2_programmable_shift2_pos 0 -#define dagc2_programmable_shift2_len 8 -#define dagc2_programmable_shift2_lsb 0 -#define xd_p_reg_dagc2_in_sat_cnt_7_0 0xA1C9 -#define reg_dagc2_in_sat_cnt_7_0_pos 0 -#define reg_dagc2_in_sat_cnt_7_0_len 8 -#define reg_dagc2_in_sat_cnt_7_0_lsb 0 -#define xd_p_reg_dagc2_in_sat_cnt_15_8 0xA1CA -#define reg_dagc2_in_sat_cnt_15_8_pos 0 -#define reg_dagc2_in_sat_cnt_15_8_len 8 -#define reg_dagc2_in_sat_cnt_15_8_lsb 8 -#define xd_p_reg_dagc2_in_sat_cnt_23_16 0xA1CB -#define reg_dagc2_in_sat_cnt_23_16_pos 0 -#define reg_dagc2_in_sat_cnt_23_16_len 8 -#define reg_dagc2_in_sat_cnt_23_16_lsb 16 -#define xd_p_reg_dagc2_in_sat_cnt_31_24 0xA1CC -#define reg_dagc2_in_sat_cnt_31_24_pos 0 -#define reg_dagc2_in_sat_cnt_31_24_len 8 -#define reg_dagc2_in_sat_cnt_31_24_lsb 24 -#define xd_p_reg_dagc2_out_sat_cnt_7_0 0xA1CD -#define reg_dagc2_out_sat_cnt_7_0_pos 0 -#define reg_dagc2_out_sat_cnt_7_0_len 8 -#define reg_dagc2_out_sat_cnt_7_0_lsb 0 -#define xd_p_reg_dagc2_out_sat_cnt_15_8 0xA1CE -#define reg_dagc2_out_sat_cnt_15_8_pos 0 -#define reg_dagc2_out_sat_cnt_15_8_len 8 -#define reg_dagc2_out_sat_cnt_15_8_lsb 8 -#define xd_p_reg_dagc2_out_sat_cnt_23_16 0xA1CF -#define reg_dagc2_out_sat_cnt_23_16_pos 0 -#define reg_dagc2_out_sat_cnt_23_16_len 8 -#define reg_dagc2_out_sat_cnt_23_16_lsb 16 -#define xd_p_reg_dagc2_out_sat_cnt_31_24 0xA1D0 -#define reg_dagc2_out_sat_cnt_31_24_pos 0 -#define reg_dagc2_out_sat_cnt_31_24_len 8 -#define reg_dagc2_out_sat_cnt_31_24_lsb 24 -#define xd_r_dagc2_multiplier_7_0 0xA1D6 -#define dagc2_multiplier_7_0_pos 0 -#define dagc2_multiplier_7_0_len 8 -#define dagc2_multiplier_7_0_lsb 0 -#define xd_r_dagc2_multiplier_15_8 0xA1D7 -#define dagc2_multiplier_15_8_pos 0 -#define dagc2_multiplier_15_8_len 8 -#define dagc2_multiplier_15_8_lsb 8 -#define xd_r_dagc2_right_shift_bits 0xA1D8 -#define dagc2_right_shift_bits_pos 0 -#define dagc2_right_shift_bits_len 4 -#define dagc2_right_shift_bits_lsb 0 -#define xd_p_cfoe_NS_coeff1_7_0 0xA200 -#define cfoe_NS_coeff1_7_0_pos 0 -#define cfoe_NS_coeff1_7_0_len 8 -#define cfoe_NS_coeff1_7_0_lsb 0 -#define xd_p_cfoe_NS_coeff1_15_8 0xA201 -#define cfoe_NS_coeff1_15_8_pos 0 -#define cfoe_NS_coeff1_15_8_len 8 -#define cfoe_NS_coeff1_15_8_lsb 8 -#define xd_p_cfoe_NS_coeff1_23_16 0xA202 -#define cfoe_NS_coeff1_23_16_pos 0 -#define cfoe_NS_coeff1_23_16_len 8 -#define cfoe_NS_coeff1_23_16_lsb 16 -#define xd_p_cfoe_NS_coeff1_25_24 0xA203 -#define cfoe_NS_coeff1_25_24_pos 0 -#define cfoe_NS_coeff1_25_24_len 2 -#define cfoe_NS_coeff1_25_24_lsb 24 -#define xd_p_cfoe_NS_coeff2_5_0 0xA203 -#define cfoe_NS_coeff2_5_0_pos 2 -#define cfoe_NS_coeff2_5_0_len 6 -#define cfoe_NS_coeff2_5_0_lsb 0 -#define xd_p_cfoe_NS_coeff2_13_6 0xA204 -#define cfoe_NS_coeff2_13_6_pos 0 -#define cfoe_NS_coeff2_13_6_len 8 -#define cfoe_NS_coeff2_13_6_lsb 6 -#define xd_p_cfoe_NS_coeff2_21_14 0xA205 -#define cfoe_NS_coeff2_21_14_pos 0 -#define cfoe_NS_coeff2_21_14_len 8 -#define cfoe_NS_coeff2_21_14_lsb 14 -#define xd_p_cfoe_NS_coeff2_24_22 0xA206 -#define cfoe_NS_coeff2_24_22_pos 0 -#define cfoe_NS_coeff2_24_22_len 3 -#define cfoe_NS_coeff2_24_22_lsb 22 -#define xd_p_cfoe_lf_c1_4_0 0xA206 -#define cfoe_lf_c1_4_0_pos 3 -#define cfoe_lf_c1_4_0_len 5 -#define cfoe_lf_c1_4_0_lsb 0 -#define xd_p_cfoe_lf_c1_12_5 0xA207 -#define cfoe_lf_c1_12_5_pos 0 -#define cfoe_lf_c1_12_5_len 8 -#define cfoe_lf_c1_12_5_lsb 5 -#define xd_p_cfoe_lf_c1_20_13 0xA208 -#define cfoe_lf_c1_20_13_pos 0 -#define cfoe_lf_c1_20_13_len 8 -#define cfoe_lf_c1_20_13_lsb 13 -#define xd_p_cfoe_lf_c1_25_21 0xA209 -#define cfoe_lf_c1_25_21_pos 0 -#define cfoe_lf_c1_25_21_len 5 -#define cfoe_lf_c1_25_21_lsb 21 -#define xd_p_cfoe_lf_c2_2_0 0xA209 -#define cfoe_lf_c2_2_0_pos 5 -#define cfoe_lf_c2_2_0_len 3 -#define cfoe_lf_c2_2_0_lsb 0 -#define xd_p_cfoe_lf_c2_10_3 0xA20A -#define cfoe_lf_c2_10_3_pos 0 -#define cfoe_lf_c2_10_3_len 8 -#define cfoe_lf_c2_10_3_lsb 3 -#define xd_p_cfoe_lf_c2_18_11 0xA20B -#define cfoe_lf_c2_18_11_pos 0 -#define cfoe_lf_c2_18_11_len 8 -#define cfoe_lf_c2_18_11_lsb 11 -#define xd_p_cfoe_lf_c2_25_19 0xA20C -#define cfoe_lf_c2_25_19_pos 0 -#define cfoe_lf_c2_25_19_len 7 -#define cfoe_lf_c2_25_19_lsb 19 -#define xd_p_cfoe_ifod_7_0 0xA20D -#define cfoe_ifod_7_0_pos 0 -#define cfoe_ifod_7_0_len 8 -#define cfoe_ifod_7_0_lsb 0 -#define xd_p_cfoe_ifod_10_8 0xA20E -#define cfoe_ifod_10_8_pos 0 -#define cfoe_ifod_10_8_len 3 -#define cfoe_ifod_10_8_lsb 8 -#define xd_p_cfoe_Divg_ctr_th 0xA20E -#define cfoe_Divg_ctr_th_pos 4 -#define cfoe_Divg_ctr_th_len 4 -#define cfoe_Divg_ctr_th_lsb 0 -#define xd_p_cfoe_FOT_divg_th 0xA20F -#define cfoe_FOT_divg_th_pos 0 -#define cfoe_FOT_divg_th_len 8 -#define cfoe_FOT_divg_th_lsb 0 -#define xd_p_cfoe_FOT_cnvg_th 0xA210 -#define cfoe_FOT_cnvg_th_pos 0 -#define cfoe_FOT_cnvg_th_len 8 -#define cfoe_FOT_cnvg_th_lsb 0 -#define xd_p_reg_cfoe_offset_7_0 0xA211 -#define reg_cfoe_offset_7_0_pos 0 -#define reg_cfoe_offset_7_0_len 8 -#define reg_cfoe_offset_7_0_lsb 0 -#define xd_p_reg_cfoe_offset_9_8 0xA212 -#define reg_cfoe_offset_9_8_pos 0 -#define reg_cfoe_offset_9_8_len 2 -#define reg_cfoe_offset_9_8_lsb 8 -#define xd_p_reg_cfoe_ifoe_sign_corr 0xA212 -#define reg_cfoe_ifoe_sign_corr_pos 2 -#define reg_cfoe_ifoe_sign_corr_len 1 -#define reg_cfoe_ifoe_sign_corr_lsb 0 -#define xd_r_cfoe_fot_LF_output_7_0 0xA218 -#define cfoe_fot_LF_output_7_0_pos 0 -#define cfoe_fot_LF_output_7_0_len 8 -#define cfoe_fot_LF_output_7_0_lsb 0 -#define xd_r_cfoe_fot_LF_output_15_8 0xA219 -#define cfoe_fot_LF_output_15_8_pos 0 -#define cfoe_fot_LF_output_15_8_len 8 -#define cfoe_fot_LF_output_15_8_lsb 8 -#define xd_r_cfoe_ifo_metric_7_0 0xA21A -#define cfoe_ifo_metric_7_0_pos 0 -#define cfoe_ifo_metric_7_0_len 8 -#define cfoe_ifo_metric_7_0_lsb 0 -#define xd_r_cfoe_ifo_metric_15_8 0xA21B -#define cfoe_ifo_metric_15_8_pos 0 -#define cfoe_ifo_metric_15_8_len 8 -#define cfoe_ifo_metric_15_8_lsb 8 -#define xd_r_cfoe_ifo_metric_23_16 0xA21C -#define cfoe_ifo_metric_23_16_pos 0 -#define cfoe_ifo_metric_23_16_len 8 -#define cfoe_ifo_metric_23_16_lsb 16 -#define xd_p_ste_Nu 0xA220 -#define ste_Nu_pos 0 -#define ste_Nu_len 2 -#define ste_Nu_lsb 0 -#define xd_p_ste_GI 0xA220 -#define ste_GI_pos 2 -#define ste_GI_len 3 -#define ste_GI_lsb 0 -#define xd_p_ste_symbol_num 0xA221 -#define ste_symbol_num_pos 0 -#define ste_symbol_num_len 2 -#define ste_symbol_num_lsb 0 -#define xd_p_ste_sample_num 0xA221 -#define ste_sample_num_pos 2 -#define ste_sample_num_len 2 -#define ste_sample_num_lsb 0 -#define xd_p_reg_ste_buf_en 0xA221 -#define reg_ste_buf_en_pos 7 -#define reg_ste_buf_en_len 1 -#define reg_ste_buf_en_lsb 0 -#define xd_p_ste_FFT_offset_7_0 0xA222 -#define ste_FFT_offset_7_0_pos 0 -#define ste_FFT_offset_7_0_len 8 -#define ste_FFT_offset_7_0_lsb 0 -#define xd_p_ste_FFT_offset_11_8 0xA223 -#define ste_FFT_offset_11_8_pos 0 -#define ste_FFT_offset_11_8_len 4 -#define ste_FFT_offset_11_8_lsb 8 -#define xd_p_reg_ste_tstmod 0xA223 -#define reg_ste_tstmod_pos 5 -#define reg_ste_tstmod_len 1 -#define reg_ste_tstmod_lsb 0 -#define xd_p_ste_adv_start_7_0 0xA224 -#define ste_adv_start_7_0_pos 0 -#define ste_adv_start_7_0_len 8 -#define ste_adv_start_7_0_lsb 0 -#define xd_p_ste_adv_start_10_8 0xA225 -#define ste_adv_start_10_8_pos 0 -#define ste_adv_start_10_8_len 3 -#define ste_adv_start_10_8_lsb 8 -#define xd_p_ste_adv_stop 0xA226 -#define ste_adv_stop_pos 0 -#define ste_adv_stop_len 8 -#define ste_adv_stop_lsb 0 -#define xd_r_ste_P_value_7_0 0xA228 -#define ste_P_value_7_0_pos 0 -#define ste_P_value_7_0_len 8 -#define ste_P_value_7_0_lsb 0 -#define xd_r_ste_P_value_10_8 0xA229 -#define ste_P_value_10_8_pos 0 -#define ste_P_value_10_8_len 3 -#define ste_P_value_10_8_lsb 8 -#define xd_r_ste_M_value_7_0 0xA22A -#define ste_M_value_7_0_pos 0 -#define ste_M_value_7_0_len 8 -#define ste_M_value_7_0_lsb 0 -#define xd_r_ste_M_value_10_8 0xA22B -#define ste_M_value_10_8_pos 0 -#define ste_M_value_10_8_len 3 -#define ste_M_value_10_8_lsb 8 -#define xd_r_ste_H1 0xA22C -#define ste_H1_pos 0 -#define ste_H1_len 7 -#define ste_H1_lsb 0 -#define xd_r_ste_H2 0xA22D -#define ste_H2_pos 0 -#define ste_H2_len 7 -#define ste_H2_lsb 0 -#define xd_r_ste_H3 0xA22E -#define ste_H3_pos 0 -#define ste_H3_len 7 -#define ste_H3_lsb 0 -#define xd_r_ste_H4 0xA22F -#define ste_H4_pos 0 -#define ste_H4_len 7 -#define ste_H4_lsb 0 -#define xd_r_ste_Corr_value_I_7_0 0xA230 -#define ste_Corr_value_I_7_0_pos 0 -#define ste_Corr_value_I_7_0_len 8 -#define ste_Corr_value_I_7_0_lsb 0 -#define xd_r_ste_Corr_value_I_15_8 0xA231 -#define ste_Corr_value_I_15_8_pos 0 -#define ste_Corr_value_I_15_8_len 8 -#define ste_Corr_value_I_15_8_lsb 8 -#define xd_r_ste_Corr_value_I_23_16 0xA232 -#define ste_Corr_value_I_23_16_pos 0 -#define ste_Corr_value_I_23_16_len 8 -#define ste_Corr_value_I_23_16_lsb 16 -#define xd_r_ste_Corr_value_I_27_24 0xA233 -#define ste_Corr_value_I_27_24_pos 0 -#define ste_Corr_value_I_27_24_len 4 -#define ste_Corr_value_I_27_24_lsb 24 -#define xd_r_ste_Corr_value_Q_7_0 0xA234 -#define ste_Corr_value_Q_7_0_pos 0 -#define ste_Corr_value_Q_7_0_len 8 -#define ste_Corr_value_Q_7_0_lsb 0 -#define xd_r_ste_Corr_value_Q_15_8 0xA235 -#define ste_Corr_value_Q_15_8_pos 0 -#define ste_Corr_value_Q_15_8_len 8 -#define ste_Corr_value_Q_15_8_lsb 8 -#define xd_r_ste_Corr_value_Q_23_16 0xA236 -#define ste_Corr_value_Q_23_16_pos 0 -#define ste_Corr_value_Q_23_16_len 8 -#define ste_Corr_value_Q_23_16_lsb 16 -#define xd_r_ste_Corr_value_Q_27_24 0xA237 -#define ste_Corr_value_Q_27_24_pos 0 -#define ste_Corr_value_Q_27_24_len 4 -#define ste_Corr_value_Q_27_24_lsb 24 -#define xd_r_ste_J_num_7_0 0xA238 -#define ste_J_num_7_0_pos 0 -#define ste_J_num_7_0_len 8 -#define ste_J_num_7_0_lsb 0 -#define xd_r_ste_J_num_15_8 0xA239 -#define ste_J_num_15_8_pos 0 -#define ste_J_num_15_8_len 8 -#define ste_J_num_15_8_lsb 8 -#define xd_r_ste_J_num_23_16 0xA23A -#define ste_J_num_23_16_pos 0 -#define ste_J_num_23_16_len 8 -#define ste_J_num_23_16_lsb 16 -#define xd_r_ste_J_num_31_24 0xA23B -#define ste_J_num_31_24_pos 0 -#define ste_J_num_31_24_len 8 -#define ste_J_num_31_24_lsb 24 -#define xd_r_ste_J_den_7_0 0xA23C -#define ste_J_den_7_0_pos 0 -#define ste_J_den_7_0_len 8 -#define ste_J_den_7_0_lsb 0 -#define xd_r_ste_J_den_15_8 0xA23D -#define ste_J_den_15_8_pos 0 -#define ste_J_den_15_8_len 8 -#define ste_J_den_15_8_lsb 8 -#define xd_r_ste_J_den_18_16 0xA23E -#define ste_J_den_18_16_pos 0 -#define ste_J_den_18_16_len 3 -#define ste_J_den_18_16_lsb 16 -#define xd_r_ste_Beacon_Indicator 0xA23E -#define ste_Beacon_Indicator_pos 4 -#define ste_Beacon_Indicator_len 1 -#define ste_Beacon_Indicator_lsb 0 -#define xd_r_tpsd_Frame_Num 0xA250 -#define tpsd_Frame_Num_pos 0 -#define tpsd_Frame_Num_len 2 -#define tpsd_Frame_Num_lsb 0 -#define xd_r_tpsd_Constel 0xA250 -#define tpsd_Constel_pos 2 -#define tpsd_Constel_len 2 -#define tpsd_Constel_lsb 0 -#define xd_r_tpsd_GI 0xA250 -#define tpsd_GI_pos 4 -#define tpsd_GI_len 2 -#define tpsd_GI_lsb 0 -#define xd_r_tpsd_Mode 0xA250 -#define tpsd_Mode_pos 6 -#define tpsd_Mode_len 2 -#define tpsd_Mode_lsb 0 -#define xd_r_tpsd_CR_HP 0xA251 -#define tpsd_CR_HP_pos 0 -#define tpsd_CR_HP_len 3 -#define tpsd_CR_HP_lsb 0 -#define xd_r_tpsd_CR_LP 0xA251 -#define tpsd_CR_LP_pos 3 -#define tpsd_CR_LP_len 3 -#define tpsd_CR_LP_lsb 0 -#define xd_r_tpsd_Hie 0xA252 -#define tpsd_Hie_pos 0 -#define tpsd_Hie_len 3 -#define tpsd_Hie_lsb 0 -#define xd_r_tpsd_Res_Bits 0xA252 -#define tpsd_Res_Bits_pos 3 -#define tpsd_Res_Bits_len 5 -#define tpsd_Res_Bits_lsb 0 -#define xd_r_tpsd_Res_Bits_0 0xA253 -#define tpsd_Res_Bits_0_pos 0 -#define tpsd_Res_Bits_0_len 1 -#define tpsd_Res_Bits_0_lsb 0 -#define xd_r_tpsd_LengthInd 0xA253 -#define tpsd_LengthInd_pos 1 -#define tpsd_LengthInd_len 6 -#define tpsd_LengthInd_lsb 0 -#define xd_r_tpsd_Cell_Id_7_0 0xA254 -#define tpsd_Cell_Id_7_0_pos 0 -#define tpsd_Cell_Id_7_0_len 8 -#define tpsd_Cell_Id_7_0_lsb 0 -#define xd_r_tpsd_Cell_Id_15_8 0xA255 -#define tpsd_Cell_Id_15_8_pos 0 -#define tpsd_Cell_Id_15_8_len 8 -#define tpsd_Cell_Id_15_8_lsb 0 -#define xd_p_reg_fft_mask_tone0_7_0 0xA260 -#define reg_fft_mask_tone0_7_0_pos 0 -#define reg_fft_mask_tone0_7_0_len 8 -#define reg_fft_mask_tone0_7_0_lsb 0 -#define xd_p_reg_fft_mask_tone0_12_8 0xA261 -#define reg_fft_mask_tone0_12_8_pos 0 -#define reg_fft_mask_tone0_12_8_len 5 -#define reg_fft_mask_tone0_12_8_lsb 8 -#define xd_p_reg_fft_mask_tone1_7_0 0xA262 -#define reg_fft_mask_tone1_7_0_pos 0 -#define reg_fft_mask_tone1_7_0_len 8 -#define reg_fft_mask_tone1_7_0_lsb 0 -#define xd_p_reg_fft_mask_tone1_12_8 0xA263 -#define reg_fft_mask_tone1_12_8_pos 0 -#define reg_fft_mask_tone1_12_8_len 5 -#define reg_fft_mask_tone1_12_8_lsb 8 -#define xd_p_reg_fft_mask_tone2_7_0 0xA264 -#define reg_fft_mask_tone2_7_0_pos 0 -#define reg_fft_mask_tone2_7_0_len 8 -#define reg_fft_mask_tone2_7_0_lsb 0 -#define xd_p_reg_fft_mask_tone2_12_8 0xA265 -#define reg_fft_mask_tone2_12_8_pos 0 -#define reg_fft_mask_tone2_12_8_len 5 -#define reg_fft_mask_tone2_12_8_lsb 8 -#define xd_p_reg_fft_mask_tone3_7_0 0xA266 -#define reg_fft_mask_tone3_7_0_pos 0 -#define reg_fft_mask_tone3_7_0_len 8 -#define reg_fft_mask_tone3_7_0_lsb 0 -#define xd_p_reg_fft_mask_tone3_12_8 0xA267 -#define reg_fft_mask_tone3_12_8_pos 0 -#define reg_fft_mask_tone3_12_8_len 5 -#define reg_fft_mask_tone3_12_8_lsb 8 -#define xd_p_reg_fft_mask_from0_7_0 0xA268 -#define reg_fft_mask_from0_7_0_pos 0 -#define reg_fft_mask_from0_7_0_len 8 -#define reg_fft_mask_from0_7_0_lsb 0 -#define xd_p_reg_fft_mask_from0_12_8 0xA269 -#define reg_fft_mask_from0_12_8_pos 0 -#define reg_fft_mask_from0_12_8_len 5 -#define reg_fft_mask_from0_12_8_lsb 8 -#define xd_p_reg_fft_mask_to0_7_0 0xA26A -#define reg_fft_mask_to0_7_0_pos 0 -#define reg_fft_mask_to0_7_0_len 8 -#define reg_fft_mask_to0_7_0_lsb 0 -#define xd_p_reg_fft_mask_to0_12_8 0xA26B -#define reg_fft_mask_to0_12_8_pos 0 -#define reg_fft_mask_to0_12_8_len 5 -#define reg_fft_mask_to0_12_8_lsb 8 -#define xd_p_reg_fft_mask_from1_7_0 0xA26C -#define reg_fft_mask_from1_7_0_pos 0 -#define reg_fft_mask_from1_7_0_len 8 -#define reg_fft_mask_from1_7_0_lsb 0 -#define xd_p_reg_fft_mask_from1_12_8 0xA26D -#define reg_fft_mask_from1_12_8_pos 0 -#define reg_fft_mask_from1_12_8_len 5 -#define reg_fft_mask_from1_12_8_lsb 8 -#define xd_p_reg_fft_mask_to1_7_0 0xA26E -#define reg_fft_mask_to1_7_0_pos 0 -#define reg_fft_mask_to1_7_0_len 8 -#define reg_fft_mask_to1_7_0_lsb 0 -#define xd_p_reg_fft_mask_to1_12_8 0xA26F -#define reg_fft_mask_to1_12_8_pos 0 -#define reg_fft_mask_to1_12_8_len 5 -#define reg_fft_mask_to1_12_8_lsb 8 -#define xd_p_reg_cge_idx0_7_0 0xA280 -#define reg_cge_idx0_7_0_pos 0 -#define reg_cge_idx0_7_0_len 8 -#define reg_cge_idx0_7_0_lsb 0 -#define xd_p_reg_cge_idx0_12_8 0xA281 -#define reg_cge_idx0_12_8_pos 0 -#define reg_cge_idx0_12_8_len 5 -#define reg_cge_idx0_12_8_lsb 8 -#define xd_p_reg_cge_idx1_7_0 0xA282 -#define reg_cge_idx1_7_0_pos 0 -#define reg_cge_idx1_7_0_len 8 -#define reg_cge_idx1_7_0_lsb 0 -#define xd_p_reg_cge_idx1_12_8 0xA283 -#define reg_cge_idx1_12_8_pos 0 -#define reg_cge_idx1_12_8_len 5 -#define reg_cge_idx1_12_8_lsb 8 -#define xd_p_reg_cge_idx2_7_0 0xA284 -#define reg_cge_idx2_7_0_pos 0 -#define reg_cge_idx2_7_0_len 8 -#define reg_cge_idx2_7_0_lsb 0 -#define xd_p_reg_cge_idx2_12_8 0xA285 -#define reg_cge_idx2_12_8_pos 0 -#define reg_cge_idx2_12_8_len 5 -#define reg_cge_idx2_12_8_lsb 8 -#define xd_p_reg_cge_idx3_7_0 0xA286 -#define reg_cge_idx3_7_0_pos 0 -#define reg_cge_idx3_7_0_len 8 -#define reg_cge_idx3_7_0_lsb 0 -#define xd_p_reg_cge_idx3_12_8 0xA287 -#define reg_cge_idx3_12_8_pos 0 -#define reg_cge_idx3_12_8_len 5 -#define reg_cge_idx3_12_8_lsb 8 -#define xd_p_reg_cge_idx4_7_0 0xA288 -#define reg_cge_idx4_7_0_pos 0 -#define reg_cge_idx4_7_0_len 8 -#define reg_cge_idx4_7_0_lsb 0 -#define xd_p_reg_cge_idx4_12_8 0xA289 -#define reg_cge_idx4_12_8_pos 0 -#define reg_cge_idx4_12_8_len 5 -#define reg_cge_idx4_12_8_lsb 8 -#define xd_p_reg_cge_idx5_7_0 0xA28A -#define reg_cge_idx5_7_0_pos 0 -#define reg_cge_idx5_7_0_len 8 -#define reg_cge_idx5_7_0_lsb 0 -#define xd_p_reg_cge_idx5_12_8 0xA28B -#define reg_cge_idx5_12_8_pos 0 -#define reg_cge_idx5_12_8_len 5 -#define reg_cge_idx5_12_8_lsb 8 -#define xd_p_reg_cge_idx6_7_0 0xA28C -#define reg_cge_idx6_7_0_pos 0 -#define reg_cge_idx6_7_0_len 8 -#define reg_cge_idx6_7_0_lsb 0 -#define xd_p_reg_cge_idx6_12_8 0xA28D -#define reg_cge_idx6_12_8_pos 0 -#define reg_cge_idx6_12_8_len 5 -#define reg_cge_idx6_12_8_lsb 8 -#define xd_p_reg_cge_idx7_7_0 0xA28E -#define reg_cge_idx7_7_0_pos 0 -#define reg_cge_idx7_7_0_len 8 -#define reg_cge_idx7_7_0_lsb 0 -#define xd_p_reg_cge_idx7_12_8 0xA28F -#define reg_cge_idx7_12_8_pos 0 -#define reg_cge_idx7_12_8_len 5 -#define reg_cge_idx7_12_8_lsb 8 -#define xd_p_reg_cge_idx8_7_0 0xA290 -#define reg_cge_idx8_7_0_pos 0 -#define reg_cge_idx8_7_0_len 8 -#define reg_cge_idx8_7_0_lsb 0 -#define xd_p_reg_cge_idx8_12_8 0xA291 -#define reg_cge_idx8_12_8_pos 0 -#define reg_cge_idx8_12_8_len 5 -#define reg_cge_idx8_12_8_lsb 8 -#define xd_p_reg_cge_idx9_7_0 0xA292 -#define reg_cge_idx9_7_0_pos 0 -#define reg_cge_idx9_7_0_len 8 -#define reg_cge_idx9_7_0_lsb 0 -#define xd_p_reg_cge_idx9_12_8 0xA293 -#define reg_cge_idx9_12_8_pos 0 -#define reg_cge_idx9_12_8_len 5 -#define reg_cge_idx9_12_8_lsb 8 -#define xd_p_reg_cge_idx10_7_0 0xA294 -#define reg_cge_idx10_7_0_pos 0 -#define reg_cge_idx10_7_0_len 8 -#define reg_cge_idx10_7_0_lsb 0 -#define xd_p_reg_cge_idx10_12_8 0xA295 -#define reg_cge_idx10_12_8_pos 0 -#define reg_cge_idx10_12_8_len 5 -#define reg_cge_idx10_12_8_lsb 8 -#define xd_p_reg_cge_idx11_7_0 0xA296 -#define reg_cge_idx11_7_0_pos 0 -#define reg_cge_idx11_7_0_len 8 -#define reg_cge_idx11_7_0_lsb 0 -#define xd_p_reg_cge_idx11_12_8 0xA297 -#define reg_cge_idx11_12_8_pos 0 -#define reg_cge_idx11_12_8_len 5 -#define reg_cge_idx11_12_8_lsb 8 -#define xd_p_reg_cge_idx12_7_0 0xA298 -#define reg_cge_idx12_7_0_pos 0 -#define reg_cge_idx12_7_0_len 8 -#define reg_cge_idx12_7_0_lsb 0 -#define xd_p_reg_cge_idx12_12_8 0xA299 -#define reg_cge_idx12_12_8_pos 0 -#define reg_cge_idx12_12_8_len 5 -#define reg_cge_idx12_12_8_lsb 8 -#define xd_p_reg_cge_idx13_7_0 0xA29A -#define reg_cge_idx13_7_0_pos 0 -#define reg_cge_idx13_7_0_len 8 -#define reg_cge_idx13_7_0_lsb 0 -#define xd_p_reg_cge_idx13_12_8 0xA29B -#define reg_cge_idx13_12_8_pos 0 -#define reg_cge_idx13_12_8_len 5 -#define reg_cge_idx13_12_8_lsb 8 -#define xd_p_reg_cge_idx14_7_0 0xA29C -#define reg_cge_idx14_7_0_pos 0 -#define reg_cge_idx14_7_0_len 8 -#define reg_cge_idx14_7_0_lsb 0 -#define xd_p_reg_cge_idx14_12_8 0xA29D -#define reg_cge_idx14_12_8_pos 0 -#define reg_cge_idx14_12_8_len 5 -#define reg_cge_idx14_12_8_lsb 8 -#define xd_p_reg_cge_idx15_7_0 0xA29E -#define reg_cge_idx15_7_0_pos 0 -#define reg_cge_idx15_7_0_len 8 -#define reg_cge_idx15_7_0_lsb 0 -#define xd_p_reg_cge_idx15_12_8 0xA29F -#define reg_cge_idx15_12_8_pos 0 -#define reg_cge_idx15_12_8_len 5 -#define reg_cge_idx15_12_8_lsb 8 -#define xd_r_reg_fft_crc 0xA2A8 -#define reg_fft_crc_pos 0 -#define reg_fft_crc_len 8 -#define reg_fft_crc_lsb 0 -#define xd_p_fd_fft_shift_max 0xA2A9 -#define fd_fft_shift_max_pos 0 -#define fd_fft_shift_max_len 4 -#define fd_fft_shift_max_lsb 0 -#define xd_r_fd_fft_shift 0xA2A9 -#define fd_fft_shift_pos 4 -#define fd_fft_shift_len 4 -#define fd_fft_shift_lsb 0 -#define xd_r_fd_fft_frame_num 0xA2AA -#define fd_fft_frame_num_pos 0 -#define fd_fft_frame_num_len 2 -#define fd_fft_frame_num_lsb 0 -#define xd_r_fd_fft_symbol_count 0xA2AB -#define fd_fft_symbol_count_pos 0 -#define fd_fft_symbol_count_len 7 -#define fd_fft_symbol_count_lsb 0 -#define xd_r_reg_fft_idx_max_7_0 0xA2AC -#define reg_fft_idx_max_7_0_pos 0 -#define reg_fft_idx_max_7_0_len 8 -#define reg_fft_idx_max_7_0_lsb 0 -#define xd_r_reg_fft_idx_max_12_8 0xA2AD -#define reg_fft_idx_max_12_8_pos 0 -#define reg_fft_idx_max_12_8_len 5 -#define reg_fft_idx_max_12_8_lsb 8 -#define xd_p_reg_cge_program 0xA2AE -#define reg_cge_program_pos 0 -#define reg_cge_program_len 1 -#define reg_cge_program_lsb 0 -#define xd_p_reg_cge_fixed 0xA2AE -#define reg_cge_fixed_pos 1 -#define reg_cge_fixed_len 1 -#define reg_cge_fixed_lsb 0 -#define xd_p_reg_fft_rotate_en 0xA2AE -#define reg_fft_rotate_en_pos 2 -#define reg_fft_rotate_en_len 1 -#define reg_fft_rotate_en_lsb 0 -#define xd_p_reg_fft_rotate_base_4_0 0xA2AE -#define reg_fft_rotate_base_4_0_pos 3 -#define reg_fft_rotate_base_4_0_len 5 -#define reg_fft_rotate_base_4_0_lsb 0 -#define xd_p_reg_fft_rotate_base_12_5 0xA2AF -#define reg_fft_rotate_base_12_5_pos 0 -#define reg_fft_rotate_base_12_5_len 8 -#define reg_fft_rotate_base_12_5_lsb 5 -#define xd_p_reg_gp_trigger_fd 0xA2B8 -#define reg_gp_trigger_fd_pos 0 -#define reg_gp_trigger_fd_len 1 -#define reg_gp_trigger_fd_lsb 0 -#define xd_p_reg_trigger_sel_fd 0xA2B8 -#define reg_trigger_sel_fd_pos 1 -#define reg_trigger_sel_fd_len 2 -#define reg_trigger_sel_fd_lsb 0 -#define xd_p_reg_trigger_module_sel_fd 0xA2B9 -#define reg_trigger_module_sel_fd_pos 0 -#define reg_trigger_module_sel_fd_len 6 -#define reg_trigger_module_sel_fd_lsb 0 -#define xd_p_reg_trigger_set_sel_fd 0xA2BA -#define reg_trigger_set_sel_fd_pos 0 -#define reg_trigger_set_sel_fd_len 6 -#define reg_trigger_set_sel_fd_lsb 0 -#define xd_p_reg_fd_noname_7_0 0xA2BC -#define reg_fd_noname_7_0_pos 0 -#define reg_fd_noname_7_0_len 8 -#define reg_fd_noname_7_0_lsb 0 -#define xd_p_reg_fd_noname_15_8 0xA2BD -#define reg_fd_noname_15_8_pos 0 -#define reg_fd_noname_15_8_len 8 -#define reg_fd_noname_15_8_lsb 8 -#define xd_p_reg_fd_noname_23_16 0xA2BE -#define reg_fd_noname_23_16_pos 0 -#define reg_fd_noname_23_16_len 8 -#define reg_fd_noname_23_16_lsb 16 -#define xd_p_reg_fd_noname_31_24 0xA2BF -#define reg_fd_noname_31_24_pos 0 -#define reg_fd_noname_31_24_len 8 -#define reg_fd_noname_31_24_lsb 24 -#define xd_r_fd_fpcc_cp_corr_signn 0xA2C0 -#define fd_fpcc_cp_corr_signn_pos 0 -#define fd_fpcc_cp_corr_signn_len 8 -#define fd_fpcc_cp_corr_signn_lsb 0 -#define xd_p_reg_feq_s1 0xA2C1 -#define reg_feq_s1_pos 0 -#define reg_feq_s1_len 5 -#define reg_feq_s1_lsb 0 -#define xd_p_fd_fpcc_cp_corr_tone_th 0xA2C2 -#define fd_fpcc_cp_corr_tone_th_pos 0 -#define fd_fpcc_cp_corr_tone_th_len 6 -#define fd_fpcc_cp_corr_tone_th_lsb 0 -#define xd_p_fd_fpcc_cp_corr_symbol_log_th 0xA2C3 -#define fd_fpcc_cp_corr_symbol_log_th_pos 0 -#define fd_fpcc_cp_corr_symbol_log_th_len 4 -#define fd_fpcc_cp_corr_symbol_log_th_lsb 0 -#define xd_p_fd_fpcc_cp_corr_int 0xA2C4 -#define fd_fpcc_cp_corr_int_pos 0 -#define fd_fpcc_cp_corr_int_len 1 -#define fd_fpcc_cp_corr_int_lsb 0 -#define xd_p_reg_sfoe_ns_7_0 0xA320 -#define reg_sfoe_ns_7_0_pos 0 -#define reg_sfoe_ns_7_0_len 8 -#define reg_sfoe_ns_7_0_lsb 0 -#define xd_p_reg_sfoe_ns_14_8 0xA321 -#define reg_sfoe_ns_14_8_pos 0 -#define reg_sfoe_ns_14_8_len 7 -#define reg_sfoe_ns_14_8_lsb 8 -#define xd_p_reg_sfoe_c1_7_0 0xA322 -#define reg_sfoe_c1_7_0_pos 0 -#define reg_sfoe_c1_7_0_len 8 -#define reg_sfoe_c1_7_0_lsb 0 -#define xd_p_reg_sfoe_c1_15_8 0xA323 -#define reg_sfoe_c1_15_8_pos 0 -#define reg_sfoe_c1_15_8_len 8 -#define reg_sfoe_c1_15_8_lsb 8 -#define xd_p_reg_sfoe_c1_17_16 0xA324 -#define reg_sfoe_c1_17_16_pos 0 -#define reg_sfoe_c1_17_16_len 2 -#define reg_sfoe_c1_17_16_lsb 16 -#define xd_p_reg_sfoe_c2_7_0 0xA325 -#define reg_sfoe_c2_7_0_pos 0 -#define reg_sfoe_c2_7_0_len 8 -#define reg_sfoe_c2_7_0_lsb 0 -#define xd_p_reg_sfoe_c2_15_8 0xA326 -#define reg_sfoe_c2_15_8_pos 0 -#define reg_sfoe_c2_15_8_len 8 -#define reg_sfoe_c2_15_8_lsb 8 -#define xd_p_reg_sfoe_c2_17_16 0xA327 -#define reg_sfoe_c2_17_16_pos 0 -#define reg_sfoe_c2_17_16_len 2 -#define reg_sfoe_c2_17_16_lsb 16 -#define xd_r_reg_sfoe_out_9_2 0xA328 -#define reg_sfoe_out_9_2_pos 0 -#define reg_sfoe_out_9_2_len 8 -#define reg_sfoe_out_9_2_lsb 0 -#define xd_r_reg_sfoe_out_1_0 0xA329 -#define reg_sfoe_out_1_0_pos 0 -#define reg_sfoe_out_1_0_len 2 -#define reg_sfoe_out_1_0_lsb 0 -#define xd_p_reg_sfoe_lm_counter_th 0xA32A -#define reg_sfoe_lm_counter_th_pos 0 -#define reg_sfoe_lm_counter_th_len 4 -#define reg_sfoe_lm_counter_th_lsb 0 -#define xd_p_reg_sfoe_convg_th 0xA32B -#define reg_sfoe_convg_th_pos 0 -#define reg_sfoe_convg_th_len 8 -#define reg_sfoe_convg_th_lsb 0 -#define xd_p_reg_sfoe_divg_th 0xA32C -#define reg_sfoe_divg_th_pos 0 -#define reg_sfoe_divg_th_len 8 -#define reg_sfoe_divg_th_lsb 0 -#define xd_p_fd_tpsd_en 0xA330 -#define fd_tpsd_en_pos 0 -#define fd_tpsd_en_len 1 -#define fd_tpsd_en_lsb 0 -#define xd_p_fd_tpsd_dis 0xA330 -#define fd_tpsd_dis_pos 1 -#define fd_tpsd_dis_len 1 -#define fd_tpsd_dis_lsb 0 -#define xd_p_fd_tpsd_rst 0xA330 -#define fd_tpsd_rst_pos 2 -#define fd_tpsd_rst_len 1 -#define fd_tpsd_rst_lsb 0 -#define xd_p_fd_tpsd_lock 0xA330 -#define fd_tpsd_lock_pos 3 -#define fd_tpsd_lock_len 1 -#define fd_tpsd_lock_lsb 0 -#define xd_r_fd_tpsd_s19 0xA330 -#define fd_tpsd_s19_pos 4 -#define fd_tpsd_s19_len 1 -#define fd_tpsd_s19_lsb 0 -#define xd_r_fd_tpsd_s17 0xA330 -#define fd_tpsd_s17_pos 5 -#define fd_tpsd_s17_len 1 -#define fd_tpsd_s17_lsb 0 -#define xd_p_fd_sfr_ste_en 0xA331 -#define fd_sfr_ste_en_pos 0 -#define fd_sfr_ste_en_len 1 -#define fd_sfr_ste_en_lsb 0 -#define xd_p_fd_sfr_ste_dis 0xA331 -#define fd_sfr_ste_dis_pos 1 -#define fd_sfr_ste_dis_len 1 -#define fd_sfr_ste_dis_lsb 0 -#define xd_p_fd_sfr_ste_rst 0xA331 -#define fd_sfr_ste_rst_pos 2 -#define fd_sfr_ste_rst_len 1 -#define fd_sfr_ste_rst_lsb 0 -#define xd_p_fd_sfr_ste_mode 0xA331 -#define fd_sfr_ste_mode_pos 3 -#define fd_sfr_ste_mode_len 1 -#define fd_sfr_ste_mode_lsb 0 -#define xd_p_fd_sfr_ste_done 0xA331 -#define fd_sfr_ste_done_pos 4 -#define fd_sfr_ste_done_len 1 -#define fd_sfr_ste_done_lsb 0 -#define xd_p_reg_cfoe_ffoe_en 0xA332 -#define reg_cfoe_ffoe_en_pos 0 -#define reg_cfoe_ffoe_en_len 1 -#define reg_cfoe_ffoe_en_lsb 0 -#define xd_p_reg_cfoe_ffoe_dis 0xA332 -#define reg_cfoe_ffoe_dis_pos 1 -#define reg_cfoe_ffoe_dis_len 1 -#define reg_cfoe_ffoe_dis_lsb 0 -#define xd_p_reg_cfoe_ffoe_rst 0xA332 -#define reg_cfoe_ffoe_rst_pos 2 -#define reg_cfoe_ffoe_rst_len 1 -#define reg_cfoe_ffoe_rst_lsb 0 -#define xd_p_reg_cfoe_ifoe_en 0xA332 -#define reg_cfoe_ifoe_en_pos 3 -#define reg_cfoe_ifoe_en_len 1 -#define reg_cfoe_ifoe_en_lsb 0 -#define xd_p_reg_cfoe_ifoe_dis 0xA332 -#define reg_cfoe_ifoe_dis_pos 4 -#define reg_cfoe_ifoe_dis_len 1 -#define reg_cfoe_ifoe_dis_lsb 0 -#define xd_p_reg_cfoe_ifoe_rst 0xA332 -#define reg_cfoe_ifoe_rst_pos 5 -#define reg_cfoe_ifoe_rst_len 1 -#define reg_cfoe_ifoe_rst_lsb 0 -#define xd_p_reg_cfoe_fot_en 0xA332 -#define reg_cfoe_fot_en_pos 6 -#define reg_cfoe_fot_en_len 1 -#define reg_cfoe_fot_en_lsb 0 -#define xd_p_reg_cfoe_fot_lm_en 0xA332 -#define reg_cfoe_fot_lm_en_pos 7 -#define reg_cfoe_fot_lm_en_len 1 -#define reg_cfoe_fot_lm_en_lsb 0 -#define xd_p_reg_cfoe_fot_rst 0xA333 -#define reg_cfoe_fot_rst_pos 0 -#define reg_cfoe_fot_rst_len 1 -#define reg_cfoe_fot_rst_lsb 0 -#define xd_r_fd_cfoe_ffoe_done 0xA333 -#define fd_cfoe_ffoe_done_pos 1 -#define fd_cfoe_ffoe_done_len 1 -#define fd_cfoe_ffoe_done_lsb 0 -#define xd_p_fd_cfoe_metric_vld 0xA333 -#define fd_cfoe_metric_vld_pos 2 -#define fd_cfoe_metric_vld_len 1 -#define fd_cfoe_metric_vld_lsb 0 -#define xd_p_reg_cfoe_ifod_vld 0xA333 -#define reg_cfoe_ifod_vld_pos 3 -#define reg_cfoe_ifod_vld_len 1 -#define reg_cfoe_ifod_vld_lsb 0 -#define xd_r_fd_cfoe_ifoe_done 0xA333 -#define fd_cfoe_ifoe_done_pos 4 -#define fd_cfoe_ifoe_done_len 1 -#define fd_cfoe_ifoe_done_lsb 0 -#define xd_r_fd_cfoe_fot_valid 0xA333 -#define fd_cfoe_fot_valid_pos 5 -#define fd_cfoe_fot_valid_len 1 -#define fd_cfoe_fot_valid_lsb 0 -#define xd_p_reg_cfoe_divg_int 0xA333 -#define reg_cfoe_divg_int_pos 6 -#define reg_cfoe_divg_int_len 1 -#define reg_cfoe_divg_int_lsb 0 -#define xd_r_reg_cfoe_divg_flag 0xA333 -#define reg_cfoe_divg_flag_pos 7 -#define reg_cfoe_divg_flag_len 1 -#define reg_cfoe_divg_flag_lsb 0 -#define xd_p_reg_sfoe_en 0xA334 -#define reg_sfoe_en_pos 0 -#define reg_sfoe_en_len 1 -#define reg_sfoe_en_lsb 0 -#define xd_p_reg_sfoe_dis 0xA334 -#define reg_sfoe_dis_pos 1 -#define reg_sfoe_dis_len 1 -#define reg_sfoe_dis_lsb 0 -#define xd_p_reg_sfoe_rst 0xA334 -#define reg_sfoe_rst_pos 2 -#define reg_sfoe_rst_len 1 -#define reg_sfoe_rst_lsb 0 -#define xd_p_reg_sfoe_vld_int 0xA334 -#define reg_sfoe_vld_int_pos 3 -#define reg_sfoe_vld_int_len 1 -#define reg_sfoe_vld_int_lsb 0 -#define xd_p_reg_sfoe_lm_en 0xA334 -#define reg_sfoe_lm_en_pos 4 -#define reg_sfoe_lm_en_len 1 -#define reg_sfoe_lm_en_lsb 0 -#define xd_p_reg_sfoe_divg_int 0xA334 -#define reg_sfoe_divg_int_pos 5 -#define reg_sfoe_divg_int_len 1 -#define reg_sfoe_divg_int_lsb 0 -#define xd_r_reg_sfoe_divg_flag 0xA334 -#define reg_sfoe_divg_flag_pos 6 -#define reg_sfoe_divg_flag_len 1 -#define reg_sfoe_divg_flag_lsb 0 -#define xd_p_reg_fft_rst 0xA335 -#define reg_fft_rst_pos 0 -#define reg_fft_rst_len 1 -#define reg_fft_rst_lsb 0 -#define xd_p_reg_fft_fast_beacon 0xA335 -#define reg_fft_fast_beacon_pos 1 -#define reg_fft_fast_beacon_len 1 -#define reg_fft_fast_beacon_lsb 0 -#define xd_p_reg_fft_fast_valid 0xA335 -#define reg_fft_fast_valid_pos 2 -#define reg_fft_fast_valid_len 1 -#define reg_fft_fast_valid_lsb 0 -#define xd_p_reg_fft_mask_en 0xA335 -#define reg_fft_mask_en_pos 3 -#define reg_fft_mask_en_len 1 -#define reg_fft_mask_en_lsb 0 -#define xd_p_reg_fft_crc_en 0xA335 -#define reg_fft_crc_en_pos 4 -#define reg_fft_crc_en_len 1 -#define reg_fft_crc_en_lsb 0 -#define xd_p_reg_finr_en 0xA336 -#define reg_finr_en_pos 0 -#define reg_finr_en_len 1 -#define reg_finr_en_lsb 0 -#define xd_p_fd_fste_en 0xA337 -#define fd_fste_en_pos 1 -#define fd_fste_en_len 1 -#define fd_fste_en_lsb 0 -#define xd_p_fd_sqi_tps_level_shift 0xA338 -#define fd_sqi_tps_level_shift_pos 0 -#define fd_sqi_tps_level_shift_len 8 -#define fd_sqi_tps_level_shift_lsb 0 -#define xd_p_fd_pilot_ma_len 0xA339 -#define fd_pilot_ma_len_pos 0 -#define fd_pilot_ma_len_len 6 -#define fd_pilot_ma_len_lsb 0 -#define xd_p_fd_tps_ma_len 0xA33A -#define fd_tps_ma_len_pos 0 -#define fd_tps_ma_len_len 6 -#define fd_tps_ma_len_lsb 0 -#define xd_p_fd_sqi_s3 0xA33B -#define fd_sqi_s3_pos 0 -#define fd_sqi_s3_len 8 -#define fd_sqi_s3_lsb 0 -#define xd_p_fd_sqi_dummy_reg_0 0xA33C -#define fd_sqi_dummy_reg_0_pos 0 -#define fd_sqi_dummy_reg_0_len 1 -#define fd_sqi_dummy_reg_0_lsb 0 -#define xd_p_fd_sqi_debug_sel 0xA33C -#define fd_sqi_debug_sel_pos 1 -#define fd_sqi_debug_sel_len 2 -#define fd_sqi_debug_sel_lsb 0 -#define xd_p_fd_sqi_s2 0xA33C -#define fd_sqi_s2_pos 3 -#define fd_sqi_s2_len 5 -#define fd_sqi_s2_lsb 0 -#define xd_p_fd_sqi_dummy_reg_1 0xA33D -#define fd_sqi_dummy_reg_1_pos 0 -#define fd_sqi_dummy_reg_1_len 1 -#define fd_sqi_dummy_reg_1_lsb 0 -#define xd_p_fd_inr_ignore 0xA33D -#define fd_inr_ignore_pos 1 -#define fd_inr_ignore_len 1 -#define fd_inr_ignore_lsb 0 -#define xd_p_fd_pilot_ignore 0xA33D -#define fd_pilot_ignore_pos 2 -#define fd_pilot_ignore_len 1 -#define fd_pilot_ignore_lsb 0 -#define xd_p_fd_etps_ignore 0xA33D -#define fd_etps_ignore_pos 3 -#define fd_etps_ignore_len 1 -#define fd_etps_ignore_lsb 0 -#define xd_p_fd_sqi_s1 0xA33D -#define fd_sqi_s1_pos 4 -#define fd_sqi_s1_len 4 -#define fd_sqi_s1_lsb 0 -#define xd_p_reg_fste_ehw_7_0 0xA33E -#define reg_fste_ehw_7_0_pos 0 -#define reg_fste_ehw_7_0_len 8 -#define reg_fste_ehw_7_0_lsb 0 -#define xd_p_reg_fste_ehw_9_8 0xA33F -#define reg_fste_ehw_9_8_pos 0 -#define reg_fste_ehw_9_8_len 2 -#define reg_fste_ehw_9_8_lsb 8 -#define xd_p_reg_fste_i_adj_vld 0xA33F -#define reg_fste_i_adj_vld_pos 2 -#define reg_fste_i_adj_vld_len 1 -#define reg_fste_i_adj_vld_lsb 0 -#define xd_p_reg_fste_phase_ini_7_0 0xA340 -#define reg_fste_phase_ini_7_0_pos 0 -#define reg_fste_phase_ini_7_0_len 8 -#define reg_fste_phase_ini_7_0_lsb 0 -#define xd_p_reg_fste_phase_ini_11_8 0xA341 -#define reg_fste_phase_ini_11_8_pos 0 -#define reg_fste_phase_ini_11_8_len 4 -#define reg_fste_phase_ini_11_8_lsb 8 -#define xd_p_reg_fste_phase_inc_3_0 0xA341 -#define reg_fste_phase_inc_3_0_pos 4 -#define reg_fste_phase_inc_3_0_len 4 -#define reg_fste_phase_inc_3_0_lsb 0 -#define xd_p_reg_fste_phase_inc_11_4 0xA342 -#define reg_fste_phase_inc_11_4_pos 0 -#define reg_fste_phase_inc_11_4_len 8 -#define reg_fste_phase_inc_11_4_lsb 4 -#define xd_p_reg_fste_acum_cost_cnt_max 0xA343 -#define reg_fste_acum_cost_cnt_max_pos 0 -#define reg_fste_acum_cost_cnt_max_len 4 -#define reg_fste_acum_cost_cnt_max_lsb 0 -#define xd_p_reg_fste_step_size_std 0xA343 -#define reg_fste_step_size_std_pos 4 -#define reg_fste_step_size_std_len 4 -#define reg_fste_step_size_std_lsb 0 -#define xd_p_reg_fste_step_size_max 0xA344 -#define reg_fste_step_size_max_pos 0 -#define reg_fste_step_size_max_len 4 -#define reg_fste_step_size_max_lsb 0 -#define xd_p_reg_fste_step_size_min 0xA344 -#define reg_fste_step_size_min_pos 4 -#define reg_fste_step_size_min_len 4 -#define reg_fste_step_size_min_lsb 0 -#define xd_p_reg_fste_frac_step_size_7_0 0xA345 -#define reg_fste_frac_step_size_7_0_pos 0 -#define reg_fste_frac_step_size_7_0_len 8 -#define reg_fste_frac_step_size_7_0_lsb 0 -#define xd_p_reg_fste_frac_step_size_15_8 0xA346 -#define reg_fste_frac_step_size_15_8_pos 0 -#define reg_fste_frac_step_size_15_8_len 8 -#define reg_fste_frac_step_size_15_8_lsb 8 -#define xd_p_reg_fste_frac_step_size_19_16 0xA347 -#define reg_fste_frac_step_size_19_16_pos 0 -#define reg_fste_frac_step_size_19_16_len 4 -#define reg_fste_frac_step_size_19_16_lsb 16 -#define xd_p_reg_fste_rpd_dir_cnt_max 0xA347 -#define reg_fste_rpd_dir_cnt_max_pos 4 -#define reg_fste_rpd_dir_cnt_max_len 4 -#define reg_fste_rpd_dir_cnt_max_lsb 0 -#define xd_p_reg_fste_ehs 0xA348 -#define reg_fste_ehs_pos 0 -#define reg_fste_ehs_len 4 -#define reg_fste_ehs_lsb 0 -#define xd_p_reg_fste_frac_cost_cnt_max_3_0 0xA348 -#define reg_fste_frac_cost_cnt_max_3_0_pos 4 -#define reg_fste_frac_cost_cnt_max_3_0_len 4 -#define reg_fste_frac_cost_cnt_max_3_0_lsb 0 -#define xd_p_reg_fste_frac_cost_cnt_max_9_4 0xA349 -#define reg_fste_frac_cost_cnt_max_9_4_pos 0 -#define reg_fste_frac_cost_cnt_max_9_4_len 6 -#define reg_fste_frac_cost_cnt_max_9_4_lsb 4 -#define xd_p_reg_fste_w0_7_0 0xA34A -#define reg_fste_w0_7_0_pos 0 -#define reg_fste_w0_7_0_len 8 -#define reg_fste_w0_7_0_lsb 0 -#define xd_p_reg_fste_w0_11_8 0xA34B -#define reg_fste_w0_11_8_pos 0 -#define reg_fste_w0_11_8_len 4 -#define reg_fste_w0_11_8_lsb 8 -#define xd_p_reg_fste_w1_3_0 0xA34B -#define reg_fste_w1_3_0_pos 4 -#define reg_fste_w1_3_0_len 4 -#define reg_fste_w1_3_0_lsb 0 -#define xd_p_reg_fste_w1_11_4 0xA34C -#define reg_fste_w1_11_4_pos 0 -#define reg_fste_w1_11_4_len 8 -#define reg_fste_w1_11_4_lsb 4 -#define xd_p_reg_fste_w2_7_0 0xA34D -#define reg_fste_w2_7_0_pos 0 -#define reg_fste_w2_7_0_len 8 -#define reg_fste_w2_7_0_lsb 0 -#define xd_p_reg_fste_w2_11_8 0xA34E -#define reg_fste_w2_11_8_pos 0 -#define reg_fste_w2_11_8_len 4 -#define reg_fste_w2_11_8_lsb 8 -#define xd_p_reg_fste_w3_3_0 0xA34E -#define reg_fste_w3_3_0_pos 4 -#define reg_fste_w3_3_0_len 4 -#define reg_fste_w3_3_0_lsb 0 -#define xd_p_reg_fste_w3_11_4 0xA34F -#define reg_fste_w3_11_4_pos 0 -#define reg_fste_w3_11_4_len 8 -#define reg_fste_w3_11_4_lsb 4 -#define xd_p_reg_fste_w4_7_0 0xA350 -#define reg_fste_w4_7_0_pos 0 -#define reg_fste_w4_7_0_len 8 -#define reg_fste_w4_7_0_lsb 0 -#define xd_p_reg_fste_w4_11_8 0xA351 -#define reg_fste_w4_11_8_pos 0 -#define reg_fste_w4_11_8_len 4 -#define reg_fste_w4_11_8_lsb 8 -#define xd_p_reg_fste_w5_3_0 0xA351 -#define reg_fste_w5_3_0_pos 4 -#define reg_fste_w5_3_0_len 4 -#define reg_fste_w5_3_0_lsb 0 -#define xd_p_reg_fste_w5_11_4 0xA352 -#define reg_fste_w5_11_4_pos 0 -#define reg_fste_w5_11_4_len 8 -#define reg_fste_w5_11_4_lsb 4 -#define xd_p_reg_fste_w6_7_0 0xA353 -#define reg_fste_w6_7_0_pos 0 -#define reg_fste_w6_7_0_len 8 -#define reg_fste_w6_7_0_lsb 0 -#define xd_p_reg_fste_w6_11_8 0xA354 -#define reg_fste_w6_11_8_pos 0 -#define reg_fste_w6_11_8_len 4 -#define reg_fste_w6_11_8_lsb 8 -#define xd_p_reg_fste_w7_3_0 0xA354 -#define reg_fste_w7_3_0_pos 4 -#define reg_fste_w7_3_0_len 4 -#define reg_fste_w7_3_0_lsb 0 -#define xd_p_reg_fste_w7_11_4 0xA355 -#define reg_fste_w7_11_4_pos 0 -#define reg_fste_w7_11_4_len 8 -#define reg_fste_w7_11_4_lsb 4 -#define xd_p_reg_fste_w8_7_0 0xA356 -#define reg_fste_w8_7_0_pos 0 -#define reg_fste_w8_7_0_len 8 -#define reg_fste_w8_7_0_lsb 0 -#define xd_p_reg_fste_w8_11_8 0xA357 -#define reg_fste_w8_11_8_pos 0 -#define reg_fste_w8_11_8_len 4 -#define reg_fste_w8_11_8_lsb 8 -#define xd_p_reg_fste_w9_3_0 0xA357 -#define reg_fste_w9_3_0_pos 4 -#define reg_fste_w9_3_0_len 4 -#define reg_fste_w9_3_0_lsb 0 -#define xd_p_reg_fste_w9_11_4 0xA358 -#define reg_fste_w9_11_4_pos 0 -#define reg_fste_w9_11_4_len 8 -#define reg_fste_w9_11_4_lsb 4 -#define xd_p_reg_fste_wa_7_0 0xA359 -#define reg_fste_wa_7_0_pos 0 -#define reg_fste_wa_7_0_len 8 -#define reg_fste_wa_7_0_lsb 0 -#define xd_p_reg_fste_wa_11_8 0xA35A -#define reg_fste_wa_11_8_pos 0 -#define reg_fste_wa_11_8_len 4 -#define reg_fste_wa_11_8_lsb 8 -#define xd_p_reg_fste_wb_3_0 0xA35A -#define reg_fste_wb_3_0_pos 4 -#define reg_fste_wb_3_0_len 4 -#define reg_fste_wb_3_0_lsb 0 -#define xd_p_reg_fste_wb_11_4 0xA35B -#define reg_fste_wb_11_4_pos 0 -#define reg_fste_wb_11_4_len 8 -#define reg_fste_wb_11_4_lsb 4 -#define xd_r_fd_fste_i_adj 0xA35C -#define fd_fste_i_adj_pos 0 -#define fd_fste_i_adj_len 5 -#define fd_fste_i_adj_lsb 0 -#define xd_r_fd_fste_f_adj_7_0 0xA35D -#define fd_fste_f_adj_7_0_pos 0 -#define fd_fste_f_adj_7_0_len 8 -#define fd_fste_f_adj_7_0_lsb 0 -#define xd_r_fd_fste_f_adj_15_8 0xA35E -#define fd_fste_f_adj_15_8_pos 0 -#define fd_fste_f_adj_15_8_len 8 -#define fd_fste_f_adj_15_8_lsb 8 -#define xd_r_fd_fste_f_adj_19_16 0xA35F -#define fd_fste_f_adj_19_16_pos 0 -#define fd_fste_f_adj_19_16_len 4 -#define fd_fste_f_adj_19_16_lsb 16 -#define xd_p_reg_feq_Leak_Bypass 0xA366 -#define reg_feq_Leak_Bypass_pos 0 -#define reg_feq_Leak_Bypass_len 1 -#define reg_feq_Leak_Bypass_lsb 0 -#define xd_p_reg_feq_Leak_Mneg1 0xA366 -#define reg_feq_Leak_Mneg1_pos 1 -#define reg_feq_Leak_Mneg1_len 3 -#define reg_feq_Leak_Mneg1_lsb 0 -#define xd_p_reg_feq_Leak_B_ShiftQ 0xA366 -#define reg_feq_Leak_B_ShiftQ_pos 4 -#define reg_feq_Leak_B_ShiftQ_len 4 -#define reg_feq_Leak_B_ShiftQ_lsb 0 -#define xd_p_reg_feq_Leak_B_Float0 0xA367 -#define reg_feq_Leak_B_Float0_pos 0 -#define reg_feq_Leak_B_Float0_len 8 -#define reg_feq_Leak_B_Float0_lsb 0 -#define xd_p_reg_feq_Leak_B_Float1 0xA368 -#define reg_feq_Leak_B_Float1_pos 0 -#define reg_feq_Leak_B_Float1_len 8 -#define reg_feq_Leak_B_Float1_lsb 0 -#define xd_p_reg_feq_Leak_B_Float2 0xA369 -#define reg_feq_Leak_B_Float2_pos 0 -#define reg_feq_Leak_B_Float2_len 8 -#define reg_feq_Leak_B_Float2_lsb 0 -#define xd_p_reg_feq_Leak_B_Float3 0xA36A -#define reg_feq_Leak_B_Float3_pos 0 -#define reg_feq_Leak_B_Float3_len 8 -#define reg_feq_Leak_B_Float3_lsb 0 -#define xd_p_reg_feq_Leak_B_Float4 0xA36B -#define reg_feq_Leak_B_Float4_pos 0 -#define reg_feq_Leak_B_Float4_len 8 -#define reg_feq_Leak_B_Float4_lsb 0 -#define xd_p_reg_feq_Leak_B_Float5 0xA36C -#define reg_feq_Leak_B_Float5_pos 0 -#define reg_feq_Leak_B_Float5_len 8 -#define reg_feq_Leak_B_Float5_lsb 0 -#define xd_p_reg_feq_Leak_B_Float6 0xA36D -#define reg_feq_Leak_B_Float6_pos 0 -#define reg_feq_Leak_B_Float6_len 8 -#define reg_feq_Leak_B_Float6_lsb 0 -#define xd_p_reg_feq_Leak_B_Float7 0xA36E -#define reg_feq_Leak_B_Float7_pos 0 -#define reg_feq_Leak_B_Float7_len 8 -#define reg_feq_Leak_B_Float7_lsb 0 -#define xd_r_reg_feq_data_h2_7_0 0xA36F -#define reg_feq_data_h2_7_0_pos 0 -#define reg_feq_data_h2_7_0_len 8 -#define reg_feq_data_h2_7_0_lsb 0 -#define xd_r_reg_feq_data_h2_9_8 0xA370 -#define reg_feq_data_h2_9_8_pos 0 -#define reg_feq_data_h2_9_8_len 2 -#define reg_feq_data_h2_9_8_lsb 8 -#define xd_p_reg_feq_leak_use_slice_tps 0xA371 -#define reg_feq_leak_use_slice_tps_pos 0 -#define reg_feq_leak_use_slice_tps_len 1 -#define reg_feq_leak_use_slice_tps_lsb 0 -#define xd_p_reg_feq_read_update 0xA371 -#define reg_feq_read_update_pos 1 -#define reg_feq_read_update_len 1 -#define reg_feq_read_update_lsb 0 -#define xd_p_reg_feq_data_vld 0xA371 -#define reg_feq_data_vld_pos 2 -#define reg_feq_data_vld_len 1 -#define reg_feq_data_vld_lsb 0 -#define xd_p_reg_feq_tone_idx_4_0 0xA371 -#define reg_feq_tone_idx_4_0_pos 3 -#define reg_feq_tone_idx_4_0_len 5 -#define reg_feq_tone_idx_4_0_lsb 0 -#define xd_p_reg_feq_tone_idx_12_5 0xA372 -#define reg_feq_tone_idx_12_5_pos 0 -#define reg_feq_tone_idx_12_5_len 8 -#define reg_feq_tone_idx_12_5_lsb 5 -#define xd_r_reg_feq_data_re_7_0 0xA373 -#define reg_feq_data_re_7_0_pos 0 -#define reg_feq_data_re_7_0_len 8 -#define reg_feq_data_re_7_0_lsb 0 -#define xd_r_reg_feq_data_re_10_8 0xA374 -#define reg_feq_data_re_10_8_pos 0 -#define reg_feq_data_re_10_8_len 3 -#define reg_feq_data_re_10_8_lsb 8 -#define xd_r_reg_feq_data_im_7_0 0xA375 -#define reg_feq_data_im_7_0_pos 0 -#define reg_feq_data_im_7_0_len 8 -#define reg_feq_data_im_7_0_lsb 0 -#define xd_r_reg_feq_data_im_10_8 0xA376 -#define reg_feq_data_im_10_8_pos 0 -#define reg_feq_data_im_10_8_len 3 -#define reg_feq_data_im_10_8_lsb 8 -#define xd_r_reg_feq_y_re 0xA377 -#define reg_feq_y_re_pos 0 -#define reg_feq_y_re_len 8 -#define reg_feq_y_re_lsb 0 -#define xd_r_reg_feq_y_im 0xA378 -#define reg_feq_y_im_pos 0 -#define reg_feq_y_im_len 8 -#define reg_feq_y_im_lsb 0 -#define xd_r_reg_feq_h_re_7_0 0xA379 -#define reg_feq_h_re_7_0_pos 0 -#define reg_feq_h_re_7_0_len 8 -#define reg_feq_h_re_7_0_lsb 0 -#define xd_r_reg_feq_h_re_8 0xA37A -#define reg_feq_h_re_8_pos 0 -#define reg_feq_h_re_8_len 1 -#define reg_feq_h_re_8_lsb 0 -#define xd_r_reg_feq_h_im_7_0 0xA37B -#define reg_feq_h_im_7_0_pos 0 -#define reg_feq_h_im_7_0_len 8 -#define reg_feq_h_im_7_0_lsb 0 -#define xd_r_reg_feq_h_im_8 0xA37C -#define reg_feq_h_im_8_pos 0 -#define reg_feq_h_im_8_len 1 -#define reg_feq_h_im_8_lsb 0 -#define xd_p_fec_super_frm_unit_7_0 0xA380 -#define fec_super_frm_unit_7_0_pos 0 -#define fec_super_frm_unit_7_0_len 8 -#define fec_super_frm_unit_7_0_lsb 0 -#define xd_p_fec_super_frm_unit_15_8 0xA381 -#define fec_super_frm_unit_15_8_pos 0 -#define fec_super_frm_unit_15_8_len 8 -#define fec_super_frm_unit_15_8_lsb 8 -#define xd_r_fec_vtb_err_bit_cnt_7_0 0xA382 -#define fec_vtb_err_bit_cnt_7_0_pos 0 -#define fec_vtb_err_bit_cnt_7_0_len 8 -#define fec_vtb_err_bit_cnt_7_0_lsb 0 -#define xd_r_fec_vtb_err_bit_cnt_15_8 0xA383 -#define fec_vtb_err_bit_cnt_15_8_pos 0 -#define fec_vtb_err_bit_cnt_15_8_len 8 -#define fec_vtb_err_bit_cnt_15_8_lsb 8 -#define xd_r_fec_vtb_err_bit_cnt_23_16 0xA384 -#define fec_vtb_err_bit_cnt_23_16_pos 0 -#define fec_vtb_err_bit_cnt_23_16_len 8 -#define fec_vtb_err_bit_cnt_23_16_lsb 16 -#define xd_p_fec_rsd_packet_unit_7_0 0xA385 -#define fec_rsd_packet_unit_7_0_pos 0 -#define fec_rsd_packet_unit_7_0_len 8 -#define fec_rsd_packet_unit_7_0_lsb 0 -#define xd_p_fec_rsd_packet_unit_15_8 0xA386 -#define fec_rsd_packet_unit_15_8_pos 0 -#define fec_rsd_packet_unit_15_8_len 8 -#define fec_rsd_packet_unit_15_8_lsb 8 -#define xd_r_fec_rsd_bit_err_cnt_7_0 0xA387 -#define fec_rsd_bit_err_cnt_7_0_pos 0 -#define fec_rsd_bit_err_cnt_7_0_len 8 -#define fec_rsd_bit_err_cnt_7_0_lsb 0 -#define xd_r_fec_rsd_bit_err_cnt_15_8 0xA388 -#define fec_rsd_bit_err_cnt_15_8_pos 0 -#define fec_rsd_bit_err_cnt_15_8_len 8 -#define fec_rsd_bit_err_cnt_15_8_lsb 8 -#define xd_r_fec_rsd_bit_err_cnt_23_16 0xA389 -#define fec_rsd_bit_err_cnt_23_16_pos 0 -#define fec_rsd_bit_err_cnt_23_16_len 8 -#define fec_rsd_bit_err_cnt_23_16_lsb 16 -#define xd_r_fec_rsd_abort_packet_cnt_7_0 0xA38A -#define fec_rsd_abort_packet_cnt_7_0_pos 0 -#define fec_rsd_abort_packet_cnt_7_0_len 8 -#define fec_rsd_abort_packet_cnt_7_0_lsb 0 -#define xd_r_fec_rsd_abort_packet_cnt_15_8 0xA38B -#define fec_rsd_abort_packet_cnt_15_8_pos 0 -#define fec_rsd_abort_packet_cnt_15_8_len 8 -#define fec_rsd_abort_packet_cnt_15_8_lsb 8 -#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_7_0 0xA38C -#define fec_RSD_PKT_NUM_PER_UNIT_7_0_pos 0 -#define fec_RSD_PKT_NUM_PER_UNIT_7_0_len 8 -#define fec_RSD_PKT_NUM_PER_UNIT_7_0_lsb 0 -#define xd_p_fec_RSD_PKT_NUM_PER_UNIT_15_8 0xA38D -#define fec_RSD_PKT_NUM_PER_UNIT_15_8_pos 0 -#define fec_RSD_PKT_NUM_PER_UNIT_15_8_len 8 -#define fec_RSD_PKT_NUM_PER_UNIT_15_8_lsb 8 -#define xd_p_fec_RS_TH_1_7_0 0xA38E -#define fec_RS_TH_1_7_0_pos 0 -#define fec_RS_TH_1_7_0_len 8 -#define fec_RS_TH_1_7_0_lsb 0 -#define xd_p_fec_RS_TH_1_15_8 0xA38F -#define fec_RS_TH_1_15_8_pos 0 -#define fec_RS_TH_1_15_8_len 8 -#define fec_RS_TH_1_15_8_lsb 8 -#define xd_p_fec_RS_TH_2 0xA390 -#define fec_RS_TH_2_pos 0 -#define fec_RS_TH_2_len 8 -#define fec_RS_TH_2_lsb 0 -#define xd_p_fec_mon_en 0xA391 -#define fec_mon_en_pos 0 -#define fec_mon_en_len 1 -#define fec_mon_en_lsb 0 -#define xd_p_reg_b8to47 0xA391 -#define reg_b8to47_pos 1 -#define reg_b8to47_len 1 -#define reg_b8to47_lsb 0 -#define xd_p_reg_rsd_sync_rep 0xA391 -#define reg_rsd_sync_rep_pos 2 -#define reg_rsd_sync_rep_len 1 -#define reg_rsd_sync_rep_lsb 0 -#define xd_p_fec_rsd_retrain_rst 0xA391 -#define fec_rsd_retrain_rst_pos 3 -#define fec_rsd_retrain_rst_len 1 -#define fec_rsd_retrain_rst_lsb 0 -#define xd_r_fec_rsd_ber_rdy 0xA391 -#define fec_rsd_ber_rdy_pos 4 -#define fec_rsd_ber_rdy_len 1 -#define fec_rsd_ber_rdy_lsb 0 -#define xd_p_fec_rsd_ber_rst 0xA391 -#define fec_rsd_ber_rst_pos 5 -#define fec_rsd_ber_rst_len 1 -#define fec_rsd_ber_rst_lsb 0 -#define xd_r_fec_vtb_ber_rdy 0xA391 -#define fec_vtb_ber_rdy_pos 6 -#define fec_vtb_ber_rdy_len 1 -#define fec_vtb_ber_rdy_lsb 0 -#define xd_p_fec_vtb_ber_rst 0xA391 -#define fec_vtb_ber_rst_pos 7 -#define fec_vtb_ber_rst_len 1 -#define fec_vtb_ber_rst_lsb 0 -#define xd_p_reg_vtb_clk40en 0xA392 -#define reg_vtb_clk40en_pos 0 -#define reg_vtb_clk40en_len 1 -#define reg_vtb_clk40en_lsb 0 -#define xd_p_fec_vtb_rsd_mon_en 0xA392 -#define fec_vtb_rsd_mon_en_pos 1 -#define fec_vtb_rsd_mon_en_len 1 -#define fec_vtb_rsd_mon_en_lsb 0 -#define xd_p_reg_fec_data_en 0xA392 -#define reg_fec_data_en_pos 2 -#define reg_fec_data_en_len 1 -#define reg_fec_data_en_lsb 0 -#define xd_p_fec_dummy_reg_2 0xA392 -#define fec_dummy_reg_2_pos 3 -#define fec_dummy_reg_2_len 3 -#define fec_dummy_reg_2_lsb 0 -#define xd_p_reg_sync_chk 0xA392 -#define reg_sync_chk_pos 6 -#define reg_sync_chk_len 1 -#define reg_sync_chk_lsb 0 -#define xd_p_fec_rsd_bypass 0xA392 -#define fec_rsd_bypass_pos 7 -#define fec_rsd_bypass_len 1 -#define fec_rsd_bypass_lsb 0 -#define xd_p_fec_sw_rst 0xA393 -#define fec_sw_rst_pos 0 -#define fec_sw_rst_len 1 -#define fec_sw_rst_lsb 0 -#define xd_r_fec_vtb_pm_crc 0xA394 -#define fec_vtb_pm_crc_pos 0 -#define fec_vtb_pm_crc_len 8 -#define fec_vtb_pm_crc_lsb 0 -#define xd_r_fec_vtb_tb_7_crc 0xA395 -#define fec_vtb_tb_7_crc_pos 0 -#define fec_vtb_tb_7_crc_len 8 -#define fec_vtb_tb_7_crc_lsb 0 -#define xd_r_fec_vtb_tb_6_crc 0xA396 -#define fec_vtb_tb_6_crc_pos 0 -#define fec_vtb_tb_6_crc_len 8 -#define fec_vtb_tb_6_crc_lsb 0 -#define xd_r_fec_vtb_tb_5_crc 0xA397 -#define fec_vtb_tb_5_crc_pos 0 -#define fec_vtb_tb_5_crc_len 8 -#define fec_vtb_tb_5_crc_lsb 0 -#define xd_r_fec_vtb_tb_4_crc 0xA398 -#define fec_vtb_tb_4_crc_pos 0 -#define fec_vtb_tb_4_crc_len 8 -#define fec_vtb_tb_4_crc_lsb 0 -#define xd_r_fec_vtb_tb_3_crc 0xA399 -#define fec_vtb_tb_3_crc_pos 0 -#define fec_vtb_tb_3_crc_len 8 -#define fec_vtb_tb_3_crc_lsb 0 -#define xd_r_fec_vtb_tb_2_crc 0xA39A -#define fec_vtb_tb_2_crc_pos 0 -#define fec_vtb_tb_2_crc_len 8 -#define fec_vtb_tb_2_crc_lsb 0 -#define xd_r_fec_vtb_tb_1_crc 0xA39B -#define fec_vtb_tb_1_crc_pos 0 -#define fec_vtb_tb_1_crc_len 8 -#define fec_vtb_tb_1_crc_lsb 0 -#define xd_r_fec_vtb_tb_0_crc 0xA39C -#define fec_vtb_tb_0_crc_pos 0 -#define fec_vtb_tb_0_crc_len 8 -#define fec_vtb_tb_0_crc_lsb 0 -#define xd_r_fec_rsd_bank0_crc 0xA39D -#define fec_rsd_bank0_crc_pos 0 -#define fec_rsd_bank0_crc_len 8 -#define fec_rsd_bank0_crc_lsb 0 -#define xd_r_fec_rsd_bank1_crc 0xA39E -#define fec_rsd_bank1_crc_pos 0 -#define fec_rsd_bank1_crc_len 8 -#define fec_rsd_bank1_crc_lsb 0 -#define xd_r_fec_idi_vtb_crc 0xA39F -#define fec_idi_vtb_crc_pos 0 -#define fec_idi_vtb_crc_len 8 -#define fec_idi_vtb_crc_lsb 0 -#define xd_g_reg_tpsd_txmod 0xA3C0 -#define reg_tpsd_txmod_pos 0 -#define reg_tpsd_txmod_len 2 -#define reg_tpsd_txmod_lsb 0 -#define xd_g_reg_tpsd_gi 0xA3C0 -#define reg_tpsd_gi_pos 2 -#define reg_tpsd_gi_len 2 -#define reg_tpsd_gi_lsb 0 -#define xd_g_reg_tpsd_hier 0xA3C0 -#define reg_tpsd_hier_pos 4 -#define reg_tpsd_hier_len 3 -#define reg_tpsd_hier_lsb 0 -#define xd_g_reg_bw 0xA3C1 -#define reg_bw_pos 2 -#define reg_bw_len 2 -#define reg_bw_lsb 0 -#define xd_g_reg_dec_pri 0xA3C1 -#define reg_dec_pri_pos 4 -#define reg_dec_pri_len 1 -#define reg_dec_pri_lsb 0 -#define xd_g_reg_tpsd_const 0xA3C1 -#define reg_tpsd_const_pos 6 -#define reg_tpsd_const_len 2 -#define reg_tpsd_const_lsb 0 -#define xd_g_reg_tpsd_hpcr 0xA3C2 -#define reg_tpsd_hpcr_pos 0 -#define reg_tpsd_hpcr_len 3 -#define reg_tpsd_hpcr_lsb 0 -#define xd_g_reg_tpsd_lpcr 0xA3C2 -#define reg_tpsd_lpcr_pos 3 -#define reg_tpsd_lpcr_len 3 -#define reg_tpsd_lpcr_lsb 0 -#define xd_g_reg_ofsm_clk 0xA3D0 -#define reg_ofsm_clk_pos 0 -#define reg_ofsm_clk_len 3 -#define reg_ofsm_clk_lsb 0 -#define xd_g_reg_fclk_cfg 0xA3D1 -#define reg_fclk_cfg_pos 0 -#define reg_fclk_cfg_len 1 -#define reg_fclk_cfg_lsb 0 -#define xd_g_reg_fclk_idi 0xA3D1 -#define reg_fclk_idi_pos 1 -#define reg_fclk_idi_len 1 -#define reg_fclk_idi_lsb 0 -#define xd_g_reg_fclk_odi 0xA3D1 -#define reg_fclk_odi_pos 2 -#define reg_fclk_odi_len 1 -#define reg_fclk_odi_lsb 0 -#define xd_g_reg_fclk_rsd 0xA3D1 -#define reg_fclk_rsd_pos 3 -#define reg_fclk_rsd_len 1 -#define reg_fclk_rsd_lsb 0 -#define xd_g_reg_fclk_vtb 0xA3D1 -#define reg_fclk_vtb_pos 4 -#define reg_fclk_vtb_len 1 -#define reg_fclk_vtb_lsb 0 -#define xd_g_reg_fclk_cste 0xA3D1 -#define reg_fclk_cste_pos 5 -#define reg_fclk_cste_len 1 -#define reg_fclk_cste_lsb 0 -#define xd_g_reg_fclk_mp2if 0xA3D1 -#define reg_fclk_mp2if_pos 6 -#define reg_fclk_mp2if_len 1 -#define reg_fclk_mp2if_lsb 0 -#define xd_I2C_i2c_m_slave_addr 0xA400 -#define i2c_m_slave_addr_pos 0 -#define i2c_m_slave_addr_len 8 -#define i2c_m_slave_addr_lsb 0 -#define xd_I2C_i2c_m_data1 0xA401 -#define i2c_m_data1_pos 0 -#define i2c_m_data1_len 8 -#define i2c_m_data1_lsb 0 -#define xd_I2C_i2c_m_data2 0xA402 -#define i2c_m_data2_pos 0 -#define i2c_m_data2_len 8 -#define i2c_m_data2_lsb 0 -#define xd_I2C_i2c_m_data3 0xA403 -#define i2c_m_data3_pos 0 -#define i2c_m_data3_len 8 -#define i2c_m_data3_lsb 0 -#define xd_I2C_i2c_m_data4 0xA404 -#define i2c_m_data4_pos 0 -#define i2c_m_data4_len 8 -#define i2c_m_data4_lsb 0 -#define xd_I2C_i2c_m_data5 0xA405 -#define i2c_m_data5_pos 0 -#define i2c_m_data5_len 8 -#define i2c_m_data5_lsb 0 -#define xd_I2C_i2c_m_data6 0xA406 -#define i2c_m_data6_pos 0 -#define i2c_m_data6_len 8 -#define i2c_m_data6_lsb 0 -#define xd_I2C_i2c_m_data7 0xA407 -#define i2c_m_data7_pos 0 -#define i2c_m_data7_len 8 -#define i2c_m_data7_lsb 0 -#define xd_I2C_i2c_m_data8 0xA408 -#define i2c_m_data8_pos 0 -#define i2c_m_data8_len 8 -#define i2c_m_data8_lsb 0 -#define xd_I2C_i2c_m_data9 0xA409 -#define i2c_m_data9_pos 0 -#define i2c_m_data9_len 8 -#define i2c_m_data9_lsb 0 -#define xd_I2C_i2c_m_data10 0xA40A -#define i2c_m_data10_pos 0 -#define i2c_m_data10_len 8 -#define i2c_m_data10_lsb 0 -#define xd_I2C_i2c_m_data11 0xA40B -#define i2c_m_data11_pos 0 -#define i2c_m_data11_len 8 -#define i2c_m_data11_lsb 0 -#define xd_I2C_i2c_m_cmd_rw 0xA40C -#define i2c_m_cmd_rw_pos 0 -#define i2c_m_cmd_rw_len 1 -#define i2c_m_cmd_rw_lsb 0 -#define xd_I2C_i2c_m_cmd_rwlen 0xA40C -#define i2c_m_cmd_rwlen_pos 3 -#define i2c_m_cmd_rwlen_len 4 -#define i2c_m_cmd_rwlen_lsb 0 -#define xd_I2C_i2c_m_status_cmd_exe 0xA40D -#define i2c_m_status_cmd_exe_pos 0 -#define i2c_m_status_cmd_exe_len 1 -#define i2c_m_status_cmd_exe_lsb 0 -#define xd_I2C_i2c_m_status_wdat_done 0xA40D -#define i2c_m_status_wdat_done_pos 1 -#define i2c_m_status_wdat_done_len 1 -#define i2c_m_status_wdat_done_lsb 0 -#define xd_I2C_i2c_m_status_wdat_fail 0xA40D -#define i2c_m_status_wdat_fail_pos 2 -#define i2c_m_status_wdat_fail_len 1 -#define i2c_m_status_wdat_fail_lsb 0 -#define xd_I2C_i2c_m_period 0xA40E -#define i2c_m_period_pos 0 -#define i2c_m_period_len 8 -#define i2c_m_period_lsb 0 -#define xd_I2C_i2c_m_reg_msb_lsb 0xA40F -#define i2c_m_reg_msb_lsb_pos 0 -#define i2c_m_reg_msb_lsb_len 1 -#define i2c_m_reg_msb_lsb_lsb 0 -#define xd_I2C_reg_ofdm_rst 0xA40F -#define reg_ofdm_rst_pos 1 -#define reg_ofdm_rst_len 1 -#define reg_ofdm_rst_lsb 0 -#define xd_I2C_reg_sample_period_on_tuner 0xA40F -#define reg_sample_period_on_tuner_pos 2 -#define reg_sample_period_on_tuner_len 1 -#define reg_sample_period_on_tuner_lsb 0 -#define xd_I2C_reg_rst_i2c 0xA40F -#define reg_rst_i2c_pos 3 -#define reg_rst_i2c_len 1 -#define reg_rst_i2c_lsb 0 -#define xd_I2C_reg_ofdm_rst_en 0xA40F -#define reg_ofdm_rst_en_pos 4 -#define reg_ofdm_rst_en_len 1 -#define reg_ofdm_rst_en_lsb 0 -#define xd_I2C_reg_tuner_sda_sync_on 0xA40F -#define reg_tuner_sda_sync_on_pos 5 -#define reg_tuner_sda_sync_on_len 1 -#define reg_tuner_sda_sync_on_lsb 0 -#define xd_p_mp2if_data_access_disable_ofsm 0xA500 -#define mp2if_data_access_disable_ofsm_pos 0 -#define mp2if_data_access_disable_ofsm_len 1 -#define mp2if_data_access_disable_ofsm_lsb 0 -#define xd_p_reg_mp2_sw_rst_ofsm 0xA500 -#define reg_mp2_sw_rst_ofsm_pos 1 -#define reg_mp2_sw_rst_ofsm_len 1 -#define reg_mp2_sw_rst_ofsm_lsb 0 -#define xd_p_reg_mp2if_clk_en_ofsm 0xA500 -#define reg_mp2if_clk_en_ofsm_pos 2 -#define reg_mp2if_clk_en_ofsm_len 1 -#define reg_mp2if_clk_en_ofsm_lsb 0 -#define xd_r_mp2if_sync_byte_locked 0xA500 -#define mp2if_sync_byte_locked_pos 3 -#define mp2if_sync_byte_locked_len 1 -#define mp2if_sync_byte_locked_lsb 0 -#define xd_r_mp2if_ts_not_188 0xA500 -#define mp2if_ts_not_188_pos 4 -#define mp2if_ts_not_188_len 1 -#define mp2if_ts_not_188_lsb 0 -#define xd_r_mp2if_psb_empty 0xA500 -#define mp2if_psb_empty_pos 5 -#define mp2if_psb_empty_len 1 -#define mp2if_psb_empty_lsb 0 -#define xd_r_mp2if_psb_overflow 0xA500 -#define mp2if_psb_overflow_pos 6 -#define mp2if_psb_overflow_len 1 -#define mp2if_psb_overflow_lsb 0 -#define xd_p_mp2if_keep_sf_sync_byte_ofsm 0xA500 -#define mp2if_keep_sf_sync_byte_ofsm_pos 7 -#define mp2if_keep_sf_sync_byte_ofsm_len 1 -#define mp2if_keep_sf_sync_byte_ofsm_lsb 0 -#define xd_r_mp2if_psb_mp2if_num_pkt 0xA501 -#define mp2if_psb_mp2if_num_pkt_pos 0 -#define mp2if_psb_mp2if_num_pkt_len 6 -#define mp2if_psb_mp2if_num_pkt_lsb 0 -#define xd_p_reg_mpeg_full_speed_ofsm 0xA501 -#define reg_mpeg_full_speed_ofsm_pos 6 -#define reg_mpeg_full_speed_ofsm_len 1 -#define reg_mpeg_full_speed_ofsm_lsb 0 -#define xd_p_mp2if_mpeg_ser_mode_ofsm 0xA501 -#define mp2if_mpeg_ser_mode_ofsm_pos 7 -#define mp2if_mpeg_ser_mode_ofsm_len 1 -#define mp2if_mpeg_ser_mode_ofsm_lsb 0 -#define xd_p_reg_sw_mon51 0xA600 -#define reg_sw_mon51_pos 0 -#define reg_sw_mon51_len 8 -#define reg_sw_mon51_lsb 0 -#define xd_p_reg_top_pcsel 0xA601 -#define reg_top_pcsel_pos 0 -#define reg_top_pcsel_len 1 -#define reg_top_pcsel_lsb 0 -#define xd_p_reg_top_rs232 0xA601 -#define reg_top_rs232_pos 1 -#define reg_top_rs232_len 1 -#define reg_top_rs232_lsb 0 -#define xd_p_reg_top_pcout 0xA601 -#define reg_top_pcout_pos 2 -#define reg_top_pcout_len 1 -#define reg_top_pcout_lsb 0 -#define xd_p_reg_top_debug 0xA601 -#define reg_top_debug_pos 3 -#define reg_top_debug_len 1 -#define reg_top_debug_lsb 0 -#define xd_p_reg_top_adcdly 0xA601 -#define reg_top_adcdly_pos 4 -#define reg_top_adcdly_len 2 -#define reg_top_adcdly_lsb 0 -#define xd_p_reg_top_pwrdw 0xA601 -#define reg_top_pwrdw_pos 6 -#define reg_top_pwrdw_len 1 -#define reg_top_pwrdw_lsb 0 -#define xd_p_reg_top_pwrdw_inv 0xA601 -#define reg_top_pwrdw_inv_pos 7 -#define reg_top_pwrdw_inv_len 1 -#define reg_top_pwrdw_inv_lsb 0 -#define xd_p_reg_top_int_inv 0xA602 -#define reg_top_int_inv_pos 0 -#define reg_top_int_inv_len 1 -#define reg_top_int_inv_lsb 0 -#define xd_p_reg_top_dio_sel 0xA602 -#define reg_top_dio_sel_pos 1 -#define reg_top_dio_sel_len 1 -#define reg_top_dio_sel_lsb 0 -#define xd_p_reg_top_gpioon0 0xA603 -#define reg_top_gpioon0_pos 0 -#define reg_top_gpioon0_len 1 -#define reg_top_gpioon0_lsb 0 -#define xd_p_reg_top_gpioon1 0xA603 -#define reg_top_gpioon1_pos 1 -#define reg_top_gpioon1_len 1 -#define reg_top_gpioon1_lsb 0 -#define xd_p_reg_top_gpioon2 0xA603 -#define reg_top_gpioon2_pos 2 -#define reg_top_gpioon2_len 1 -#define reg_top_gpioon2_lsb 0 -#define xd_p_reg_top_gpioon3 0xA603 -#define reg_top_gpioon3_pos 3 -#define reg_top_gpioon3_len 1 -#define reg_top_gpioon3_lsb 0 -#define xd_p_reg_top_lockon1 0xA603 -#define reg_top_lockon1_pos 4 -#define reg_top_lockon1_len 1 -#define reg_top_lockon1_lsb 0 -#define xd_p_reg_top_lockon2 0xA603 -#define reg_top_lockon2_pos 5 -#define reg_top_lockon2_len 1 -#define reg_top_lockon2_lsb 0 -#define xd_p_reg_top_gpioo0 0xA604 -#define reg_top_gpioo0_pos 0 -#define reg_top_gpioo0_len 1 -#define reg_top_gpioo0_lsb 0 -#define xd_p_reg_top_gpioo1 0xA604 -#define reg_top_gpioo1_pos 1 -#define reg_top_gpioo1_len 1 -#define reg_top_gpioo1_lsb 0 -#define xd_p_reg_top_gpioo2 0xA604 -#define reg_top_gpioo2_pos 2 -#define reg_top_gpioo2_len 1 -#define reg_top_gpioo2_lsb 0 -#define xd_p_reg_top_gpioo3 0xA604 -#define reg_top_gpioo3_pos 3 -#define reg_top_gpioo3_len 1 -#define reg_top_gpioo3_lsb 0 -#define xd_p_reg_top_lock1 0xA604 -#define reg_top_lock1_pos 4 -#define reg_top_lock1_len 1 -#define reg_top_lock1_lsb 0 -#define xd_p_reg_top_lock2 0xA604 -#define reg_top_lock2_pos 5 -#define reg_top_lock2_len 1 -#define reg_top_lock2_lsb 0 -#define xd_p_reg_top_gpioen0 0xA605 -#define reg_top_gpioen0_pos 0 -#define reg_top_gpioen0_len 1 -#define reg_top_gpioen0_lsb 0 -#define xd_p_reg_top_gpioen1 0xA605 -#define reg_top_gpioen1_pos 1 -#define reg_top_gpioen1_len 1 -#define reg_top_gpioen1_lsb 0 -#define xd_p_reg_top_gpioen2 0xA605 -#define reg_top_gpioen2_pos 2 -#define reg_top_gpioen2_len 1 -#define reg_top_gpioen2_lsb 0 -#define xd_p_reg_top_gpioen3 0xA605 -#define reg_top_gpioen3_pos 3 -#define reg_top_gpioen3_len 1 -#define reg_top_gpioen3_lsb 0 -#define xd_p_reg_top_locken1 0xA605 -#define reg_top_locken1_pos 4 -#define reg_top_locken1_len 1 -#define reg_top_locken1_lsb 0 -#define xd_p_reg_top_locken2 0xA605 -#define reg_top_locken2_pos 5 -#define reg_top_locken2_len 1 -#define reg_top_locken2_lsb 0 -#define xd_r_reg_top_gpioi0 0xA606 -#define reg_top_gpioi0_pos 0 -#define reg_top_gpioi0_len 1 -#define reg_top_gpioi0_lsb 0 -#define xd_r_reg_top_gpioi1 0xA606 -#define reg_top_gpioi1_pos 1 -#define reg_top_gpioi1_len 1 -#define reg_top_gpioi1_lsb 0 -#define xd_r_reg_top_gpioi2 0xA606 -#define reg_top_gpioi2_pos 2 -#define reg_top_gpioi2_len 1 -#define reg_top_gpioi2_lsb 0 -#define xd_r_reg_top_gpioi3 0xA606 -#define reg_top_gpioi3_pos 3 -#define reg_top_gpioi3_len 1 -#define reg_top_gpioi3_lsb 0 -#define xd_r_reg_top_locki1 0xA606 -#define reg_top_locki1_pos 4 -#define reg_top_locki1_len 1 -#define reg_top_locki1_lsb 0 -#define xd_r_reg_top_locki2 0xA606 -#define reg_top_locki2_pos 5 -#define reg_top_locki2_len 1 -#define reg_top_locki2_lsb 0 -#define xd_p_reg_dummy_7_0 0xA608 -#define reg_dummy_7_0_pos 0 -#define reg_dummy_7_0_len 8 -#define reg_dummy_7_0_lsb 0 -#define xd_p_reg_dummy_15_8 0xA609 -#define reg_dummy_15_8_pos 0 -#define reg_dummy_15_8_len 8 -#define reg_dummy_15_8_lsb 8 -#define xd_p_reg_dummy_23_16 0xA60A -#define reg_dummy_23_16_pos 0 -#define reg_dummy_23_16_len 8 -#define reg_dummy_23_16_lsb 16 -#define xd_p_reg_dummy_31_24 0xA60B -#define reg_dummy_31_24_pos 0 -#define reg_dummy_31_24_len 8 -#define reg_dummy_31_24_lsb 24 -#define xd_p_reg_dummy_39_32 0xA60C -#define reg_dummy_39_32_pos 0 -#define reg_dummy_39_32_len 8 -#define reg_dummy_39_32_lsb 32 -#define xd_p_reg_dummy_47_40 0xA60D -#define reg_dummy_47_40_pos 0 -#define reg_dummy_47_40_len 8 -#define reg_dummy_47_40_lsb 40 -#define xd_p_reg_dummy_55_48 0xA60E -#define reg_dummy_55_48_pos 0 -#define reg_dummy_55_48_len 8 -#define reg_dummy_55_48_lsb 48 -#define xd_p_reg_dummy_63_56 0xA60F -#define reg_dummy_63_56_pos 0 -#define reg_dummy_63_56_len 8 -#define reg_dummy_63_56_lsb 56 -#define xd_p_reg_dummy_71_64 0xA610 -#define reg_dummy_71_64_pos 0 -#define reg_dummy_71_64_len 8 -#define reg_dummy_71_64_lsb 64 -#define xd_p_reg_dummy_79_72 0xA611 -#define reg_dummy_79_72_pos 0 -#define reg_dummy_79_72_len 8 -#define reg_dummy_79_72_lsb 72 -#define xd_p_reg_dummy_87_80 0xA612 -#define reg_dummy_87_80_pos 0 -#define reg_dummy_87_80_len 8 -#define reg_dummy_87_80_lsb 80 -#define xd_p_reg_dummy_95_88 0xA613 -#define reg_dummy_95_88_pos 0 -#define reg_dummy_95_88_len 8 -#define reg_dummy_95_88_lsb 88 -#define xd_p_reg_dummy_103_96 0xA614 -#define reg_dummy_103_96_pos 0 -#define reg_dummy_103_96_len 8 -#define reg_dummy_103_96_lsb 96 - -#define xd_p_reg_unplug_flag 0xA615 -#define reg_unplug_flag_pos 0 -#define reg_unplug_flag_len 1 -#define reg_unplug_flag_lsb 104 - -#define xd_p_reg_api_dca_stes_request 0xA615 -#define reg_api_dca_stes_request_pos 1 -#define reg_api_dca_stes_request_len 1 -#define reg_api_dca_stes_request_lsb 0 - -#define xd_p_reg_back_to_dca_flag 0xA615 -#define reg_back_to_dca_flag_pos 2 -#define reg_back_to_dca_flag_len 1 -#define reg_back_to_dca_flag_lsb 106 - -#define xd_p_reg_api_retrain_request 0xA615 -#define reg_api_retrain_request_pos 3 -#define reg_api_retrain_request_len 1 -#define reg_api_retrain_request_lsb 0 - -#define xd_p_reg_Dyn_Top_Try_flag 0xA615 -#define reg_Dyn_Top_Try_flag_pos 3 -#define reg_Dyn_Top_Try_flag_len 1 -#define reg_Dyn_Top_Try_flag_lsb 107 - -#define xd_p_reg_API_retrain_freeze_flag 0xA615 -#define reg_API_retrain_freeze_flag_pos 4 -#define reg_API_retrain_freeze_flag_len 1 -#define reg_API_retrain_freeze_flag_lsb 108 - -#define xd_p_reg_dummy_111_104 0xA615 -#define reg_dummy_111_104_pos 0 -#define reg_dummy_111_104_len 8 -#define reg_dummy_111_104_lsb 104 -#define xd_p_reg_dummy_119_112 0xA616 -#define reg_dummy_119_112_pos 0 -#define reg_dummy_119_112_len 8 -#define reg_dummy_119_112_lsb 112 -#define xd_p_reg_dummy_127_120 0xA617 -#define reg_dummy_127_120_pos 0 -#define reg_dummy_127_120_len 8 -#define reg_dummy_127_120_lsb 120 -#define xd_p_reg_dummy_135_128 0xA618 -#define reg_dummy_135_128_pos 0 -#define reg_dummy_135_128_len 8 -#define reg_dummy_135_128_lsb 128 - -#define xd_p_reg_dummy_143_136 0xA619 -#define reg_dummy_143_136_pos 0 -#define reg_dummy_143_136_len 8 -#define reg_dummy_143_136_lsb 136 - -#define xd_p_reg_CCIR_dis 0xA619 -#define reg_CCIR_dis_pos 0 -#define reg_CCIR_dis_len 1 -#define reg_CCIR_dis_lsb 0 - -#define xd_p_reg_dummy_151_144 0xA61A -#define reg_dummy_151_144_pos 0 -#define reg_dummy_151_144_len 8 -#define reg_dummy_151_144_lsb 144 - -#define xd_p_reg_dummy_159_152 0xA61B -#define reg_dummy_159_152_pos 0 -#define reg_dummy_159_152_len 8 -#define reg_dummy_159_152_lsb 152 - -#define xd_p_reg_dummy_167_160 0xA61C -#define reg_dummy_167_160_pos 0 -#define reg_dummy_167_160_len 8 -#define reg_dummy_167_160_lsb 160 - -#define xd_p_reg_dummy_175_168 0xA61D -#define reg_dummy_175_168_pos 0 -#define reg_dummy_175_168_len 8 -#define reg_dummy_175_168_lsb 168 - -#define xd_p_reg_dummy_183_176 0xA61E -#define reg_dummy_183_176_pos 0 -#define reg_dummy_183_176_len 8 -#define reg_dummy_183_176_lsb 176 - -#define xd_p_reg_ofsm_read_rbc_en 0xA61E -#define reg_ofsm_read_rbc_en_pos 2 -#define reg_ofsm_read_rbc_en_len 1 -#define reg_ofsm_read_rbc_en_lsb 0 - -#define xd_p_reg_ce_filter_selection_dis 0xA61E -#define reg_ce_filter_selection_dis_pos 1 -#define reg_ce_filter_selection_dis_len 1 -#define reg_ce_filter_selection_dis_lsb 0 - -#define xd_p_reg_OFSM_version_control_7_0 0xA611 -#define reg_OFSM_version_control_7_0_pos 0 -#define reg_OFSM_version_control_7_0_len 8 -#define reg_OFSM_version_control_7_0_lsb 0 - -#define xd_p_reg_OFSM_version_control_15_8 0xA61F -#define reg_OFSM_version_control_15_8_pos 0 -#define reg_OFSM_version_control_15_8_len 8 -#define reg_OFSM_version_control_15_8_lsb 0 - -#define xd_p_reg_OFSM_version_control_23_16 0xA620 -#define reg_OFSM_version_control_23_16_pos 0 -#define reg_OFSM_version_control_23_16_len 8 -#define reg_OFSM_version_control_23_16_lsb 0 - -#define xd_p_reg_dummy_191_184 0xA61F -#define reg_dummy_191_184_pos 0 -#define reg_dummy_191_184_len 8 -#define reg_dummy_191_184_lsb 184 - -#define xd_p_reg_dummy_199_192 0xA620 -#define reg_dummy_199_192_pos 0 -#define reg_dummy_199_192_len 8 -#define reg_dummy_199_192_lsb 192 - -#define xd_p_reg_ce_en 0xABC0 -#define reg_ce_en_pos 0 -#define reg_ce_en_len 1 -#define reg_ce_en_lsb 0 -#define xd_p_reg_ce_fctrl_en 0xABC0 -#define reg_ce_fctrl_en_pos 1 -#define reg_ce_fctrl_en_len 1 -#define reg_ce_fctrl_en_lsb 0 -#define xd_p_reg_ce_fste_tdi 0xABC0 -#define reg_ce_fste_tdi_pos 2 -#define reg_ce_fste_tdi_len 1 -#define reg_ce_fste_tdi_lsb 0 -#define xd_p_reg_ce_dynamic 0xABC0 -#define reg_ce_dynamic_pos 3 -#define reg_ce_dynamic_len 1 -#define reg_ce_dynamic_lsb 0 -#define xd_p_reg_ce_conf 0xABC0 -#define reg_ce_conf_pos 4 -#define reg_ce_conf_len 2 -#define reg_ce_conf_lsb 0 -#define xd_p_reg_ce_dyn12 0xABC0 -#define reg_ce_dyn12_pos 6 -#define reg_ce_dyn12_len 1 -#define reg_ce_dyn12_lsb 0 -#define xd_p_reg_ce_derot_en 0xABC0 -#define reg_ce_derot_en_pos 7 -#define reg_ce_derot_en_len 1 -#define reg_ce_derot_en_lsb 0 -#define xd_p_reg_ce_dynamic_th_7_0 0xABC1 -#define reg_ce_dynamic_th_7_0_pos 0 -#define reg_ce_dynamic_th_7_0_len 8 -#define reg_ce_dynamic_th_7_0_lsb 0 -#define xd_p_reg_ce_dynamic_th_15_8 0xABC2 -#define reg_ce_dynamic_th_15_8_pos 0 -#define reg_ce_dynamic_th_15_8_len 8 -#define reg_ce_dynamic_th_15_8_lsb 8 -#define xd_p_reg_ce_s1 0xABC3 -#define reg_ce_s1_pos 0 -#define reg_ce_s1_len 5 -#define reg_ce_s1_lsb 0 -#define xd_p_reg_ce_var_forced_value 0xABC3 -#define reg_ce_var_forced_value_pos 5 -#define reg_ce_var_forced_value_len 3 -#define reg_ce_var_forced_value_lsb 0 -#define xd_p_reg_ce_data_im_7_0 0xABC4 -#define reg_ce_data_im_7_0_pos 0 -#define reg_ce_data_im_7_0_len 8 -#define reg_ce_data_im_7_0_lsb 0 -#define xd_p_reg_ce_data_im_8 0xABC5 -#define reg_ce_data_im_8_pos 0 -#define reg_ce_data_im_8_len 1 -#define reg_ce_data_im_8_lsb 0 -#define xd_p_reg_ce_data_re_6_0 0xABC5 -#define reg_ce_data_re_6_0_pos 1 -#define reg_ce_data_re_6_0_len 7 -#define reg_ce_data_re_6_0_lsb 0 -#define xd_p_reg_ce_data_re_8_7 0xABC6 -#define reg_ce_data_re_8_7_pos 0 -#define reg_ce_data_re_8_7_len 2 -#define reg_ce_data_re_8_7_lsb 7 -#define xd_p_reg_ce_tone_5_0 0xABC6 -#define reg_ce_tone_5_0_pos 2 -#define reg_ce_tone_5_0_len 6 -#define reg_ce_tone_5_0_lsb 0 -#define xd_p_reg_ce_tone_12_6 0xABC7 -#define reg_ce_tone_12_6_pos 0 -#define reg_ce_tone_12_6_len 7 -#define reg_ce_tone_12_6_lsb 6 -#define xd_p_reg_ce_centroid_drift_th 0xABC8 -#define reg_ce_centroid_drift_th_pos 0 -#define reg_ce_centroid_drift_th_len 8 -#define reg_ce_centroid_drift_th_lsb 0 -#define xd_p_reg_ce_centroid_count_max 0xABC9 -#define reg_ce_centroid_count_max_pos 0 -#define reg_ce_centroid_count_max_len 4 -#define reg_ce_centroid_count_max_lsb 0 -#define xd_p_reg_ce_centroid_bias_inc_7_0 0xABCA -#define reg_ce_centroid_bias_inc_7_0_pos 0 -#define reg_ce_centroid_bias_inc_7_0_len 8 -#define reg_ce_centroid_bias_inc_7_0_lsb 0 -#define xd_p_reg_ce_centroid_bias_inc_8 0xABCB -#define reg_ce_centroid_bias_inc_8_pos 0 -#define reg_ce_centroid_bias_inc_8_len 1 -#define reg_ce_centroid_bias_inc_8_lsb 0 -#define xd_p_reg_ce_var_th0_7_0 0xABCC -#define reg_ce_var_th0_7_0_pos 0 -#define reg_ce_var_th0_7_0_len 8 -#define reg_ce_var_th0_7_0_lsb 0 -#define xd_p_reg_ce_var_th0_15_8 0xABCD -#define reg_ce_var_th0_15_8_pos 0 -#define reg_ce_var_th0_15_8_len 8 -#define reg_ce_var_th0_15_8_lsb 8 -#define xd_p_reg_ce_var_th1_7_0 0xABCE -#define reg_ce_var_th1_7_0_pos 0 -#define reg_ce_var_th1_7_0_len 8 -#define reg_ce_var_th1_7_0_lsb 0 -#define xd_p_reg_ce_var_th1_15_8 0xABCF -#define reg_ce_var_th1_15_8_pos 0 -#define reg_ce_var_th1_15_8_len 8 -#define reg_ce_var_th1_15_8_lsb 8 -#define xd_p_reg_ce_var_th2_7_0 0xABD0 -#define reg_ce_var_th2_7_0_pos 0 -#define reg_ce_var_th2_7_0_len 8 -#define reg_ce_var_th2_7_0_lsb 0 -#define xd_p_reg_ce_var_th2_15_8 0xABD1 -#define reg_ce_var_th2_15_8_pos 0 -#define reg_ce_var_th2_15_8_len 8 -#define reg_ce_var_th2_15_8_lsb 8 -#define xd_p_reg_ce_var_th3_7_0 0xABD2 -#define reg_ce_var_th3_7_0_pos 0 -#define reg_ce_var_th3_7_0_len 8 -#define reg_ce_var_th3_7_0_lsb 0 -#define xd_p_reg_ce_var_th3_15_8 0xABD3 -#define reg_ce_var_th3_15_8_pos 0 -#define reg_ce_var_th3_15_8_len 8 -#define reg_ce_var_th3_15_8_lsb 8 -#define xd_p_reg_ce_var_th4_7_0 0xABD4 -#define reg_ce_var_th4_7_0_pos 0 -#define reg_ce_var_th4_7_0_len 8 -#define reg_ce_var_th4_7_0_lsb 0 -#define xd_p_reg_ce_var_th4_15_8 0xABD5 -#define reg_ce_var_th4_15_8_pos 0 -#define reg_ce_var_th4_15_8_len 8 -#define reg_ce_var_th4_15_8_lsb 8 -#define xd_p_reg_ce_var_th5_7_0 0xABD6 -#define reg_ce_var_th5_7_0_pos 0 -#define reg_ce_var_th5_7_0_len 8 -#define reg_ce_var_th5_7_0_lsb 0 -#define xd_p_reg_ce_var_th5_15_8 0xABD7 -#define reg_ce_var_th5_15_8_pos 0 -#define reg_ce_var_th5_15_8_len 8 -#define reg_ce_var_th5_15_8_lsb 8 -#define xd_p_reg_ce_var_th6_7_0 0xABD8 -#define reg_ce_var_th6_7_0_pos 0 -#define reg_ce_var_th6_7_0_len 8 -#define reg_ce_var_th6_7_0_lsb 0 -#define xd_p_reg_ce_var_th6_15_8 0xABD9 -#define reg_ce_var_th6_15_8_pos 0 -#define reg_ce_var_th6_15_8_len 8 -#define reg_ce_var_th6_15_8_lsb 8 -#define xd_p_reg_ce_fctrl_reset 0xABDA -#define reg_ce_fctrl_reset_pos 0 -#define reg_ce_fctrl_reset_len 1 -#define reg_ce_fctrl_reset_lsb 0 -#define xd_p_reg_ce_cent_auto_clr_en 0xABDA -#define reg_ce_cent_auto_clr_en_pos 1 -#define reg_ce_cent_auto_clr_en_len 1 -#define reg_ce_cent_auto_clr_en_lsb 0 -#define xd_p_reg_ce_fctrl_auto_reset_en 0xABDA -#define reg_ce_fctrl_auto_reset_en_pos 2 -#define reg_ce_fctrl_auto_reset_en_len 1 -#define reg_ce_fctrl_auto_reset_en_lsb 0 -#define xd_p_reg_ce_var_forced_en 0xABDA -#define reg_ce_var_forced_en_pos 3 -#define reg_ce_var_forced_en_len 1 -#define reg_ce_var_forced_en_lsb 0 -#define xd_p_reg_ce_cent_forced_en 0xABDA -#define reg_ce_cent_forced_en_pos 4 -#define reg_ce_cent_forced_en_len 1 -#define reg_ce_cent_forced_en_lsb 0 -#define xd_p_reg_ce_var_max 0xABDA -#define reg_ce_var_max_pos 5 -#define reg_ce_var_max_len 3 -#define reg_ce_var_max_lsb 0 -#define xd_p_reg_ce_cent_forced_value_7_0 0xABDB -#define reg_ce_cent_forced_value_7_0_pos 0 -#define reg_ce_cent_forced_value_7_0_len 8 -#define reg_ce_cent_forced_value_7_0_lsb 0 -#define xd_p_reg_ce_cent_forced_value_11_8 0xABDC -#define reg_ce_cent_forced_value_11_8_pos 0 -#define reg_ce_cent_forced_value_11_8_len 4 -#define reg_ce_cent_forced_value_11_8_lsb 8 -#define xd_p_reg_ce_fctrl_rd 0xABDD -#define reg_ce_fctrl_rd_pos 0 -#define reg_ce_fctrl_rd_len 1 -#define reg_ce_fctrl_rd_lsb 0 -#define xd_p_reg_ce_centroid_max_6_0 0xABDD -#define reg_ce_centroid_max_6_0_pos 1 -#define reg_ce_centroid_max_6_0_len 7 -#define reg_ce_centroid_max_6_0_lsb 0 -#define xd_p_reg_ce_centroid_max_11_7 0xABDE -#define reg_ce_centroid_max_11_7_pos 0 -#define reg_ce_centroid_max_11_7_len 5 -#define reg_ce_centroid_max_11_7_lsb 7 -#define xd_p_reg_ce_var 0xABDF -#define reg_ce_var_pos 0 -#define reg_ce_var_len 3 -#define reg_ce_var_lsb 0 -#define xd_p_reg_ce_fctrl_rdy 0xABDF -#define reg_ce_fctrl_rdy_pos 3 -#define reg_ce_fctrl_rdy_len 1 -#define reg_ce_fctrl_rdy_lsb 0 -#define xd_p_reg_ce_centroid_out_3_0 0xABDF -#define reg_ce_centroid_out_3_0_pos 4 -#define reg_ce_centroid_out_3_0_len 4 -#define reg_ce_centroid_out_3_0_lsb 0 -#define xd_p_reg_ce_centroid_out_11_4 0xABE0 -#define reg_ce_centroid_out_11_4_pos 0 -#define reg_ce_centroid_out_11_4_len 8 -#define reg_ce_centroid_out_11_4_lsb 4 -#define xd_p_reg_ce_bias_7_0 0xABE1 -#define reg_ce_bias_7_0_pos 0 -#define reg_ce_bias_7_0_len 8 -#define reg_ce_bias_7_0_lsb 0 -#define xd_p_reg_ce_bias_11_8 0xABE2 -#define reg_ce_bias_11_8_pos 0 -#define reg_ce_bias_11_8_len 4 -#define reg_ce_bias_11_8_lsb 8 -#define xd_p_reg_ce_m1_3_0 0xABE2 -#define reg_ce_m1_3_0_pos 4 -#define reg_ce_m1_3_0_len 4 -#define reg_ce_m1_3_0_lsb 0 -#define xd_p_reg_ce_m1_11_4 0xABE3 -#define reg_ce_m1_11_4_pos 0 -#define reg_ce_m1_11_4_len 8 -#define reg_ce_m1_11_4_lsb 4 -#define xd_p_reg_ce_rh0_7_0 0xABE4 -#define reg_ce_rh0_7_0_pos 0 -#define reg_ce_rh0_7_0_len 8 -#define reg_ce_rh0_7_0_lsb 0 -#define xd_p_reg_ce_rh0_15_8 0xABE5 -#define reg_ce_rh0_15_8_pos 0 -#define reg_ce_rh0_15_8_len 8 -#define reg_ce_rh0_15_8_lsb 8 -#define xd_p_reg_ce_rh0_23_16 0xABE6 -#define reg_ce_rh0_23_16_pos 0 -#define reg_ce_rh0_23_16_len 8 -#define reg_ce_rh0_23_16_lsb 16 -#define xd_p_reg_ce_rh0_31_24 0xABE7 -#define reg_ce_rh0_31_24_pos 0 -#define reg_ce_rh0_31_24_len 8 -#define reg_ce_rh0_31_24_lsb 24 -#define xd_p_reg_ce_rh3_real_7_0 0xABE8 -#define reg_ce_rh3_real_7_0_pos 0 -#define reg_ce_rh3_real_7_0_len 8 -#define reg_ce_rh3_real_7_0_lsb 0 -#define xd_p_reg_ce_rh3_real_15_8 0xABE9 -#define reg_ce_rh3_real_15_8_pos 0 -#define reg_ce_rh3_real_15_8_len 8 -#define reg_ce_rh3_real_15_8_lsb 8 -#define xd_p_reg_ce_rh3_real_23_16 0xABEA -#define reg_ce_rh3_real_23_16_pos 0 -#define reg_ce_rh3_real_23_16_len 8 -#define reg_ce_rh3_real_23_16_lsb 16 -#define xd_p_reg_ce_rh3_real_31_24 0xABEB -#define reg_ce_rh3_real_31_24_pos 0 -#define reg_ce_rh3_real_31_24_len 8 -#define reg_ce_rh3_real_31_24_lsb 24 -#define xd_p_reg_ce_rh3_imag_7_0 0xABEC -#define reg_ce_rh3_imag_7_0_pos 0 -#define reg_ce_rh3_imag_7_0_len 8 -#define reg_ce_rh3_imag_7_0_lsb 0 -#define xd_p_reg_ce_rh3_imag_15_8 0xABED -#define reg_ce_rh3_imag_15_8_pos 0 -#define reg_ce_rh3_imag_15_8_len 8 -#define reg_ce_rh3_imag_15_8_lsb 8 -#define xd_p_reg_ce_rh3_imag_23_16 0xABEE -#define reg_ce_rh3_imag_23_16_pos 0 -#define reg_ce_rh3_imag_23_16_len 8 -#define reg_ce_rh3_imag_23_16_lsb 16 -#define xd_p_reg_ce_rh3_imag_31_24 0xABEF -#define reg_ce_rh3_imag_31_24_pos 0 -#define reg_ce_rh3_imag_31_24_len 8 -#define reg_ce_rh3_imag_31_24_lsb 24 -#define xd_p_reg_feq_fix_eh2_7_0 0xABF0 -#define reg_feq_fix_eh2_7_0_pos 0 -#define reg_feq_fix_eh2_7_0_len 8 -#define reg_feq_fix_eh2_7_0_lsb 0 -#define xd_p_reg_feq_fix_eh2_15_8 0xABF1 -#define reg_feq_fix_eh2_15_8_pos 0 -#define reg_feq_fix_eh2_15_8_len 8 -#define reg_feq_fix_eh2_15_8_lsb 8 -#define xd_p_reg_feq_fix_eh2_23_16 0xABF2 -#define reg_feq_fix_eh2_23_16_pos 0 -#define reg_feq_fix_eh2_23_16_len 8 -#define reg_feq_fix_eh2_23_16_lsb 16 -#define xd_p_reg_feq_fix_eh2_31_24 0xABF3 -#define reg_feq_fix_eh2_31_24_pos 0 -#define reg_feq_fix_eh2_31_24_len 8 -#define reg_feq_fix_eh2_31_24_lsb 24 -#define xd_p_reg_ce_m2_central_7_0 0xABF4 -#define reg_ce_m2_central_7_0_pos 0 -#define reg_ce_m2_central_7_0_len 8 -#define reg_ce_m2_central_7_0_lsb 0 -#define xd_p_reg_ce_m2_central_15_8 0xABF5 -#define reg_ce_m2_central_15_8_pos 0 -#define reg_ce_m2_central_15_8_len 8 -#define reg_ce_m2_central_15_8_lsb 8 -#define xd_p_reg_ce_fftshift 0xABF6 -#define reg_ce_fftshift_pos 0 -#define reg_ce_fftshift_len 4 -#define reg_ce_fftshift_lsb 0 -#define xd_p_reg_ce_fftshift1 0xABF6 -#define reg_ce_fftshift1_pos 4 -#define reg_ce_fftshift1_len 4 -#define reg_ce_fftshift1_lsb 0 -#define xd_p_reg_ce_fftshift2 0xABF7 -#define reg_ce_fftshift2_pos 0 -#define reg_ce_fftshift2_len 4 -#define reg_ce_fftshift2_lsb 0 -#define xd_p_reg_ce_top_mobile 0xABF7 -#define reg_ce_top_mobile_pos 4 -#define reg_ce_top_mobile_len 1 -#define reg_ce_top_mobile_lsb 0 -#define xd_p_reg_strong_sginal_detected 0xA2BC -#define reg_strong_sginal_detected_pos 2 -#define reg_strong_sginal_detected_len 1 -#define reg_strong_sginal_detected_lsb 0 - -#define XD_MP2IF_BASE 0xB000 -#define XD_MP2IF_CSR (0x00 + XD_MP2IF_BASE) -#define XD_MP2IF_DMX_CTRL (0x03 + XD_MP2IF_BASE) -#define XD_MP2IF_PID_IDX (0x04 + XD_MP2IF_BASE) -#define XD_MP2IF_PID_DATA_L (0x05 + XD_MP2IF_BASE) -#define XD_MP2IF_PID_DATA_H (0x06 + XD_MP2IF_BASE) -#define XD_MP2IF_MISC (0x07 + XD_MP2IF_BASE) - -extern struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d); -extern int af9005_read_ofdm_register(struct dvb_usb_device *d, u16 reg, - u8 * value); -extern int af9005_read_ofdm_registers(struct dvb_usb_device *d, u16 reg, - u8 * values, int len); -extern int af9005_write_ofdm_register(struct dvb_usb_device *d, u16 reg, - u8 value); -extern int af9005_write_ofdm_registers(struct dvb_usb_device *d, u16 reg, - u8 * values, int len); -extern int af9005_read_tuner_registers(struct dvb_usb_device *d, u16 reg, - u8 addr, u8 * values, int len); -extern int af9005_write_tuner_registers(struct dvb_usb_device *d, u16 reg, - u8 * values, int len); -extern int af9005_read_register_bits(struct dvb_usb_device *d, u16 reg, - u8 pos, u8 len, u8 * value); -extern int af9005_write_register_bits(struct dvb_usb_device *d, u16 reg, - u8 pos, u8 len, u8 value); -extern int af9005_send_command(struct dvb_usb_device *d, u8 command, - u8 * wbuf, int wlen, u8 * rbuf, int rlen); -extern int af9005_read_eeprom(struct dvb_usb_device *d, u8 address, - u8 * values, int len); -extern int af9005_tuner_attach(struct dvb_usb_adapter *adap); -extern int af9005_led_control(struct dvb_usb_device *d, int onoff); - -extern u8 regmask[8]; - -/* remote control decoder */ -extern int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, - u32 * event, int *state); -extern struct dvb_usb_rc_key af9005_rc_keys[]; -extern int af9005_rc_keys_size; - -#endif diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c deleted file mode 100644 index e1e9aa5c6b8..00000000000 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ /dev/null @@ -1,1497 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "af9015.h" -#include "af9013.h" -#include "mt2060.h" -#include "qt1010.h" -#include "tda18271.h" -#include "mxl5005s.h" -#if 0 -#include "mc44s80x.h" -#endif - -static int dvb_usb_af9015_debug; -module_param_named(debug, dvb_usb_af9015_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -static int dvb_usb_af9015_remote; -module_param_named(remote, dvb_usb_af9015_remote, int, 0644); -MODULE_PARM_DESC(remote, "select remote"); -static int dvb_usb_af9015_dual_mode; -module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644); -MODULE_PARM_DESC(dual_mode, "enable dual mode"); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static DEFINE_MUTEX(af9015_usb_mutex); - -static struct af9015_config af9015_config; -static struct dvb_usb_device_properties af9015_properties[2]; -static int af9015_properties_count = ARRAY_SIZE(af9015_properties); - -static struct af9013_config af9015_af9013_config[] = { - { - .demod_address = AF9015_I2C_DEMOD, - .output_mode = AF9013_OUTPUT_MODE_USB, - .api_version = { 0, 1, 9, 0 }, - .gpio[0] = AF9013_GPIO_HI, - .gpio[3] = AF9013_GPIO_TUNER_ON, - - }, { - .output_mode = AF9013_OUTPUT_MODE_SERIAL, - .api_version = { 0, 1, 9, 0 }, - .gpio[0] = AF9013_GPIO_TUNER_ON, - .gpio[1] = AF9013_GPIO_LO, - } -}; - -static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) -{ - int act_len, ret; - u8 buf[64]; - u8 write = 1; - u8 msg_len = 8; - static u8 seq; /* packet sequence number */ - - if (mutex_lock_interruptible(&af9015_usb_mutex) < 0) - return -EAGAIN; - - buf[0] = req->cmd; - buf[1] = seq++; - buf[2] = req->i2c_addr; - buf[3] = req->addr >> 8; - buf[4] = req->addr & 0xff; - buf[5] = req->mbox; - buf[6] = req->addr_len; - buf[7] = req->data_len; - - switch (req->cmd) { - case GET_CONFIG: - case BOOT: - case READ_MEMORY: - case RECONNECT_USB: - case GET_IR_CODE: - write = 0; - break; - case READ_I2C: - write = 0; - buf[2] |= 0x01; /* set I2C direction */ - case WRITE_I2C: - buf[0] = READ_WRITE_I2C; - break; - case WRITE_MEMORY: - if (((req->addr & 0xff00) == 0xff00) || - ((req->addr & 0xae00) == 0xae00)) - buf[0] = WRITE_VIRTUAL_MEMORY; - case WRITE_VIRTUAL_MEMORY: - case COPY_FIRMWARE: - case DOWNLOAD_FIRMWARE: - break; - default: - err("unknown command:%d", req->cmd); - ret = -1; - goto error_unlock; - } - - /* write requested */ - if (write) { - memcpy(&buf[8], req->data, req->data_len); - msg_len += req->data_len; - } - deb_xfer(">>> "); - debug_dump(buf, msg_len, deb_xfer); - - /* send req */ - ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len, - &act_len, AF9015_USB_TIMEOUT); - if (ret) - err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len); - else - if (act_len != msg_len) - ret = -1; /* all data is not send */ - if (ret) - goto error_unlock; - - /* no ack for those packets */ - if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) - goto exit_unlock; - - /* receive ack and data if read req */ - msg_len = 1 + 1 + req->data_len; /* seq + status + data len */ - ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len, - &act_len, AF9015_USB_TIMEOUT); - if (ret) { - err("recv bulk message failed:%d", ret); - ret = -1; - goto error_unlock; - } - - 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]); - ret = -1; - goto error_unlock; - } - - /* read request, copy returned data to return buf */ - if (!write) - memcpy(req->data, &buf[2], req->data_len); - -error_unlock: -exit_unlock: - mutex_unlock(&af9015_usb_mutex); - - return ret; -} - -static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req) -{ - return af9015_rw_udev(d->udev, req); -} - -static int af9015_write_regs(struct dvb_usb_device *d, u16 addr, u8 *val, - u8 len) -{ - struct req_t req = {WRITE_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, len, - val}; - return af9015_ctrl_msg(d, &req); -} - -static int af9015_write_reg(struct dvb_usb_device *d, u16 addr, u8 val) -{ - return af9015_write_regs(d, addr, &val, 1); -} - -static int af9015_read_reg(struct dvb_usb_device *d, u16 addr, u8 *val) -{ - struct req_t req = {READ_MEMORY, AF9015_I2C_DEMOD, addr, 0, 0, 1, val}; - return af9015_ctrl_msg(d, &req); -} - -static int af9015_write_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 val) -{ - struct req_t req = {WRITE_I2C, addr, reg, 1, 1, 1, &val}; - - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) - req.addr_len = 3; - - return af9015_ctrl_msg(d, &req); -} - -static int af9015_read_reg_i2c(struct dvb_usb_device *d, u8 addr, u16 reg, - u8 *val) -{ - struct req_t req = {READ_I2C, addr, reg, 0, 1, 1, val}; - - if (addr == af9015_af9013_config[0].demod_address || - addr == af9015_af9013_config[1].demod_address) - req.addr_len = 3; - - return af9015_ctrl_msg(d, &req); -} - -static int af9015_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0, i = 0; - u16 addr; - u8 mbox, addr_len; - struct req_t req; - -/* TODO: implement bus lock - -The bus lock is needed because there is two tuners both using same I2C-address. -Due to that the only way to select correct tuner is use demodulator I2C-gate. - -................................................ -. AF9015 includes integrated AF9013 demodulator. -. ____________ ____________ . ____________ -.| uC | | demod | . | tuner | -.|------------| |------------| . |------------| -.| AF9015 | | AF9013/5 | . | MXL5003 | -.| |--+----I2C-------|-----/ -----|-.-----I2C-------| | -.| | | | addr 0x38 | . | addr 0xc6 | -.|____________| | |____________| . |____________| -.................|.............................. - | ____________ ____________ - | | demod | | tuner | - | |------------| |------------| - | | AF9013 | | MXL5003 | - +----I2C-------|-----/ -----|-------I2C-------| | - | addr 0x3a | | addr 0xc6 | - |____________| |____________| -*/ - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - while (i < num) { - if (msg[i].addr == af9015_af9013_config[0].demod_address || - msg[i].addr == af9015_af9013_config[1].demod_address) { - addr = msg[i].buf[0] << 8; - addr += msg[i].buf[1]; - mbox = msg[i].buf[2]; - addr_len = 3; - } else { - addr = msg[i].buf[0]; - addr_len = 1; - mbox = 0; - } - - if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { - if (msg[i].addr == - af9015_af9013_config[0].demod_address) - req.cmd = READ_MEMORY; - else - req.cmd = READ_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i+1].len; - req.data = &msg[i+1].buf[0]; - ret = af9015_ctrl_msg(d, &req); - i += 2; - } else { - if (msg[i].addr == - af9015_af9013_config[0].demod_address) - req.cmd = WRITE_MEMORY; - else - req.cmd = WRITE_I2C; - req.i2c_addr = msg[i].addr; - req.addr = addr; - req.mbox = mbox; - req.addr_len = addr_len; - req.data_len = msg[i].len-addr_len; - req.data = &msg[i].buf[addr_len]; - ret = af9015_ctrl_msg(d, &req); - i += 1; - } - if (ret) - goto error; - - } - ret = i; - -error: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -static u32 af9015_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm af9015_i2c_algo = { - .master_xfer = af9015_i2c_xfer, - .functionality = af9015_i2c_func, -}; - -static int af9015_do_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit, u8 op) -{ - int ret; - u8 val, mask = 0x01; - - ret = af9015_read_reg(d, addr, &val); - if (ret) - return ret; - - mask <<= bit; - if (op) { - /* set bit */ - val |= mask; - } else { - /* clear bit */ - mask ^= 0xff; - val &= mask; - } - - return af9015_write_reg(d, addr, val); -} - -static int af9015_set_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 1); -} - -static int af9015_clear_reg_bit(struct dvb_usb_device *d, u16 addr, u8 bit) -{ - return af9015_do_reg_bit(d, addr, bit, 0); -} - -static int af9015_init_endpoint(struct dvb_usb_device *d) -{ - int ret; - u16 frame_size; - u8 packet_size; - deb_info("%s: USB speed:%d\n", __func__, d->udev->speed); - -#define TS_PACKET_SIZE 188 - -#define TS_USB20_PACKET_COUNT 348 -#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT) - -#define TS_USB11_PACKET_COUNT 21 -#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT) - -#define TS_USB20_MAX_PACKET_SIZE 512 -#define TS_USB11_MAX_PACKET_SIZE 64 - - if (d->udev->speed == USB_SPEED_FULL) { - frame_size = TS_USB11_FRAME_SIZE/4; - packet_size = TS_USB11_MAX_PACKET_SIZE/4; - } else { - frame_size = TS_USB20_FRAME_SIZE/4; - packet_size = TS_USB20_MAX_PACKET_SIZE/4; - } - - ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */ - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */ - if (ret) - goto error; - ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */ - if (ret) - goto error; - if (af9015_config.dual_mode) { - ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */ - if (ret) - goto error; - } - ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */ - if (ret) - goto error; - if (af9015_config.dual_mode) { - ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */ - if (ret) - goto error; - } - /* EP4 xfer length */ - ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd89, frame_size >> 8); - if (ret) - goto error; - /* EP5 xfer length */ - ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8); - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */ - if (ret) - goto error; - ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */ - if (ret) - goto error; - ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */ - if (ret) - goto error; - if (af9015_config.dual_mode) { - ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */ - if (ret) - goto error; - } - - /* enable / disable mp2if2 */ - if (af9015_config.dual_mode) - ret = af9015_set_reg_bit(d, 0xd50b, 0); - else - ret = af9015_clear_reg_bit(d, 0xd50b, 0); -error: - if (ret) - err("endpoint init failed:%d", ret); - return ret; -} - -static int af9015_copy_firmware(struct dvb_usb_device *d) -{ - int ret; - u8 fw_params[4]; - u8 val, i; - struct req_t req = {COPY_FIRMWARE, 0, 0x5100, 0, 0, sizeof(fw_params), - fw_params }; - deb_info("%s:\n", __func__); - - fw_params[0] = af9015_config.firmware_size >> 8; - fw_params[1] = af9015_config.firmware_size & 0xff; - fw_params[2] = af9015_config.firmware_checksum >> 8; - fw_params[3] = af9015_config.firmware_checksum & 0xff; - - /* wait 2nd demodulator ready */ - msleep(100); - - ret = af9015_read_reg_i2c(d, 0x3a, 0x98be, &val); - if (ret) - goto error; - else - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; - - /* set I2C master clock to fast (to speed up firmware copy) */ - ret = af9015_write_reg(d, 0xd416, 0x04); /* 0x04 * 400ns */ - if (ret) - goto error; - - msleep(50); - - /* copy firmware */ - ret = af9015_ctrl_msg(d, &req); - if (ret) - err("firmware copy cmd failed:%d", ret); - deb_info("%s: firmware copy done\n", __func__); - - /* set I2C master clock back to normal */ - ret = af9015_write_reg(d, 0xd416, 0x14); /* 0x14 * 400ns */ - if (ret) - goto error; - - /* request boot firmware */ - ret = af9015_write_reg_i2c(d, af9015_af9013_config[1].demod_address, - 0xe205, 1); - deb_info("%s: firmware boot cmd status:%d\n", __func__, ret); - if (ret) - goto error; - - for (i = 0; i < 15; i++) { - msleep(100); - - /* check firmware status */ - ret = af9015_read_reg_i2c(d, - af9015_af9013_config[1].demod_address, 0x98be, &val); - deb_info("%s: firmware status cmd status:%d fw status:%02x\n", - __func__, ret, val); - if (ret) - goto error; - - if (val == 0x0c || val == 0x04) /* success or fail */ - break; - } - - if (val == 0x04) { - err("firmware did not run"); - ret = -1; - } else if (val != 0x0c) { - err("firmware boot timeout"); - ret = -1; - } - -error: -exit: - return ret; -} - -/* dump eeprom */ -static int af9015_eeprom_dump(struct dvb_usb_device *d) -{ - char buf[52], buf2[4]; - u8 reg, val; - - for (reg = 0; ; reg++) { - if (reg % 16 == 0) { - if (reg) - deb_info("%s\n", buf); - sprintf(buf, "%02x: ", reg); - } - if (af9015_read_reg_i2c(d, AF9015_I2C_EEPROM, reg, &val) == 0) - sprintf(buf2, "%02x ", val); - else - strcpy(buf2, "-- "); - strcat(buf, buf2); - if (reg == 0xff) - break; - } - deb_info("%s\n", buf); - return 0; -} - -static int af9015_download_ir_table(struct dvb_usb_device *d) -{ - int i, packets = 0, ret; - u16 addr = 0x9a56; /* ir-table start address */ - struct req_t req = {WRITE_MEMORY, 0, 0, 0, 0, 1, NULL}; - u8 *data = NULL; - deb_info("%s:\n", __func__); - - data = af9015_config.ir_table; - packets = af9015_config.ir_table_size; - - /* no remote */ - if (!packets) - goto exit; - - /* load remote ir-table */ - for (i = 0; i < packets; i++) { - req.addr = addr + i; - req.data = &data[i]; - ret = af9015_ctrl_msg(d, &req); - if (ret) { - err("ir-table download failed at packet %d with " \ - "code %d", i, ret); - return ret; - } - } - -exit: - return 0; -} - -static int af9015_init(struct dvb_usb_device *d) -{ - int ret; - deb_info("%s:\n", __func__); - - ret = af9015_init_endpoint(d); - if (ret) - goto error; - - ret = af9015_download_ir_table(d); - if (ret) - goto error; - -error: - return ret; -} - -static int af9015_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); - - if (onoff) - ret = af9015_set_reg_bit(adap->dev, 0xd503, 0); - else - ret = af9015_clear_reg_bit(adap->dev, 0xd503, 0); - - return ret; -} - -static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, - int onoff) -{ - int ret; - u8 idx; - - deb_info("%s: set pid filter, index %d, pid %x, onoff %d\n", - __func__, index, pid, onoff); - - ret = af9015_write_reg(adap->dev, 0xd505, (pid & 0xff)); - if (ret) - goto error; - - ret = af9015_write_reg(adap->dev, 0xd506, (pid >> 8)); - if (ret) - goto error; - - idx = ((index & 0x1f) | (1 << 5)); - ret = af9015_write_reg(adap->dev, 0xd504, idx); - -error: - return ret; -} - -static int af9015_download_firmware(struct usb_device *udev, - const struct firmware *fw) -{ - int i, len, packets, remainder, ret; - struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; - u16 addr = 0x5100; /* firmware start address */ - u16 checksum = 0; - - deb_info("%s:\n", __func__); - - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; - - af9015_config.firmware_size = fw->size; - af9015_config.firmware_checksum = checksum; - - #define FW_PACKET_MAX_DATA 55 - - packets = fw->size / FW_PACKET_MAX_DATA; - remainder = fw->size % FW_PACKET_MAX_DATA; - len = FW_PACKET_MAX_DATA; - for (i = 0; i <= packets; i++) { - if (i == packets) /* set size of the last packet */ - len = remainder; - - req.data_len = len; - req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); - req.addr = addr; - addr += FW_PACKET_MAX_DATA; - - ret = af9015_rw_udev(udev, &req); - if (ret) { - err("firmware download failed at packet %d with " \ - "code %d", i, ret); - goto error; - } - } - - /* firmware loaded, request boot */ - req.cmd = BOOT; - ret = af9015_rw_udev(udev, &req); - if (ret) { - err("firmware boot failed:%d", ret); - goto error; - } - -error: - return ret; -} - -static int af9015_read_config(struct usb_device *udev) -{ - int ret; - u8 val, i, offset = 0; - struct req_t req = {READ_I2C, AF9015_I2C_EEPROM, 0, 0, 1, 1, &val}; - char manufacturer[10]; - - /* IR remote controller */ - req.addr = AF9015_EEPROM_IR_MODE; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - deb_info("%s: IR mode:%d\n", __func__, val); - for (i = 0; i < af9015_properties_count; i++) { - if (val == AF9015_IR_MODE_DISABLED || val == 0x04) { - af9015_properties[i].rc_key_map = NULL; - af9015_properties[i].rc_key_map_size = 0; - } else if (dvb_usb_af9015_remote) { - /* load remote defined as module param */ - switch (dvb_usb_af9015_remote) { - case AF9015_REMOTE_A_LINK_DTU_M: - af9015_properties[i].rc_key_map = - af9015_rc_keys_a_link; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_a_link); - af9015_config.ir_table = af9015_ir_table_a_link; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_a_link); - break; - case AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3: - af9015_properties[i].rc_key_map = - af9015_rc_keys_msi; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_msi); - af9015_config.ir_table = af9015_ir_table_msi; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_msi); - break; - case AF9015_REMOTE_MYGICTV_U718: - af9015_properties[i].rc_key_map = - af9015_rc_keys_mygictv; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_mygictv); - af9015_config.ir_table = - af9015_ir_table_mygictv; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_mygictv); - break; - case AF9015_REMOTE_DIGITTRADE_DVB_T: - af9015_properties[i].rc_key_map = - af9015_rc_keys_digittrade; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_digittrade); - af9015_config.ir_table = - af9015_ir_table_digittrade; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_digittrade); - break; - } - } else { - switch (le16_to_cpu(udev->descriptor.idVendor)) { - case USB_VID_LEADTEK: - af9015_properties[i].rc_key_map = - af9015_rc_keys_leadtek; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_leadtek); - af9015_config.ir_table = - af9015_ir_table_leadtek; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_leadtek); - break; - case USB_VID_VISIONPLUS: - if (udev->descriptor.idProduct == - cpu_to_le16(USB_PID_AZUREWAVE_AD_TU700)) { - af9015_properties[i].rc_key_map = - af9015_rc_keys_twinhan; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_twinhan); - af9015_config.ir_table = - af9015_ir_table_twinhan; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_twinhan); - } - break; - case USB_VID_KWORLD_2: - /* TODO: use correct rc keys */ - af9015_properties[i].rc_key_map = - af9015_rc_keys_twinhan; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_twinhan); - af9015_config.ir_table = af9015_ir_table_kworld; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_kworld); - break; - /* Check USB manufacturer and product strings and try - to determine correct remote in case of chip vendor - reference IDs are used. */ - case USB_VID_AFATECH: - memset(manufacturer, 0, sizeof(manufacturer)); - usb_string(udev, udev->descriptor.iManufacturer, - manufacturer, sizeof(manufacturer)); - if (!strcmp("Geniatech", manufacturer)) { - /* iManufacturer 1 Geniatech - iProduct 2 AF9015 */ - af9015_properties[i].rc_key_map = - af9015_rc_keys_mygictv; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_mygictv); - af9015_config.ir_table = - af9015_ir_table_mygictv; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_mygictv); - } else if (!strcmp("MSI", manufacturer)) { - /* iManufacturer 1 MSI - iProduct 2 MSI K-VOX */ - af9015_properties[i].rc_key_map = - af9015_rc_keys_msi; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_msi); - af9015_config.ir_table = - af9015_ir_table_msi; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_msi); - } - break; - case USB_VID_AVERMEDIA: - af9015_properties[i].rc_key_map = - af9015_rc_keys_avermedia; - af9015_properties[i].rc_key_map_size = - ARRAY_SIZE(af9015_rc_keys_avermedia); - af9015_config.ir_table = - af9015_ir_table_avermedia; - af9015_config.ir_table_size = - ARRAY_SIZE(af9015_ir_table_avermedia); - break; - } - } - } - - /* TS mode - one or two receivers */ - req.addr = AF9015_EEPROM_TS_MODE; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_config.dual_mode = val; - deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode); - /* disable dual mode by default because it is buggy */ - if (!dvb_usb_af9015_dual_mode) - af9015_config.dual_mode = 0; - - /* set buffer size according to USB port speed */ - 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->stream.u.bulk.buffersize = - TS_USB11_MAX_PACKET_SIZE; - /* disable 2nd adapter because we don't have - PID-filters */ - af9015_config.dual_mode = 0; - } else { - af9015_properties[i].adapter->stream.u.bulk.buffersize = - TS_USB20_MAX_PACKET_SIZE; - } - } - - if (af9015_config.dual_mode) { - /* read 2nd demodulator I2C address */ - req.addr = AF9015_EEPROM_DEMOD2_I2C; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_af9013_config[1].demod_address = val; - - /* enable 2nd adapter */ - for (i = 0; i < af9015_properties_count; i++) - af9015_properties[i].num_adapters = 2; - - } else { - /* disable 2nd adapter */ - for (i = 0; i < af9015_properties_count; i++) - af9015_properties[i].num_adapters = 1; - } - - for (i = 0; i < af9015_properties[0].num_adapters; i++) { - if (i == 1) - offset = AF9015_EEPROM_OFFSET; - /* xtal */ - req.addr = AF9015_EEPROM_XTAL_TYPE1 + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - switch (val) { - case 0: - af9015_af9013_config[i].adc_clock = 28800; - break; - case 1: - af9015_af9013_config[i].adc_clock = 20480; - break; - case 2: - af9015_af9013_config[i].adc_clock = 28000; - break; - case 3: - af9015_af9013_config[i].adc_clock = 25000; - break; - }; - deb_info("%s: [%d] xtal:%d set adc_clock:%d\n", __func__, i, - val, af9015_af9013_config[i].adc_clock); - - /* tuner IF */ - req.addr = AF9015_EEPROM_IF1H + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_af9013_config[i].tuner_if = val << 8; - req.addr = AF9015_EEPROM_IF1L + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_af9013_config[i].tuner_if += val; - deb_info("%s: [%d] IF1:%d\n", __func__, i, - af9015_af9013_config[0].tuner_if); - - /* MT2060 IF1 */ - req.addr = AF9015_EEPROM_MT2060_IF1H + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_config.mt2060_if1[i] = val << 8; - req.addr = AF9015_EEPROM_MT2060_IF1L + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - af9015_config.mt2060_if1[i] += val; - deb_info("%s: [%d] MT2060 IF1:%d\n", __func__, i, - af9015_config.mt2060_if1[i]); - - /* tuner */ - req.addr = AF9015_EEPROM_TUNER_ID1 + offset; - ret = af9015_rw_udev(udev, &req); - if (ret) - goto error; - switch (val) { - case AF9013_TUNER_ENV77H11D5: - case AF9013_TUNER_MT2060: - case AF9013_TUNER_MC44S803: - case AF9013_TUNER_QT1010: - case AF9013_TUNER_UNKNOWN: - case AF9013_TUNER_MT2060_2: - case AF9013_TUNER_TDA18271: - case AF9013_TUNER_QT1010A: - af9015_af9013_config[i].rf_spec_inv = 1; - break; - case AF9013_TUNER_MXL5003D: - case AF9013_TUNER_MXL5005D: - case AF9013_TUNER_MXL5005R: - af9015_af9013_config[i].rf_spec_inv = 0; - break; - default: - warn("tuner id:%d not supported, please report!", val); - return -ENODEV; - }; - - af9015_af9013_config[i].tuner = val; - deb_info("%s: [%d] tuner id:%d\n", __func__, i, val); - } - -error: - if (ret) - err("eeprom read failed:%d", ret); - - return ret; -} - -static int af9015_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - int ret; - u8 reply; - struct req_t req = {GET_CONFIG, 0, 0, 0, 0, 1, &reply}; - - ret = af9015_rw_udev(udev, &req); - if (ret) - return ret; - - deb_info("%s: reply:%02x\n", __func__, reply); - if (reply == 0x02) - *cold = 0; - else - *cold = 1; - - return ret; -} - -static int af9015_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 buf[8]; - struct req_t req = {GET_IR_CODE, 0, 0, 0, 0, sizeof(buf), buf}; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - int i, ret; - - memset(buf, 0, sizeof(buf)); - - ret = af9015_ctrl_msg(d, &req); - if (ret) - return ret; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (!buf[1] && keymap[i].custom == buf[0] && - keymap[i].data == buf[2]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - break; - } - } - if (!buf[1]) - deb_rc("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", - __func__, buf[0], buf[1], buf[2], buf[3], buf[4], - buf[5], buf[6], buf[7]); - - return 0; -} - -/* 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)); -#ifdef I2C_ADAP_CLASS_TV_DIGITAL - state->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, -#else - state->i2c_adap.class = I2C_CLASS_TV_DIGITAL, -#endif - 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); - - /* dump eeprom (debug) */ - ret = af9015_eeprom_dump(adap->dev); - if (ret) - return ret; - } else { - /* select I2C adapter */ - i2c_adap = &state->i2c_adap; - - /* copy firmware to 2nd demodulator */ - if (af9015_config.dual_mode) { - ret = af9015_copy_firmware(adap->dev); - if (ret) { - err("firmware copy to 2nd frontend " \ - "failed, will disable it"); - af9015_config.dual_mode = 0; - return -ENODEV; - } - } else { - return -ENODEV; - } - } - - /* attach demodulator */ - adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], - i2c_adap); - - return adap->fe == NULL ? -ENODEV : 0; -} - -static struct mt2060_config af9015_mt2060_config = { - .i2c_address = 0xc0, - .clock_out = 0, -}; - -static struct qt1010_config af9015_qt1010_config = { - .i2c_address = 0xc4, -}; - -static struct tda18271_config af9015_tda18271_config = { - .gate = TDA18271_GATE_DIGITAL, - .small_i2c = 1, -}; - -static struct mxl5005s_config af9015_mxl5003_config = { - .i2c_address = 0xc6, - .if_freq = IF_FREQ_4570000HZ, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_DEFAULT, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -static struct mxl5005s_config af9015_mxl5005_config = { - .i2c_address = 0xc6, - .if_freq = IF_FREQ_4570000HZ, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_OFF, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -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, - &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, - &af9015_qt1010_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_TDA18271: - ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, - &af9015_tda18271_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_MXL5003D: - ret = dvb_attach(mxl5005s_attach, adap->fe, 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, - &af9015_mxl5005_config) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_ENV77H11D5: - ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0, i2c_adap, - DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; - break; - case AF9013_TUNER_MC44S803: -#if 0 - ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap) - == NULL ? -ENODEV : 0; -#else - ret = -ENODEV; - info("Freescale MC44S803 tuner found but no driver for that" \ - "tuner. Look at the Linuxtv.org for tuner driver" \ - "status."); -#endif - break; - case AF9013_TUNER_UNKNOWN: - default: - ret = -ENODEV; - err("Unknown tuner id:%d", - af9015_af9013_config[adap->id].tuner); - } - return ret; -} - -static struct usb_device_id af9015_usb_table[] = { -/* 0 */{USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9015)}, - {USB_DEVICE(USB_VID_AFATECH, USB_PID_AFATECH_AF9015_9016)}, - {USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_GOLD)}, - {USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV71E)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_399U)}, -/* 5 */{USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_TINYTWIN)}, - {USB_DEVICE(USB_VID_VISIONPLUS, - USB_PID_AZUREWAVE_AD_TU700)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_PC160_2T)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X)}, -/* 10 */{USB_DEVICE(USB_VID_XTENSIONS, USB_PID_XTENSIONS_XD_380)}, - {USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGIVOX_DUO)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_X_2)}, - {USB_DEVICE(USB_VID_TELESTAR, USB_PID_TELESTAR_STARSTICK_2)}, - {USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)}, -/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)}, - {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)}, - {0}, -}; -MODULE_DEVICE_TABLE(usb, af9015_usb_table); - -static struct dvb_usb_device_properties af9015_properties[] = { - { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .download_firmware = af9015_download_firmware, - .firmware = "dvb-usb-af9015.fw", - .no_reconnect = 1, - - .size_of_priv = sizeof(struct af9015_state), \ - - .num_adapters = 2, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 32, - .pid_filter = af9015_pid_filter, - .pid_filter_ctrl = af9015_pid_filter_ctrl, - - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x84, - }, - }, - { - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x85, - }, - } - }, - - .identify_state = af9015_identify_state, - - .rc_query = af9015_rc_query, - .rc_interval = 150, - - .i2c_algo = &af9015_i2c_algo, - - .num_device_descs = 9, - .devices = { - { - .name = "Afatech AF9015 DVB-T USB2.0 stick", - .cold_ids = {&af9015_usb_table[0], - &af9015_usb_table[1], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Leadtek WinFast DTV Dongle Gold", - .cold_ids = {&af9015_usb_table[2], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Pinnacle PCTV 71e", - .cold_ids = {&af9015_usb_table[3], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "KWorld PlusTV Dual DVB-T Stick " \ - "(DVB-T 399U)", - .cold_ids = {&af9015_usb_table[4], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "DigitalNow TinyTwin DVB-T Receiver", - .cold_ids = {&af9015_usb_table[5], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "TwinHan AzureWave AD-TU700(704J)", - .cold_ids = {&af9015_usb_table[6], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "TerraTec Cinergy T USB XE", - .cold_ids = {&af9015_usb_table[7], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "KWorld PlusTV Dual DVB-T PCI " \ - "(DVB-T PC160-2T)", - .cold_ids = {&af9015_usb_table[8], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "AVerMedia AVerTV DVB-T Volar X", - .cold_ids = {&af9015_usb_table[9], NULL}, - .warm_ids = {NULL}, - }, - } - }, { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .download_firmware = af9015_download_firmware, - .firmware = "dvb-usb-af9015.fw", - .no_reconnect = 1, - - .size_of_priv = sizeof(struct af9015_state), \ - - .num_adapters = 2, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 32, - .pid_filter = af9015_pid_filter, - .pid_filter_ctrl = af9015_pid_filter_ctrl, - - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x84, - }, - }, - { - .frontend_attach = - af9015_af9013_frontend_attach, - .tuner_attach = af9015_tuner_attach, - .stream = { - .type = USB_BULK, - .count = 6, - .endpoint = 0x85, - }, - } - }, - - .identify_state = af9015_identify_state, - - .rc_query = af9015_rc_query, - .rc_interval = 150, - - .i2c_algo = &af9015_i2c_algo, - - .num_device_descs = 7, - .devices = { - { - .name = "Xtensions XD-380", - .cold_ids = {&af9015_usb_table[10], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "MSI DIGIVOX Duo", - .cold_ids = {&af9015_usb_table[11], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Fujitsu-Siemens Slim Mobile USB DVB-T", - .cold_ids = {&af9015_usb_table[12], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "Telestar Starstick 2", - .cold_ids = {&af9015_usb_table[13], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "AVerMedia A309", - .cold_ids = {&af9015_usb_table[14], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "MSI Digi VOX mini III", - .cold_ids = {&af9015_usb_table[15], NULL}, - .warm_ids = {NULL}, - }, - { - .name = "KWorld USB DVB-T TV Stick II " \ - "(VS-DVB-T 395U)", - .cold_ids = {&af9015_usb_table[16], NULL}, - .warm_ids = {NULL}, - }, - } - } -}; - -static int af9015_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int ret = 0; - struct dvb_usb_device *d = NULL; - struct usb_device *udev = interface_to_usbdev(intf); - u8 i; - - deb_info("%s: interface:%d\n", __func__, - intf->cur_altsetting->desc.bInterfaceNumber); - - /* interface 0 is used by DVB-T receiver and - interface 1 is for remote controller (HID) */ - if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { - ret = af9015_read_config(udev); - if (ret) - return ret; - - for (i = 0; i < af9015_properties_count; i++) { - ret = dvb_usb_device_init(intf, &af9015_properties[i], - THIS_MODULE, &d, adapter_nr); - if (!ret) - break; - if (ret != -ENODEV) - return ret; - } - if (ret) - return ret; - - if (d) - ret = af9015_init(d); - } - - 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, - .id_table = af9015_usb_table, -}; - -/* module stuff */ -static int __init af9015_usb_module_init(void) -{ - int ret; - ret = usb_register(&af9015_usb_driver); - if (ret) - err("module init failed:%d", ret); - - return ret; -} - -static void __exit af9015_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&af9015_usb_driver); -} - -module_init(af9015_usb_module_init); -module_exit(af9015_usb_module_exit); - -MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); -MODULE_DESCRIPTION("Driver for Afatech AF9015 DVB-T"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h deleted file mode 100644 index 21c7782f488..00000000000 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ /dev/null @@ -1,663 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _DVB_USB_AF9015_H_ -#define _DVB_USB_AF9015_H_ - -#define DVB_USB_LOG_PREFIX "af9015" -#include "dvb-usb.h" - -#define deb_info(args...) dprintk(dvb_usb_af9015_debug, 0x01, args) -#define deb_rc(args...) dprintk(dvb_usb_af9015_debug, 0x02, args) -#define deb_xfer(args...) dprintk(dvb_usb_af9015_debug, 0x04, args) -#define deb_reg(args...) dprintk(dvb_usb_af9015_debug, 0x08, args) -#define deb_i2c(args...) dprintk(dvb_usb_af9015_debug, 0x10, args) -#define deb_fw(args...) dprintk(dvb_usb_af9015_debug, 0x20, args) - -#define AF9015_I2C_EEPROM 0xa0 -#define AF9015_I2C_DEMOD 0x38 -#define AF9015_USB_TIMEOUT 2000 - -/* EEPROM locations */ -#define AF9015_EEPROM_IR_MODE 0x18 -#define AF9015_EEPROM_IR_REMOTE_TYPE 0x34 -#define AF9015_EEPROM_TS_MODE 0x31 -#define AF9015_EEPROM_DEMOD2_I2C 0x32 - -#define AF9015_EEPROM_SAW_BW1 0x35 -#define AF9015_EEPROM_XTAL_TYPE1 0x36 -#define AF9015_EEPROM_SPEC_INV1 0x37 -#define AF9015_EEPROM_IF1L 0x38 -#define AF9015_EEPROM_IF1H 0x39 -#define AF9015_EEPROM_MT2060_IF1L 0x3a -#define AF9015_EEPROM_MT2060_IF1H 0x3b -#define AF9015_EEPROM_TUNER_ID1 0x3c - -#define AF9015_EEPROM_SAW_BW2 0x45 -#define AF9015_EEPROM_XTAL_TYPE2 0x46 -#define AF9015_EEPROM_SPEC_INV2 0x47 -#define AF9015_EEPROM_IF2L 0x48 -#define AF9015_EEPROM_IF2H 0x49 -#define AF9015_EEPROM_MT2060_IF2L 0x4a -#define AF9015_EEPROM_MT2060_IF2H 0x4b -#define AF9015_EEPROM_TUNER_ID2 0x4c - -#define AF9015_EEPROM_OFFSET (AF9015_EEPROM_SAW_BW2 - AF9015_EEPROM_SAW_BW1) - -#define AF9015_GPIO_ON (1 << 0) -#define AF9015_GPIO_EN (1 << 1) -#define AF9015_GPIO_O (1 << 2) -#define AF9015_GPIO_I (1 << 3) - -#define AF9015_GPIO_TUNER_ON (AF9015_GPIO_ON|AF9015_GPIO_EN) -#define AF9015_GPIO_TUNER_OFF (AF9015_GPIO_ON|AF9015_GPIO_EN|AF9015_GPIO_O) - -struct req_t { - u8 cmd; /* [0] */ - /* seq */ /* [1] */ - u8 i2c_addr; /* [2] */ - u16 addr; /* [3|4] */ - u8 mbox; /* [5] */ - u8 addr_len; /* [6] */ - u8 data_len; /* [7] */ - u8 *data; -}; - -enum af9015_cmd { - GET_CONFIG = 0x10, - DOWNLOAD_FIRMWARE = 0x11, - BOOT = 0x13, - READ_MEMORY = 0x20, - WRITE_MEMORY = 0x21, - READ_WRITE_I2C = 0x22, - COPY_FIRMWARE = 0x23, - RECONNECT_USB = 0x5a, - WRITE_VIRTUAL_MEMORY = 0x26, - GET_IR_CODE = 0x27, - READ_I2C, - WRITE_I2C, -}; - -enum af9015_ir_mode { - AF9015_IR_MODE_DISABLED = 0, - AF9015_IR_MODE_HID, - AF9015_IR_MODE_RLC, - AF9015_IR_MODE_RC6, -}; - -struct af9015_state { - struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ -}; - -struct af9015_config { - u8 dual_mode:1; - u16 mt2060_if1[2]; - u16 firmware_size; - u16 firmware_checksum; - u8 *ir_table; - u16 ir_table_size; -}; - -enum af9015_remote { - AF9015_REMOTE_NONE = 0, - AF9015_REMOTE_A_LINK_DTU_M, - AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3, - AF9015_REMOTE_MYGICTV_U718, - AF9015_REMOTE_DIGITTRADE_DVB_T, -}; - -/* Leadtek WinFast DTV Dongle Gold */ -static struct dvb_usb_rc_key af9015_rc_keys_leadtek[] = { - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x28, KEY_ENTER }, - { 0x00, 0x4f, KEY_VOLUMEUP }, - { 0x00, 0x50, KEY_VOLUMEDOWN }, - { 0x00, 0x51, KEY_CHANNELDOWN }, - { 0x00, 0x52, KEY_CHANNELUP }, -}; - -static u8 af9015_ir_table_leadtek[] = { - 0x03, 0xfc, 0x00, 0xff, 0x1a, 0x01, 0x00, - 0x03, 0xfc, 0x56, 0xa9, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4b, 0xb4, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4c, 0xb3, 0xb2, 0x04, 0x00, - 0x03, 0xfc, 0x4d, 0xb2, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x4e, 0xb1, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x1f, 0xe0, 0x3d, 0x00, 0x00, - 0x03, 0xfc, 0x40, 0xbf, 0x13, 0x01, 0x00, - 0x03, 0xfc, 0x14, 0xeb, 0x10, 0x00, 0x00, - 0x03, 0xfc, 0x49, 0xb6, 0x05, 0x01, 0x00, - 0x03, 0xfc, 0x50, 0xaf, 0x29, 0x00, 0x00, - 0x03, 0xfc, 0x0c, 0xf3, 0x52, 0x00, 0x00, - 0x03, 0xfc, 0x03, 0xfc, 0x09, 0x00, 0x00, - 0x03, 0xfc, 0x08, 0xf7, 0x50, 0x00, 0x00, - 0x03, 0xfc, 0x13, 0xec, 0x28, 0x00, 0x00, - 0x03, 0xfc, 0x04, 0xfb, 0x4f, 0x00, 0x00, - 0x03, 0xfc, 0x4f, 0xb0, 0x0f, 0x01, 0x00, - 0x03, 0xfc, 0x10, 0xef, 0x51, 0x00, 0x00, - 0x03, 0xfc, 0x51, 0xae, 0x3f, 0x00, 0x00, - 0x03, 0xfc, 0x42, 0xbd, 0x13, 0x00, 0x00, - 0x03, 0xfc, 0x43, 0xbc, 0x00, 0x00, 0x00, - 0x03, 0xfc, 0x44, 0xbb, 0x11, 0x00, 0x00, - 0x03, 0xfc, 0x52, 0xad, 0x19, 0x00, 0x00, - 0x03, 0xfc, 0x54, 0xab, 0x05, 0x00, 0x00, - 0x03, 0xfc, 0x46, 0xb9, 0x29, 0x00, 0x00, - 0x03, 0xfc, 0x55, 0xaa, 0x2b, 0x00, 0x00, - 0x03, 0xfc, 0x53, 0xac, 0x41, 0x00, 0x00, - 0x03, 0xfc, 0x05, 0xfa, 0x1e, 0x00, 0x00, - 0x03, 0xfc, 0x06, 0xf9, 0x1f, 0x00, 0x00, - 0x03, 0xfc, 0x07, 0xf8, 0x20, 0x00, 0x00, - 0x03, 0xfc, 0x1e, 0xe1, 0x19, 0x00, 0x00, - 0x03, 0xfc, 0x09, 0xf6, 0x21, 0x00, 0x00, - 0x03, 0xfc, 0x0a, 0xf5, 0x22, 0x00, 0x00, - 0x03, 0xfc, 0x0b, 0xf4, 0x23, 0x00, 0x00, - 0x03, 0xfc, 0x1b, 0xe4, 0x16, 0x00, 0x00, - 0x03, 0xfc, 0x0d, 0xf2, 0x24, 0x00, 0x00, - 0x03, 0xfc, 0x0e, 0xf1, 0x25, 0x00, 0x00, - 0x03, 0xfc, 0x0f, 0xf0, 0x26, 0x00, 0x00, - 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, - 0x03, 0xfc, 0x41, 0xbe, 0x37, 0x00, 0x00, - 0x03, 0xfc, 0x12, 0xed, 0x27, 0x00, 0x00, - 0x03, 0xfc, 0x11, 0xee, 0x2a, 0x00, 0x00, - 0x03, 0xfc, 0x48, 0xb7, 0x2c, 0x00, 0x00, - 0x03, 0xfc, 0x4a, 0xb5, 0x3c, 0x00, 0x00, - 0x03, 0xfc, 0x47, 0xb8, 0x15, 0x01, 0x00, - 0x03, 0xfc, 0x45, 0xba, 0x0b, 0x01, 0x00, - 0x03, 0xfc, 0x5e, 0xa1, 0x43, 0x00, 0x00, - 0x03, 0xfc, 0x5a, 0xa5, 0x42, 0x00, 0x00, - 0x03, 0xfc, 0x5b, 0xa4, 0x4b, 0x00, 0x00, - 0x03, 0xfc, 0x5f, 0xa0, 0x4e, 0x00, 0x00, -}; - -/* TwinHan AzureWave AD-TU700(704J) */ -static struct dvb_usb_rc_key af9015_rc_keys_twinhan[] = { - { 0x05, 0x3f, KEY_POWER }, - { 0x00, 0x19, KEY_FAVORITES }, /* Favorite List */ - { 0x00, 0x04, KEY_TEXT }, /* Teletext */ - { 0x00, 0x0e, KEY_POWER }, - { 0x00, 0x0e, KEY_INFO }, /* Preview */ - { 0x00, 0x08, KEY_EPG }, /* Info/EPG */ - { 0x00, 0x0f, KEY_LIST }, /* Record List */ - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x29, KEY_CANCEL }, /* Cancel */ - { 0x00, 0x4c, KEY_CLEAR }, /* Clear */ - { 0x00, 0x2a, KEY_BACK }, /* Back */ - { 0x00, 0x2b, KEY_TAB }, /* Tab */ - { 0x00, 0x52, KEY_UP }, /* up arrow */ - { 0x00, 0x51, KEY_DOWN }, /* down arrow */ - { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */ - { 0x00, 0x50, KEY_LEFT }, /* left arrow */ - { 0x00, 0x28, KEY_ENTER }, /* Enter / ok */ - { 0x02, 0x52, KEY_VOLUMEUP }, - { 0x02, 0x51, KEY_VOLUMEDOWN }, - { 0x00, 0x4e, KEY_CHANNELDOWN }, - { 0x00, 0x4b, KEY_CHANNELUP }, - { 0x00, 0x4a, KEY_RECORD }, - { 0x01, 0x11, KEY_PLAY }, - { 0x00, 0x17, KEY_PAUSE }, - { 0x00, 0x0c, KEY_REWIND }, /* FR << */ - { 0x00, 0x11, KEY_FASTFORWARD }, /* FF >> */ - { 0x01, 0x15, KEY_PREVIOUS }, /* Replay */ - { 0x01, 0x0e, KEY_NEXT }, /* Skip */ - { 0x00, 0x13, KEY_CAMERA }, /* Capture */ - { 0x01, 0x0f, KEY_LANGUAGE }, /* SAP */ - { 0x01, 0x13, KEY_TV2 }, /* PIP */ - { 0x00, 0x1d, KEY_ZOOM }, /* Full Screen */ - { 0x01, 0x17, KEY_SUBTITLE }, /* Subtitle / CC */ - { 0x00, 0x10, KEY_MUTE }, - { 0x01, 0x19, KEY_AUDIO }, /* L/R */ /* TODO better event */ - { 0x01, 0x16, KEY_SLEEP }, /* Hibernate */ - { 0x01, 0x16, KEY_SWITCHVIDEOMODE }, - /* A/V */ /* TODO does not work */ - { 0x00, 0x06, KEY_AGAIN }, /* Recall */ - { 0x01, 0x16, KEY_KPPLUS }, /* Zoom+ */ /* TODO does not work */ - { 0x01, 0x16, KEY_KPMINUS }, /* Zoom- */ /* TODO does not work */ - { 0x02, 0x15, KEY_RED }, - { 0x02, 0x0a, KEY_GREEN }, - { 0x02, 0x1c, KEY_YELLOW }, - { 0x02, 0x05, KEY_BLUE }, -}; - -static u8 af9015_ir_table_twinhan[] = { - 0x00, 0xff, 0x16, 0xe9, 0x3f, 0x05, 0x00, - 0x00, 0xff, 0x07, 0xf8, 0x16, 0x01, 0x00, - 0x00, 0xff, 0x14, 0xeb, 0x11, 0x01, 0x00, - 0x00, 0xff, 0x1a, 0xe5, 0x4d, 0x00, 0x00, - 0x00, 0xff, 0x4c, 0xb3, 0x17, 0x00, 0x00, - 0x00, 0xff, 0x12, 0xed, 0x11, 0x00, 0x00, - 0x00, 0xff, 0x40, 0xbf, 0x0c, 0x00, 0x00, - 0x00, 0xff, 0x11, 0xee, 0x4a, 0x00, 0x00, - 0x00, 0xff, 0x54, 0xab, 0x13, 0x00, 0x00, - 0x00, 0xff, 0x41, 0xbe, 0x15, 0x01, 0x00, - 0x00, 0xff, 0x42, 0xbd, 0x0e, 0x01, 0x00, - 0x00, 0xff, 0x43, 0xbc, 0x17, 0x01, 0x00, - 0x00, 0xff, 0x50, 0xaf, 0x0f, 0x01, 0x00, - 0x00, 0xff, 0x4d, 0xb2, 0x1d, 0x00, 0x00, - 0x00, 0xff, 0x47, 0xb8, 0x13, 0x01, 0x00, - 0x00, 0xff, 0x05, 0xfa, 0x4b, 0x00, 0x00, - 0x00, 0xff, 0x02, 0xfd, 0x4e, 0x00, 0x00, - 0x00, 0xff, 0x0e, 0xf1, 0x06, 0x00, 0x00, - 0x00, 0xff, 0x1e, 0xe1, 0x52, 0x02, 0x00, - 0x00, 0xff, 0x0a, 0xf5, 0x51, 0x02, 0x00, - 0x00, 0xff, 0x10, 0xef, 0x10, 0x00, 0x00, - 0x00, 0xff, 0x49, 0xb6, 0x19, 0x01, 0x00, - 0x00, 0xff, 0x15, 0xea, 0x27, 0x00, 0x00, - 0x00, 0xff, 0x03, 0xfc, 0x1e, 0x00, 0x00, - 0x00, 0xff, 0x01, 0xfe, 0x1f, 0x00, 0x00, - 0x00, 0xff, 0x06, 0xf9, 0x20, 0x00, 0x00, - 0x00, 0xff, 0x09, 0xf6, 0x21, 0x00, 0x00, - 0x00, 0xff, 0x1d, 0xe2, 0x22, 0x00, 0x00, - 0x00, 0xff, 0x1f, 0xe0, 0x23, 0x00, 0x00, - 0x00, 0xff, 0x0d, 0xf2, 0x24, 0x00, 0x00, - 0x00, 0xff, 0x19, 0xe6, 0x25, 0x00, 0x00, - 0x00, 0xff, 0x1b, 0xe4, 0x26, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xff, 0x2b, 0x00, 0x00, - 0x00, 0xff, 0x4a, 0xb5, 0x4c, 0x00, 0x00, - 0x00, 0xff, 0x4b, 0xb4, 0x52, 0x00, 0x00, - 0x00, 0xff, 0x51, 0xae, 0x51, 0x00, 0x00, - 0x00, 0xff, 0x52, 0xad, 0x4f, 0x00, 0x00, - 0x00, 0xff, 0x4e, 0xb1, 0x50, 0x00, 0x00, - 0x00, 0xff, 0x0c, 0xf3, 0x29, 0x00, 0x00, - 0x00, 0xff, 0x4f, 0xb0, 0x28, 0x00, 0x00, - 0x00, 0xff, 0x13, 0xec, 0x2a, 0x00, 0x00, - 0x00, 0xff, 0x17, 0xe8, 0x19, 0x00, 0x00, - 0x00, 0xff, 0x04, 0xfb, 0x0f, 0x00, 0x00, - 0x00, 0xff, 0x48, 0xb7, 0x0e, 0x00, 0x00, - 0x00, 0xff, 0x0f, 0xf0, 0x04, 0x00, 0x00, - 0x00, 0xff, 0x1c, 0xe3, 0x08, 0x00, 0x00, - 0x00, 0xff, 0x18, 0xe7, 0x15, 0x02, 0x00, - 0x00, 0xff, 0x53, 0xac, 0x0a, 0x02, 0x00, - 0x00, 0xff, 0x5e, 0xa1, 0x1c, 0x02, 0x00, - 0x00, 0xff, 0x5f, 0xa0, 0x05, 0x02, 0x00, -}; - -/* A-Link DTU(m) */ -static struct dvb_usb_rc_key af9015_rc_keys_a_link[] = { - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x2e, KEY_CHANNELUP }, - { 0x00, 0x2d, KEY_CHANNELDOWN }, - { 0x04, 0x28, KEY_ZOOM }, - { 0x00, 0x41, KEY_MUTE }, - { 0x00, 0x42, KEY_VOLUMEDOWN }, - { 0x00, 0x43, KEY_VOLUMEUP }, - { 0x00, 0x44, KEY_GOTO }, /* jump */ - { 0x05, 0x45, KEY_POWER }, -}; - -static u8 af9015_ir_table_a_link[] = { - 0x08, 0xf7, 0x12, 0xed, 0x45, 0x05, 0x00, /* power */ - 0x08, 0xf7, 0x1a, 0xe5, 0x41, 0x00, 0x00, /* mute */ - 0x08, 0xf7, 0x01, 0xfe, 0x1e, 0x00, 0x00, /* 1 */ - 0x08, 0xf7, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */ - 0x08, 0xf7, 0x03, 0xfc, 0x24, 0x00, 0x00, /* 7 */ - 0x08, 0xf7, 0x05, 0xfa, 0x28, 0x04, 0x00, /* zoom */ - 0x08, 0xf7, 0x00, 0xff, 0x43, 0x00, 0x00, /* volume up */ - 0x08, 0xf7, 0x16, 0xe9, 0x42, 0x00, 0x00, /* volume down */ - 0x08, 0xf7, 0x0f, 0xf0, 0x1f, 0x00, 0x00, /* 2 */ - 0x08, 0xf7, 0x0d, 0xf2, 0x22, 0x00, 0x00, /* 5 */ - 0x08, 0xf7, 0x1b, 0xe4, 0x25, 0x00, 0x00, /* 8 */ - 0x08, 0xf7, 0x06, 0xf9, 0x27, 0x00, 0x00, /* 0 */ - 0x08, 0xf7, 0x14, 0xeb, 0x2e, 0x00, 0x00, /* channel up */ - 0x08, 0xf7, 0x1d, 0xe2, 0x2d, 0x00, 0x00, /* channel down */ - 0x08, 0xf7, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */ - 0x08, 0xf7, 0x18, 0xe7, 0x23, 0x00, 0x00, /* 6 */ - 0x08, 0xf7, 0x04, 0xfb, 0x26, 0x00, 0x00, /* 9 */ - 0x08, 0xf7, 0x07, 0xf8, 0x44, 0x00, 0x00, /* jump */ -}; - -/* MSI DIGIVOX mini II V3.0 */ -static struct dvb_usb_rc_key af9015_rc_keys_msi[] = { - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x03, 0x0f, KEY_CHANNELUP }, - { 0x03, 0x0e, KEY_CHANNELDOWN }, - { 0x00, 0x42, KEY_VOLUMEDOWN }, - { 0x00, 0x43, KEY_VOLUMEUP }, - { 0x05, 0x45, KEY_POWER }, - { 0x00, 0x52, KEY_UP }, /* up */ - { 0x00, 0x51, KEY_DOWN }, /* down */ - { 0x00, 0x28, KEY_ENTER }, -}; - -static u8 af9015_ir_table_msi[] = { - 0x03, 0xfc, 0x17, 0xe8, 0x45, 0x05, 0x00, /* power */ - 0x03, 0xfc, 0x0d, 0xf2, 0x51, 0x00, 0x00, /* down */ - 0x03, 0xfc, 0x03, 0xfc, 0x52, 0x00, 0x00, /* up */ - 0x03, 0xfc, 0x1a, 0xe5, 0x1e, 0x00, 0x00, /* 1 */ - 0x03, 0xfc, 0x02, 0xfd, 0x1f, 0x00, 0x00, /* 2 */ - 0x03, 0xfc, 0x04, 0xfb, 0x20, 0x00, 0x00, /* 3 */ - 0x03, 0xfc, 0x1c, 0xe3, 0x21, 0x00, 0x00, /* 4 */ - 0x03, 0xfc, 0x08, 0xf7, 0x22, 0x00, 0x00, /* 5 */ - 0x03, 0xfc, 0x1d, 0xe2, 0x23, 0x00, 0x00, /* 6 */ - 0x03, 0xfc, 0x11, 0xee, 0x24, 0x00, 0x00, /* 7 */ - 0x03, 0xfc, 0x0b, 0xf4, 0x25, 0x00, 0x00, /* 8 */ - 0x03, 0xfc, 0x10, 0xef, 0x26, 0x00, 0x00, /* 9 */ - 0x03, 0xfc, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */ - 0x03, 0xfc, 0x14, 0xeb, 0x43, 0x00, 0x00, /* volume up */ - 0x03, 0xfc, 0x1f, 0xe0, 0x42, 0x00, 0x00, /* volume down */ - 0x03, 0xfc, 0x15, 0xea, 0x0f, 0x03, 0x00, /* channel up */ - 0x03, 0xfc, 0x05, 0xfa, 0x0e, 0x03, 0x00, /* channel down */ - 0x03, 0xfc, 0x16, 0xe9, 0x28, 0x00, 0x00, /* enter */ -}; - -/* MYGICTV U718 */ -static struct dvb_usb_rc_key af9015_rc_keys_mygictv[] = { - { 0x00, 0x3d, KEY_SWITCHVIDEOMODE }, - /* TV / AV */ - { 0x05, 0x45, KEY_POWER }, - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x41, KEY_MUTE }, - { 0x00, 0x2a, KEY_ESC }, /* Esc */ - { 0x00, 0x2e, KEY_CHANNELUP }, - { 0x00, 0x2d, KEY_CHANNELDOWN }, - { 0x00, 0x42, KEY_VOLUMEDOWN }, - { 0x00, 0x43, KEY_VOLUMEUP }, - { 0x00, 0x52, KEY_UP }, /* up arrow */ - { 0x00, 0x51, KEY_DOWN }, /* down arrow */ - { 0x00, 0x4f, KEY_RIGHT }, /* right arrow */ - { 0x00, 0x50, KEY_LEFT }, /* left arrow */ - { 0x00, 0x28, KEY_ENTER }, /* ok */ - { 0x01, 0x15, KEY_RECORD }, - { 0x03, 0x13, KEY_PLAY }, - { 0x01, 0x13, KEY_PAUSE }, - { 0x01, 0x16, KEY_STOP }, - { 0x03, 0x07, KEY_REWIND }, /* FR << */ - { 0x03, 0x09, KEY_FASTFORWARD }, /* FF >> */ - { 0x00, 0x3b, KEY_TIME }, /* TimeShift */ - { 0x00, 0x3e, KEY_CAMERA }, /* Snapshot */ - { 0x03, 0x16, KEY_CYCLEWINDOWS }, /* yellow, min / max */ - { 0x00, 0x00, KEY_ZOOM }, /* 'select' (?) */ - { 0x03, 0x16, KEY_SHUFFLE }, /* Shuffle */ - { 0x03, 0x45, KEY_POWER }, -}; - -static u8 af9015_ir_table_mygictv[] = { - 0x02, 0xbd, 0x0c, 0xf3, 0x3d, 0x00, 0x00, /* TV / AV */ - 0x02, 0xbd, 0x14, 0xeb, 0x45, 0x05, 0x00, /* power */ - 0x02, 0xbd, 0x00, 0xff, 0x1e, 0x00, 0x00, /* 1 */ - 0x02, 0xbd, 0x01, 0xfe, 0x1f, 0x00, 0x00, /* 2 */ - 0x02, 0xbd, 0x02, 0xfd, 0x20, 0x00, 0x00, /* 3 */ - 0x02, 0xbd, 0x03, 0xfc, 0x21, 0x00, 0x00, /* 4 */ - 0x02, 0xbd, 0x04, 0xfb, 0x22, 0x00, 0x00, /* 5 */ - 0x02, 0xbd, 0x05, 0xfa, 0x23, 0x00, 0x00, /* 6 */ - 0x02, 0xbd, 0x06, 0xf9, 0x24, 0x00, 0x00, /* 7 */ - 0x02, 0xbd, 0x07, 0xf8, 0x25, 0x00, 0x00, /* 8 */ - 0x02, 0xbd, 0x08, 0xf7, 0x26, 0x00, 0x00, /* 9 */ - 0x02, 0xbd, 0x09, 0xf6, 0x27, 0x00, 0x00, /* 0 */ - 0x02, 0xbd, 0x0a, 0xf5, 0x41, 0x00, 0x00, /* mute */ - 0x02, 0xbd, 0x1c, 0xe3, 0x2a, 0x00, 0x00, /* esc */ - 0x02, 0xbd, 0x1f, 0xe0, 0x43, 0x00, 0x00, /* volume up */ - 0x02, 0xbd, 0x12, 0xed, 0x52, 0x00, 0x00, /* up arrow */ - 0x02, 0xbd, 0x11, 0xee, 0x50, 0x00, 0x00, /* left arrow */ - 0x02, 0xbd, 0x15, 0xea, 0x28, 0x00, 0x00, /* ok */ - 0x02, 0xbd, 0x10, 0xef, 0x4f, 0x00, 0x00, /* right arrow */ - 0x02, 0xbd, 0x13, 0xec, 0x51, 0x00, 0x00, /* down arrow */ - 0x02, 0xbd, 0x0e, 0xf1, 0x42, 0x00, 0x00, /* volume down */ - 0x02, 0xbd, 0x19, 0xe6, 0x15, 0x01, 0x00, /* record */ - 0x02, 0xbd, 0x1e, 0xe1, 0x13, 0x03, 0x00, /* play */ - 0x02, 0xbd, 0x16, 0xe9, 0x16, 0x01, 0x00, /* stop */ - 0x02, 0xbd, 0x0b, 0xf4, 0x28, 0x04, 0x00, /* yellow, min / max */ - 0x02, 0xbd, 0x0f, 0xf0, 0x3b, 0x00, 0x00, /* time shift */ - 0x02, 0xbd, 0x18, 0xe7, 0x2e, 0x00, 0x00, /* channel up */ - 0x02, 0xbd, 0x1a, 0xe5, 0x2d, 0x00, 0x00, /* channel down */ - 0x02, 0xbd, 0x17, 0xe8, 0x3e, 0x00, 0x00, /* snapshot */ - 0x02, 0xbd, 0x40, 0xbf, 0x13, 0x01, 0x00, /* pause */ - 0x02, 0xbd, 0x41, 0xbe, 0x09, 0x03, 0x00, /* FF >> */ - 0x02, 0xbd, 0x42, 0xbd, 0x07, 0x03, 0x00, /* FR << */ - 0x02, 0xbd, 0x43, 0xbc, 0x00, 0x00, 0x00, /* 'select' (?) */ - 0x02, 0xbd, 0x44, 0xbb, 0x16, 0x03, 0x00, /* shuffle */ - 0x02, 0xbd, 0x45, 0xba, 0x45, 0x03, 0x00, /* power */ -}; - -/* KWorld PlusTV Dual DVB-T Stick (DVB-T 399U) */ -static u8 af9015_ir_table_kworld[] = { - 0x86, 0x6b, 0x0c, 0xf3, 0x2e, 0x07, 0x00, - 0x86, 0x6b, 0x16, 0xe9, 0x2d, 0x07, 0x00, - 0x86, 0x6b, 0x1d, 0xe2, 0x37, 0x07, 0x00, - 0x86, 0x6b, 0x00, 0xff, 0x1e, 0x07, 0x00, - 0x86, 0x6b, 0x01, 0xfe, 0x1f, 0x07, 0x00, - 0x86, 0x6b, 0x02, 0xfd, 0x20, 0x07, 0x00, - 0x86, 0x6b, 0x03, 0xfc, 0x21, 0x07, 0x00, - 0x86, 0x6b, 0x04, 0xfb, 0x22, 0x07, 0x00, - 0x86, 0x6b, 0x05, 0xfa, 0x23, 0x07, 0x00, - 0x86, 0x6b, 0x06, 0xf9, 0x24, 0x07, 0x00, - 0x86, 0x6b, 0x07, 0xf8, 0x25, 0x07, 0x00, - 0x86, 0x6b, 0x08, 0xf7, 0x26, 0x07, 0x00, - 0x86, 0x6b, 0x09, 0xf6, 0x4d, 0x07, 0x00, - 0x86, 0x6b, 0x0a, 0xf5, 0x4e, 0x07, 0x00, - 0x86, 0x6b, 0x14, 0xeb, 0x4f, 0x07, 0x00, - 0x86, 0x6b, 0x1e, 0xe1, 0x50, 0x07, 0x00, - 0x86, 0x6b, 0x17, 0xe8, 0x52, 0x07, 0x00, - 0x86, 0x6b, 0x1f, 0xe0, 0x51, 0x07, 0x00, - 0x86, 0x6b, 0x0e, 0xf1, 0x0b, 0x07, 0x00, - 0x86, 0x6b, 0x20, 0xdf, 0x0c, 0x07, 0x00, - 0x86, 0x6b, 0x42, 0xbd, 0x0d, 0x07, 0x00, - 0x86, 0x6b, 0x0b, 0xf4, 0x0e, 0x07, 0x00, - 0x86, 0x6b, 0x43, 0xbc, 0x0f, 0x07, 0x00, - 0x86, 0x6b, 0x10, 0xef, 0x10, 0x07, 0x00, - 0x86, 0x6b, 0x21, 0xde, 0x11, 0x07, 0x00, - 0x86, 0x6b, 0x13, 0xec, 0x12, 0x07, 0x00, - 0x86, 0x6b, 0x11, 0xee, 0x13, 0x07, 0x00, - 0x86, 0x6b, 0x12, 0xed, 0x14, 0x07, 0x00, - 0x86, 0x6b, 0x19, 0xe6, 0x15, 0x07, 0x00, - 0x86, 0x6b, 0x1a, 0xe5, 0x16, 0x07, 0x00, - 0x86, 0x6b, 0x1b, 0xe4, 0x17, 0x07, 0x00, - 0x86, 0x6b, 0x4b, 0xb4, 0x18, 0x07, 0x00, - 0x86, 0x6b, 0x40, 0xbf, 0x19, 0x07, 0x00, - 0x86, 0x6b, 0x44, 0xbb, 0x1a, 0x07, 0x00, - 0x86, 0x6b, 0x41, 0xbe, 0x1b, 0x07, 0x00, - 0x86, 0x6b, 0x22, 0xdd, 0x1c, 0x07, 0x00, - 0x86, 0x6b, 0x15, 0xea, 0x1d, 0x07, 0x00, - 0x86, 0x6b, 0x0f, 0xf0, 0x3f, 0x07, 0x00, - 0x86, 0x6b, 0x1c, 0xe3, 0x40, 0x07, 0x00, - 0x86, 0x6b, 0x4a, 0xb5, 0x41, 0x07, 0x00, - 0x86, 0x6b, 0x48, 0xb7, 0x42, 0x07, 0x00, - 0x86, 0x6b, 0x49, 0xb6, 0x43, 0x07, 0x00, - 0x86, 0x6b, 0x18, 0xe7, 0x44, 0x07, 0x00, - 0x86, 0x6b, 0x23, 0xdc, 0x45, 0x07, 0x00, -}; - -/* AverMedia Volar X */ -static struct dvb_usb_rc_key af9015_rc_keys_avermedia[] = { - { 0x05, 0x3d, KEY_PROG1 }, /* SOURCE */ - { 0x05, 0x12, KEY_POWER }, /* POWER */ - { 0x05, 0x1e, KEY_1 }, /* 1 */ - { 0x05, 0x1f, KEY_2 }, /* 2 */ - { 0x05, 0x20, KEY_3 }, /* 3 */ - { 0x05, 0x21, KEY_4 }, /* 4 */ - { 0x05, 0x22, KEY_5 }, /* 5 */ - { 0x05, 0x23, KEY_6 }, /* 6 */ - { 0x05, 0x24, KEY_7 }, /* 7 */ - { 0x05, 0x25, KEY_8 }, /* 8 */ - { 0x05, 0x26, KEY_9 }, /* 9 */ - { 0x05, 0x3f, KEY_LEFT }, /* L / DISPLAY */ - { 0x05, 0x27, KEY_0 }, /* 0 */ - { 0x05, 0x0f, KEY_RIGHT }, /* R / CH RTN */ - { 0x05, 0x18, KEY_PROG2 }, /* SNAP SHOT */ - { 0x05, 0x1c, KEY_PROG3 }, /* 16-CH PREV */ - { 0x05, 0x2d, KEY_VOLUMEDOWN }, /* VOL DOWN */ - { 0x05, 0x3e, KEY_ZOOM }, /* FULL SCREEN */ - { 0x05, 0x2e, KEY_VOLUMEUP }, /* VOL UP */ - { 0x05, 0x10, KEY_MUTE }, /* MUTE */ - { 0x05, 0x04, KEY_AUDIO }, /* AUDIO */ - { 0x05, 0x15, KEY_RECORD }, /* RECORD */ - { 0x05, 0x11, KEY_PLAY }, /* PLAY */ - { 0x05, 0x16, KEY_STOP }, /* STOP */ - { 0x05, 0x0c, KEY_PLAYPAUSE }, /* TIMESHIFT / PAUSE */ - { 0x05, 0x05, KEY_BACK }, /* << / RED */ - { 0x05, 0x09, KEY_FORWARD }, /* >> / YELLOW */ - { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */ - { 0x05, 0x0a, KEY_EPG }, /* EPG */ - { 0x05, 0x13, KEY_MENU }, /* MENU */ - - { 0x05, 0x0e, KEY_CHANNELUP }, /* CH UP */ - { 0x05, 0x0d, KEY_CHANNELDOWN }, /* CH DOWN */ - { 0x05, 0x19, KEY_FIRST }, /* |<< / GREEN */ - { 0x05, 0x08, KEY_LAST }, /* >>| / BLUE */ -}; - -static u8 af9015_ir_table_avermedia[] = { - 0x02, 0xfd, 0x00, 0xff, 0x12, 0x05, 0x00, - 0x02, 0xfd, 0x01, 0xfe, 0x3d, 0x05, 0x00, - 0x02, 0xfd, 0x03, 0xfc, 0x17, 0x05, 0x00, - 0x02, 0xfd, 0x04, 0xfb, 0x0a, 0x05, 0x00, - 0x02, 0xfd, 0x05, 0xfa, 0x1e, 0x05, 0x00, - 0x02, 0xfd, 0x06, 0xf9, 0x1f, 0x05, 0x00, - 0x02, 0xfd, 0x07, 0xf8, 0x20, 0x05, 0x00, - 0x02, 0xfd, 0x09, 0xf6, 0x21, 0x05, 0x00, - 0x02, 0xfd, 0x0a, 0xf5, 0x22, 0x05, 0x00, - 0x02, 0xfd, 0x0b, 0xf4, 0x23, 0x05, 0x00, - 0x02, 0xfd, 0x0d, 0xf2, 0x24, 0x05, 0x00, - 0x02, 0xfd, 0x0e, 0xf1, 0x25, 0x05, 0x00, - 0x02, 0xfd, 0x0f, 0xf0, 0x26, 0x05, 0x00, - 0x02, 0xfd, 0x11, 0xee, 0x27, 0x05, 0x00, - 0x02, 0xfd, 0x08, 0xf7, 0x04, 0x05, 0x00, - 0x02, 0xfd, 0x0c, 0xf3, 0x3e, 0x05, 0x00, - 0x02, 0xfd, 0x10, 0xef, 0x1c, 0x05, 0x00, - 0x02, 0xfd, 0x12, 0xed, 0x3f, 0x05, 0x00, - 0x02, 0xfd, 0x13, 0xec, 0x0f, 0x05, 0x00, - 0x02, 0xfd, 0x14, 0xeb, 0x10, 0x05, 0x00, - 0x02, 0xfd, 0x15, 0xea, 0x13, 0x05, 0x00, - 0x02, 0xfd, 0x17, 0xe8, 0x18, 0x05, 0x00, - 0x02, 0xfd, 0x18, 0xe7, 0x11, 0x05, 0x00, - 0x02, 0xfd, 0x19, 0xe6, 0x15, 0x05, 0x00, - 0x02, 0xfd, 0x1a, 0xe5, 0x0c, 0x05, 0x00, - 0x02, 0xfd, 0x1b, 0xe4, 0x16, 0x05, 0x00, - 0x02, 0xfd, 0x1c, 0xe3, 0x09, 0x05, 0x00, - 0x02, 0xfd, 0x1d, 0xe2, 0x05, 0x05, 0x00, - 0x02, 0xfd, 0x1e, 0xe1, 0x2d, 0x05, 0x00, - 0x02, 0xfd, 0x1f, 0xe0, 0x2e, 0x05, 0x00, - 0x03, 0xfc, 0x00, 0xff, 0x08, 0x05, 0x00, - 0x03, 0xfc, 0x01, 0xfe, 0x19, 0x05, 0x00, - 0x03, 0xfc, 0x02, 0xfd, 0x0d, 0x05, 0x00, - 0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00, -}; - -/* Digittrade DVB-T USB Stick */ -static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = { - { 0x01, 0x0f, KEY_LAST }, /* RETURN */ - { 0x05, 0x17, KEY_TEXT }, /* TELETEXT */ - { 0x01, 0x08, KEY_EPG }, /* EPG */ - { 0x05, 0x13, KEY_POWER }, /* POWER */ - { 0x01, 0x09, KEY_ZOOM }, /* FULLSCREEN */ - { 0x00, 0x40, KEY_AUDIO }, /* DUAL SOUND */ - { 0x00, 0x2c, KEY_PRINT }, /* SNAPSHOT */ - { 0x05, 0x16, KEY_SUBTITLE }, /* SUBTITLE */ - { 0x00, 0x52, KEY_CHANNELUP }, /* CH Up */ - { 0x00, 0x51, KEY_CHANNELDOWN },/* Ch Dn */ - { 0x00, 0x57, KEY_VOLUMEUP }, /* Vol Up */ - { 0x00, 0x56, KEY_VOLUMEDOWN }, /* Vol Dn */ - { 0x01, 0x10, KEY_MUTE }, /* MUTE */ - { 0x00, 0x27, KEY_0 }, - { 0x00, 0x1e, KEY_1 }, - { 0x00, 0x1f, KEY_2 }, - { 0x00, 0x20, KEY_3 }, - { 0x00, 0x21, KEY_4 }, - { 0x00, 0x22, KEY_5 }, - { 0x00, 0x23, KEY_6 }, - { 0x00, 0x24, KEY_7 }, - { 0x00, 0x25, KEY_8 }, - { 0x00, 0x26, KEY_9 }, - { 0x01, 0x17, KEY_PLAYPAUSE }, /* TIMESHIFT */ - { 0x01, 0x15, KEY_RECORD }, /* RECORD */ - { 0x03, 0x13, KEY_PLAY }, /* PLAY */ - { 0x01, 0x16, KEY_STOP }, /* STOP */ - { 0x01, 0x13, KEY_PAUSE }, /* PAUSE */ -}; - -static u8 af9015_ir_table_digittrade[] = { - 0x00, 0xff, 0x06, 0xf9, 0x13, 0x05, 0x00, - 0x00, 0xff, 0x4d, 0xb2, 0x17, 0x01, 0x00, - 0x00, 0xff, 0x1f, 0xe0, 0x2c, 0x00, 0x00, - 0x00, 0xff, 0x0a, 0xf5, 0x15, 0x01, 0x00, - 0x00, 0xff, 0x0e, 0xf1, 0x16, 0x01, 0x00, - 0x00, 0xff, 0x09, 0xf6, 0x09, 0x01, 0x00, - 0x00, 0xff, 0x01, 0xfe, 0x08, 0x01, 0x00, - 0x00, 0xff, 0x05, 0xfa, 0x10, 0x01, 0x00, - 0x00, 0xff, 0x02, 0xfd, 0x56, 0x00, 0x00, - 0x00, 0xff, 0x40, 0xbf, 0x57, 0x00, 0x00, - 0x00, 0xff, 0x19, 0xe6, 0x52, 0x00, 0x00, - 0x00, 0xff, 0x17, 0xe8, 0x51, 0x00, 0x00, - 0x00, 0xff, 0x10, 0xef, 0x0f, 0x01, 0x00, - 0x00, 0xff, 0x54, 0xab, 0x27, 0x00, 0x00, - 0x00, 0xff, 0x1b, 0xe4, 0x1e, 0x00, 0x00, - 0x00, 0xff, 0x11, 0xee, 0x1f, 0x00, 0x00, - 0x00, 0xff, 0x15, 0xea, 0x20, 0x00, 0x00, - 0x00, 0xff, 0x12, 0xed, 0x21, 0x00, 0x00, - 0x00, 0xff, 0x16, 0xe9, 0x22, 0x00, 0x00, - 0x00, 0xff, 0x4c, 0xb3, 0x23, 0x00, 0x00, - 0x00, 0xff, 0x48, 0xb7, 0x24, 0x00, 0x00, - 0x00, 0xff, 0x04, 0xfb, 0x25, 0x00, 0x00, - 0x00, 0xff, 0x00, 0xff, 0x26, 0x00, 0x00, - 0x00, 0xff, 0x1e, 0xe1, 0x13, 0x03, 0x00, - 0x00, 0xff, 0x1a, 0xe5, 0x13, 0x01, 0x00, - 0x00, 0xff, 0x03, 0xfc, 0x17, 0x05, 0x00, - 0x00, 0xff, 0x0d, 0xf2, 0x16, 0x05, 0x00, - 0x00, 0xff, 0x1d, 0xe2, 0x40, 0x00, 0x00, -}; - -#endif diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c deleted file mode 100644 index c6e7b4215d6..00000000000 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * TODO: - * - add smart card reader support for Conditional Access (CA) - * - * Card reader in Anysee is nothing more than ISO 7816 card reader. - * There is no hardware CAM in any Anysee device sold. - * In my understanding it should be implemented by making own module - * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This - * module registers serial interface that can be used to communicate - * with any ISO 7816 smart card. - * - * Any help according to implement serial smart card reader support - * is highly welcome! - */ - -#include "anysee.h" -#include "tda1002x.h" -#include "mt352.h" -#include "mt352_priv.h" -#include "zl10353.h" - -/* debug */ -static int dvb_usb_anysee_debug; -module_param_named(debug, dvb_usb_anysee_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -static int dvb_usb_anysee_delsys; -module_param_named(delsys, dvb_usb_anysee_delsys, int, 0644); -MODULE_PARM_DESC(delsys, "select delivery mode (0=DVB-C, 1=DVB-T)"); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static DEFINE_MUTEX(anysee_usb_mutex); - -static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, - u8 *rbuf, u8 rlen) -{ - struct anysee_state *state = d->priv; - int act_len, ret; - u8 buf[64]; - - if (slen > sizeof(buf)) - slen = sizeof(buf); - memcpy(&buf[0], sbuf, slen); - buf[60] = state->seq++; - - if (mutex_lock_interruptible(&anysee_usb_mutex) < 0) - return -EAGAIN; - - /* We need receive one message more after dvb_usb_generic_rw due - to weird transaction flow, which is 1 x send + 2 x receive. */ - ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); - - if (!ret) { - /* receive 2nd answer */ - ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, - d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), - &act_len, 2000); - if (ret) - err("%s: recv bulk message failed: %d", __func__, ret); - else { - deb_xfer("<<< "); - debug_dump(buf, act_len, deb_xfer); - } - } - - /* read request, copy returned data to return buf */ - if (!ret && rbuf && rlen) - memcpy(rbuf, buf, rlen); - - mutex_unlock(&anysee_usb_mutex); - - return ret; -} - -static int anysee_read_reg(struct dvb_usb_device *d, u16 reg, u8 *val) -{ - u8 buf[] = {CMD_REG_READ, reg >> 8, reg & 0xff, 0x01}; - int ret; - ret = anysee_ctrl_msg(d, buf, sizeof(buf), val, 1); - deb_info("%s: reg:%04x val:%02x\n", __func__, reg, *val); - return ret; -} - -static int anysee_write_reg(struct dvb_usb_device *d, u16 reg, u8 val) -{ - u8 buf[] = {CMD_REG_WRITE, reg >> 8, reg & 0xff, 0x01, val}; - deb_info("%s: reg:%04x val:%02x\n", __func__, reg, val); - return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); -} - -static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id) -{ - u8 buf[] = {CMD_GET_HW_INFO}; - return anysee_ctrl_msg(d, buf, sizeof(buf), id, 3); -} - -static int anysee_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - u8 buf[] = {CMD_STREAMING_CTRL, (u8)onoff, 0x00}; - deb_info("%s: onoff:%02x\n", __func__, onoff); - return anysee_ctrl_msg(adap->dev, buf, sizeof(buf), NULL, 0); -} - -static int anysee_led_ctrl(struct dvb_usb_device *d, u8 mode, u8 interval) -{ - u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x01, mode, interval}; - deb_info("%s: state:%02x interval:%02x\n", __func__, mode, interval); - return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); -} - -static int anysee_ir_ctrl(struct dvb_usb_device *d, u8 onoff) -{ - u8 buf[] = {CMD_LED_AND_IR_CTRL, 0x02, onoff}; - deb_info("%s: onoff:%02x\n", __func__, onoff); - return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); -} - -static int anysee_init(struct dvb_usb_device *d) -{ - int ret; - /* LED light */ - ret = anysee_led_ctrl(d, 0x01, 0x03); - if (ret) - return ret; - - /* enable IR */ - ret = anysee_ir_ctrl(d, 1); - if (ret) - return ret; - - return 0; -} - -/* I2C */ -static int anysee_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0, inc, i = 0; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - while (i < num) { - if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { - u8 buf[6]; - buf[0] = CMD_I2C_READ; - buf[1] = msg[i].addr + 1; - buf[2] = msg[i].buf[0]; - buf[3] = 0x00; - buf[4] = 0x00; - buf[5] = 0x01; - ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf, - msg[i+1].len); - inc = 2; - } else { - u8 buf[4+msg[i].len]; - buf[0] = CMD_I2C_WRITE; - buf[1] = msg[i].addr; - buf[2] = msg[i].len; - buf[3] = 0x01; - memcpy(&buf[4], msg[i].buf, msg[i].len); - ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0); - inc = 1; - } - if (ret) - break; - - i += inc; - } - - mutex_unlock(&d->i2c_mutex); - - return ret ? ret : i; -} - -static u32 anysee_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm anysee_i2c_algo = { - .master_xfer = anysee_master_xfer, - .functionality = anysee_i2c_func, -}; - -static int anysee_mt352_demod_init(struct dvb_frontend *fe) -{ - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; - static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; - static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; - - mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(200); - mt352_write(fe, reset, sizeof(reset)); - mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); - - mt352_write(fe, agc_cfg, sizeof(agc_cfg)); - mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); - mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - - return 0; -} - -/* Callbacks for DVB USB */ -static struct tda10023_config anysee_tda10023_config = { - .demod_address = 0x1a, - .invert = 0, - .xtal = 16000000, - .pll_m = 11, - .pll_p = 3, - .pll_n = 1, - .output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C, - .deltaf = 0xfeeb, -}; - -static struct mt352_config anysee_mt352_config = { - .demod_address = 0x1e, - .demod_init = anysee_mt352_demod_init, -}; - -static struct zl10353_config anysee_zl10353_config = { - .demod_address = 0x1e, - .parallel_ts = 1, -}; - -static int anysee_frontend_attach(struct dvb_usb_adapter *adap) -{ - int ret; - struct anysee_state *state = adap->dev->priv; - u8 hw_info[3]; - u8 io_d; /* IO port D */ - - /* 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) - return ret; - ret = anysee_get_hw_info(adap->dev, hw_info); - if (ret) - return ret; - - /* Meaning of these info bytes are guessed. */ - info("firmware version:%d.%d.%d hardware id:%d", - 0, hw_info[1], hw_info[2], hw_info[0]); - - ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */ - if (ret) - return ret; - deb_info("%s: IO port D:%02x\n", __func__, io_d); - - /* Select demod using trial and error method. */ - - /* Try to attach demodulator in following order: - model demod hw firmware - 1. E30 MT352 02 0.2.1 - 2. E30 ZL10353 02 0.2.1 - 3. E30 Combo ZL10353 0f 0.1.2 DVB-T/C combo - 4. E30 Plus ZL10353 06 0.1.0 - 5. E30C Plus TDA10023 0a 0.1.0 rev 0.2 - E30C Plus TDA10023 0f 0.1.2 rev 0.4 - E30 Combo TDA10023 0f 0.1.2 DVB-T/C combo - */ - - /* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */ - adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config, - &adap->dev->i2c_adap); - if (adap->fe != NULL) { - state->tuner = DVB_PLL_THOMSON_DTT7579; - return 0; - } - - /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ - adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe != NULL) { - state->tuner = DVB_PLL_THOMSON_DTT7579; - return 0; - } - - /* for E30 Combo Plus DVB-T demodulator */ - if (dvb_usb_anysee_delsys) { - ret = anysee_write_reg(adap->dev, 0xb0, 0x01); - if (ret) - return ret; - - /* Zarlink ZL10353 DVB-T demod */ - adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe != NULL) { - state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; - return 0; - } - } - - /* connect demod on IO port D for TDA10023 & ZL10353 */ - ret = anysee_write_reg(adap->dev, 0xb0, 0x25); - if (ret) - return ret; - - /* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */ - adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe != NULL) { - state->tuner = DVB_PLL_THOMSON_DTT7579; - return 0; - } - - /* IO port E - E30C rev 0.4 board requires this */ - ret = anysee_write_reg(adap->dev, 0xb1, 0xa7); - if (ret) - return ret; - - /* Philips TDA10023 DVB-C demod */ - adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, - &adap->dev->i2c_adap, 0x48); - if (adap->fe != NULL) { - state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A; - return 0; - } - - /* return IO port D to init value for safe */ - ret = anysee_write_reg(adap->dev, 0xb0, io_d); - if (ret) - return ret; - - err("Unkown Anysee version: %02x %02x %02x. "\ - "Please report the <linux-dvb@linuxtv.org>.", - hw_info[0], hw_info[1], hw_info[2]); - - return -ENODEV; -} - -static int anysee_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct anysee_state *state = adap->dev->priv; - deb_info("%s: \n", __func__); - - switch (state->tuner) { - case DVB_PLL_THOMSON_DTT7579: - /* Thomson dtt7579 (not sure) PLL inside of: - Samsung DNOS404ZH102A NIM - Samsung DNOS404ZH103A NIM */ - dvb_attach(dvb_pll_attach, adap->fe, 0x61, - NULL, DVB_PLL_THOMSON_DTT7579); - break; - case DVB_PLL_SAMSUNG_DTOS403IH102A: - /* Unknown PLL inside of Samsung DTOS403IH102A tuner module */ - dvb_attach(dvb_pll_attach, adap->fe, 0xc0, - &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); - break; - } - - return 0; -} - -static int anysee_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 buf[] = {CMD_GET_IR_CODE}; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - u8 ircode[2]; - int i, ret; - - ret = anysee_ctrl_msg(d, buf, sizeof(buf), &ircode[0], 2); - if (ret) - return ret; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == ircode[0] && - keymap[i].data == ircode[1]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - return 0; - } - } - return 0; -} - -static struct dvb_usb_rc_key anysee_rc_keys[] = { - { 0x01, 0x00, KEY_0 }, - { 0x01, 0x01, KEY_1 }, - { 0x01, 0x02, KEY_2 }, - { 0x01, 0x03, KEY_3 }, - { 0x01, 0x04, KEY_4 }, - { 0x01, 0x05, KEY_5 }, - { 0x01, 0x06, KEY_6 }, - { 0x01, 0x07, KEY_7 }, - { 0x01, 0x08, KEY_8 }, - { 0x01, 0x09, KEY_9 }, - { 0x01, 0x0a, KEY_POWER }, - { 0x01, 0x0b, KEY_DOCUMENTS }, /* * */ - { 0x01, 0x19, KEY_FAVORITES }, - { 0x01, 0x20, KEY_SLEEP }, - { 0x01, 0x21, KEY_MODE }, /* 4:3 / 16:9 select */ - { 0x01, 0x22, KEY_ZOOM }, - { 0x01, 0x47, KEY_TEXT }, - { 0x01, 0x16, KEY_TV }, /* TV / radio select */ - { 0x01, 0x1e, KEY_LANGUAGE }, /* Second Audio Program */ - { 0x01, 0x1a, KEY_SUBTITLE }, - { 0x01, 0x1b, KEY_CAMERA }, /* screenshot */ - { 0x01, 0x42, KEY_MUTE }, - { 0x01, 0x0e, KEY_MENU }, - { 0x01, 0x0f, KEY_EPG }, - { 0x01, 0x17, KEY_INFO }, - { 0x01, 0x10, KEY_EXIT }, - { 0x01, 0x13, KEY_VOLUMEUP }, - { 0x01, 0x12, KEY_VOLUMEDOWN }, - { 0x01, 0x11, KEY_CHANNELUP }, - { 0x01, 0x14, KEY_CHANNELDOWN }, - { 0x01, 0x15, KEY_OK }, - { 0x01, 0x1d, KEY_RED }, - { 0x01, 0x1f, KEY_GREEN }, - { 0x01, 0x1c, KEY_YELLOW }, - { 0x01, 0x44, KEY_BLUE }, - { 0x01, 0x0c, KEY_SHUFFLE }, /* snapshot */ - { 0x01, 0x48, KEY_STOP }, - { 0x01, 0x50, KEY_PLAY }, - { 0x01, 0x51, KEY_PAUSE }, - { 0x01, 0x49, KEY_RECORD }, - { 0x01, 0x18, KEY_PREVIOUS }, /* |<< */ - { 0x01, 0x0d, KEY_NEXT }, /* >>| */ - { 0x01, 0x24, KEY_PROG1 }, /* F1 */ - { 0x01, 0x25, KEY_PROG2 }, /* F2 */ -}; - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties anysee_properties; - -static int anysee_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct dvb_usb_device *d; - struct usb_host_interface *alt; - int ret; - - /* There is one interface with two alternate settings. - Alternate setting 0 is for bulk transfer. - Alternate setting 1 is for isochronous transfer. - We use bulk transfer (alternate setting 0). */ - if (intf->num_altsetting < 1) - return -ENODEV; - - ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d, - adapter_nr); - if (ret) - return ret; - - alt = usb_altnum_to_altsetting(intf, 0); - if (alt == NULL) { - deb_info("%s: no alt found!\n", __func__); - return -ENODEV; - } - - ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); - if (ret) - return ret; - - if (d) - ret = anysee_init(d); - - return ret; -} - -static struct usb_device_id anysee_table [] = { - { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, - { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, anysee_table); - -static struct dvb_usb_device_properties anysee_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - - .size_of_priv = sizeof(struct anysee_state), - - .num_adapters = 1, - .adapter = { - { - .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 = 512, - } - } - }, - } - }, - - .rc_key_map = anysee_rc_keys, - .rc_key_map_size = ARRAY_SIZE(anysee_rc_keys), - .rc_query = anysee_rc_query, - .rc_interval = 200, /* windows driver uses 500ms */ - - .i2c_algo = &anysee_i2c_algo, - - .generic_bulk_ctrl_endpoint = 1, - - .num_device_descs = 1, - .devices = { - { - .name = "Anysee DVB USB2.0", - .cold_ids = {NULL}, - .warm_ids = {&anysee_table[0], - &anysee_table[1], NULL}, - }, - } -}; - -static struct usb_driver anysee_driver = { - .name = "dvb_usb_anysee", - .probe = anysee_probe, - .disconnect = dvb_usb_device_exit, - .id_table = anysee_table, -}; - -/* module stuff */ -static int __init anysee_module_init(void) -{ - int ret; - - ret = usb_register(&anysee_driver); - if (ret) - err("%s: usb_register failed. Error number %d", __func__, ret); - - return ret; -} - -static void __exit anysee_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&anysee_driver); -} - -module_init(anysee_module_init); -module_exit(anysee_module_exit); - -MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); -MODULE_DESCRIPTION("Driver Anysee E30 DVB-C & DVB-T USB2.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h deleted file mode 100644 index 7ca01ff6e13..00000000000 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ /dev/null @@ -1,304 +0,0 @@ -/* - * DVB USB Linux driver for Anysee E30 DVB-C & DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * TODO: - * - add smart card reader support for Conditional Access (CA) - * - * Card reader in Anysee is nothing more than ISO 7816 card reader. - * There is no hardware CAM in any Anysee device sold. - * In my understanding it should be implemented by making own module - * for ISO 7816 card reader, like dvb_ca_en50221 is implemented. This - * module registers serial interface that can be used to communicate - * with any ISO 7816 smart card. - * - * Any help according to implement serial smart card reader support - * is highly welcome! - */ - -#ifndef _DVB_USB_ANYSEE_H_ -#define _DVB_USB_ANYSEE_H_ - -#define DVB_USB_LOG_PREFIX "anysee" -#include "dvb-usb.h" - -#define deb_info(args...) dprintk(dvb_usb_anysee_debug, 0x01, args) -#define deb_xfer(args...) dprintk(dvb_usb_anysee_debug, 0x02, args) -#define deb_rc(args...) dprintk(dvb_usb_anysee_debug, 0x04, args) -#define deb_reg(args...) dprintk(dvb_usb_anysee_debug, 0x08, args) -#define deb_i2c(args...) dprintk(dvb_usb_anysee_debug, 0x10, args) -#define deb_fw(args...) dprintk(dvb_usb_anysee_debug, 0x20, args) - -enum cmd { - CMD_I2C_READ = 0x33, - CMD_I2C_WRITE = 0x31, - CMD_REG_READ = 0xb0, - CMD_REG_WRITE = 0xb1, - CMD_STREAMING_CTRL = 0x12, - CMD_LED_AND_IR_CTRL = 0x16, - CMD_GET_IR_CODE = 0x41, - CMD_GET_HW_INFO = 0x19, - CMD_SMARTCARD = 0x34, -}; - -struct anysee_state { - u8 tuner; - u8 seq; -}; - -#endif - -/*************************************************************************** - * USB API description (reverse engineered) - *************************************************************************** - -Transaction flow: -================= -BULK[00001] >>> REQUEST PACKET 64 bytes -BULK[00081] <<< REPLY PACKET #1 64 bytes (PREVIOUS TRANSACTION REPLY) -BULK[00081] <<< REPLY PACKET #2 64 bytes (CURRENT TRANSACTION REPLY) - -General reply packet(s) are always used if not own reply defined. - -============================================================================ -| 00-63 | GENERAL REPLY PACKET #1 (PREVIOUS REPLY) -============================================================================ -| 00 | reply data (if any) from previous transaction -| | Just same reply packet as returned during previous transaction. -| | Needed only if reply is missed in previous transaction. -| | Just skip normally. ----------------------------------------------------------------------------- -| 01-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | GENERAL REPLY PACKET #2 (CURRENT REPLY) -============================================================================ -| 00 | reply data (if any) ----------------------------------------------------------------------------- -| 01-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | I2C WRITE REQUEST PACKET -============================================================================ -| 00 | 0x31 I2C write command ----------------------------------------------------------------------------- -| 01 | i2c address ----------------------------------------------------------------------------- -| 02 | data length -| | 0x02 (for typical I2C reg / val pair) ----------------------------------------------------------------------------- -| 03 | 0x01 ----------------------------------------------------------------------------- -| 04- | data ----------------------------------------------------------------------------- -| -59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | I2C READ REQUEST PACKET -============================================================================ -| 00 | 0x33 I2C read command ----------------------------------------------------------------------------- -| 01 | i2c address + 1 ----------------------------------------------------------------------------- -| 02 | register ----------------------------------------------------------------------------- -| 03 | 0x00 ----------------------------------------------------------------------------- -| 04 | 0x00 ----------------------------------------------------------------------------- -| 05 | 0x01 ----------------------------------------------------------------------------- -| 06-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | USB CONTROLLER REGISTER WRITE REQUEST PACKET -============================================================================ -| 00 | 0xb1 register write command ----------------------------------------------------------------------------- -| 01-02 | register ----------------------------------------------------------------------------- -| 03 | 0x01 ----------------------------------------------------------------------------- -| 04 | value ----------------------------------------------------------------------------- -| 05-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | USB CONTROLLER REGISTER READ REQUEST PACKET -============================================================================ -| 00 | 0xb0 register read command ----------------------------------------------------------------------------- -| 01-02 | register ----------------------------------------------------------------------------- -| 03 | 0x01 ----------------------------------------------------------------------------- -| 04-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | LED CONTROL REQUEST PACKET -============================================================================ -| 00 | 0x16 LED and IR control command ----------------------------------------------------------------------------- -| 01 | 0x01 (LED) ----------------------------------------------------------------------------- -| 03 | 0x00 blink -| | 0x01 lights continuously ----------------------------------------------------------------------------- -| 04 | blink interval -| | 0x00 fastest (looks like LED lights continuously) -| | 0xff slowest ----------------------------------------------------------------------------- -| 05-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | IR CONTROL REQUEST PACKET -============================================================================ -| 00 | 0x16 LED and IR control command ----------------------------------------------------------------------------- -| 01 | 0x02 (IR) ----------------------------------------------------------------------------- -| 03 | 0x00 IR disabled -| | 0x01 IR enabled ----------------------------------------------------------------------------- -| 04-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | STREAMING CONTROL REQUEST PACKET -============================================================================ -| 00 | 0x12 streaming control command ----------------------------------------------------------------------------- -| 01 | 0x00 streaming disabled -| | 0x01 streaming enabled ----------------------------------------------------------------------------- -| 02 | 0x00 ----------------------------------------------------------------------------- -| 03-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | REMOTE CONTROL REQUEST PACKET -============================================================================ -| 00 | 0x41 remote control command ----------------------------------------------------------------------------- -| 01-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | REMOTE CONTROL REPLY PACKET -============================================================================ -| 00 | 0x00 code not received -| | 0x01 code received ----------------------------------------------------------------------------- -| 01 | remote control code ----------------------------------------------------------------------------- -| 02-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | GET HARDWARE INFO REQUEST PACKET -============================================================================ -| 00 | 0x19 get hardware info command ----------------------------------------------------------------------------- -| 01-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | GET HARDWARE INFO REPLY PACKET -============================================================================ -| 00 | hardware id ----------------------------------------------------------------------------- -| 01-02 | firmware version ----------------------------------------------------------------------------- -| 03-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -============================================================================ -| 00-63 | SMART CARD READER PACKET -============================================================================ -| 00 | 0x34 smart card reader command ----------------------------------------------------------------------------- -| xx | ----------------------------------------------------------------------------- -| xx-59 | don't care ----------------------------------------------------------------------------- -| 60 | packet sequence number ----------------------------------------------------------------------------- -| 61-63 | don't care ----------------------------------------------------------------------------- - -*/ diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c deleted file mode 100644 index eb34cc3894e..00000000000 --- a/drivers/media/dvb/dvb-usb/au6610.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0. - * - * Copyright (C) 2006 Antti Palosaari <crope@iki.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "au6610.h" -#include "zl10353.h" -#include "qt1010.h" - -/* debug */ -static int dvb_usb_au6610_debug; -module_param_named(debug, dvb_usb_au6610_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - int ret; - u16 index; - u8 usb_buf[6]; /* enough for all known requests, - read returns 5 and write 6 bytes */ - switch (wlen) { - case 1: - index = wbuf[0] << 8; - break; - case 2: - index = wbuf[0] << 8; - index += wbuf[1]; - break; - default: - warn("wlen = %x, aborting.", wlen); - return -EINVAL; - } - - ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation, - USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index, - usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT); - if (ret < 0) - return ret; - - switch (operation) { - case AU6610_REQ_I2C_READ: - case AU6610_REQ_USB_READ: - /* requested value is always 5th byte in buffer */ - rbuf[0] = usb_buf[4]; - } - - return ret; -} - -static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u8 request; - u8 wo = (rbuf == NULL || rlen == 0); /* write-only */ - - if (wo) { - request = AU6610_REQ_I2C_WRITE; - } else { /* rw */ - request = AU6610_REQ_I2C_READ; - } - - return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen); -} - - -/* I2C */ -static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, - msg[i+1].len) < 0) - break; - i++; - } else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, NULL, 0) < 0) - break; - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - - -static u32 au6610_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm au6610_i2c_algo = { - .master_xfer = au6610_i2c_xfer, - .functionality = au6610_i2c_func, -}; - -/* Callbacks for DVB USB */ -static struct zl10353_config au6610_zl10353_config = { - .demod_address = 0x0f, - .no_tuner = 1, - .parallel_ts = 1, -}; - -static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) -{ - adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe == NULL) - return -ENODEV; - - return 0; -} - -static struct qt1010_config au6610_qt1010_config = { - .i2c_address = 0x62 -}; - -static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) -{ - return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, - &au6610_qt1010_config) == NULL ? -ENODEV : 0; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties au6610_properties; - -static int au6610_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct dvb_usb_device *d; - struct usb_host_interface *alt; - int ret; - - if (intf->num_altsetting < AU6610_ALTSETTING_COUNT) - return -ENODEV; - - ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d, - adapter_nr); - if (ret == 0) { - alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING); - - if (alt == NULL) { - deb_info("%s: no alt found!\n", __func__); - return -ENODEV; - } - ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); - } - - return ret; -} - -static struct usb_device_id au6610_table [] = { - { USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, au6610_table); - -static struct dvb_usb_device_properties au6610_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - - .size_of_priv = 0, - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = au6610_zl10353_frontend_attach, - .tuner_attach = au6610_qt1010_tuner_attach, - - .stream = { - .type = USB_ISOC, - .count = 5, - .endpoint = 0x82, - .u = { - .isoc = { - .framesperurb = 40, - .framesize = 942, - .interval = 1, - } - } - }, - } - }, - - .i2c_algo = &au6610_i2c_algo, - - .num_device_descs = 1, - .devices = { - { - .name = "Sigmatek DVB-110 DVB-T USB2.0", - .cold_ids = {NULL}, - .warm_ids = {&au6610_table[0], NULL}, - }, - } -}; - -static struct usb_driver au6610_driver = { - .name = "dvb_usb_au6610", - .probe = au6610_probe, - .disconnect = dvb_usb_device_exit, - .id_table = au6610_table, -}; - -/* module stuff */ -static int __init au6610_module_init(void) -{ - int ret; - - ret = usb_register(&au6610_driver); - if (ret) - err("usb_register failed. Error number %d", ret); - - return ret; -} - -static void __exit au6610_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&au6610_driver); -} - -module_init(au6610_module_init); -module_exit(au6610_module_exit); - -MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); -MODULE_DESCRIPTION("Driver for Alcor Micro AU6610 DVB-T USB2.0"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/au6610.h b/drivers/media/dvb/dvb-usb/au6610.h deleted file mode 100644 index 7849abe2c61..00000000000 --- a/drivers/media/dvb/dvb-usb/au6610.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * DVB USB Linux driver for Alcor Micro AU6610 DVB-T USB2.0. - * - * Copyright (C) 2006 Antti Palosaari <crope@iki.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _DVB_USB_AU6610_H_ -#define _DVB_USB_AU6610_H_ - -#define DVB_USB_LOG_PREFIX "au6610" -#include "dvb-usb.h" - -#define deb_info(args...) dprintk(dvb_usb_au6610_debug, 0x01, args) - -#define AU6610_REQ_I2C_WRITE 0x14 -#define AU6610_REQ_I2C_READ 0x13 -#define AU6610_REQ_USB_WRITE 0x16 -#define AU6610_REQ_USB_READ 0x15 - -#define AU6610_USB_TIMEOUT 1000 - -#define AU6610_ALTSETTING_COUNT 6 -#define AU6610_ALTSETTING 5 - -#endif diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c deleted file mode 100644 index 80e37a0d089..00000000000 --- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * TerraTec Cinergy T2/qanu USB2 DVB-T adapter. - * - * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi) - * - * Based on the dvb-usb-framework code and the - * original Terratec Cinergy T2 driver by: - * - * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and - * Holger Waechtler <holger@qanu.de> - * - * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "cinergyT2.h" - - -/* debug */ -int dvb_usb_cinergyt2_debug; - -module_param_named(debug, dvb_usb_cinergyt2_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info, xfer=2, rc=4 " - "(or-able))."); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct cinergyt2_state { - u8 rc_counter; -}; - -/* We are missing a release hook with usb_device data */ -static struct dvb_usb_device *cinergyt2_usb_device; - -static struct dvb_usb_device_properties cinergyt2_properties; - -static int cinergyt2_streaming_ctrl(struct dvb_usb_adapter *adap, int enable) -{ - char buf[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 }; - char result[64]; - return dvb_usb_generic_rw(adap->dev, buf, sizeof(buf), result, - sizeof(result), 0); -} - -static int cinergyt2_power_ctrl(struct dvb_usb_device *d, int enable) -{ - char buf[] = { CINERGYT2_EP1_SLEEP_MODE, enable ? 0 : 1 }; - char state[3]; - return dvb_usb_generic_rw(d, buf, sizeof(buf), state, sizeof(state), 0); -} - -static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) -{ - char query[] = { CINERGYT2_EP1_GET_FIRMWARE_VERSION }; - char state[3]; - int ret; - - adap->fe = cinergyt2_fe_attach(adap->dev); - - ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state, - sizeof(state), 0); - if (ret < 0) { - deb_rc("cinergyt2_power_ctrl() Failed to retrieve sleep " - "state info\n"); - } - - /* Copy this pointer as we are gonna need it in the release phase */ - cinergyt2_usb_device = adap->dev; - - return 0; -} - -static struct dvb_usb_rc_key cinergyt2_rc_keys[] = { - { 0x04, 0x01, KEY_POWER }, - { 0x04, 0x02, KEY_1 }, - { 0x04, 0x03, KEY_2 }, - { 0x04, 0x04, KEY_3 }, - { 0x04, 0x05, KEY_4 }, - { 0x04, 0x06, KEY_5 }, - { 0x04, 0x07, KEY_6 }, - { 0x04, 0x08, KEY_7 }, - { 0x04, 0x09, KEY_8 }, - { 0x04, 0x0a, KEY_9 }, - { 0x04, 0x0c, KEY_0 }, - { 0x04, 0x0b, KEY_VIDEO }, - { 0x04, 0x0d, KEY_REFRESH }, - { 0x04, 0x0e, KEY_SELECT }, - { 0x04, 0x0f, KEY_EPG }, - { 0x04, 0x10, KEY_UP }, - { 0x04, 0x14, KEY_DOWN }, - { 0x04, 0x11, KEY_LEFT }, - { 0x04, 0x13, KEY_RIGHT }, - { 0x04, 0x12, KEY_OK }, - { 0x04, 0x15, KEY_TEXT }, - { 0x04, 0x16, KEY_INFO }, - { 0x04, 0x17, KEY_RED }, - { 0x04, 0x18, KEY_GREEN }, - { 0x04, 0x19, KEY_YELLOW }, - { 0x04, 0x1a, KEY_BLUE }, - { 0x04, 0x1c, KEY_VOLUMEUP }, - { 0x04, 0x1e, KEY_VOLUMEDOWN }, - { 0x04, 0x1d, KEY_MUTE }, - { 0x04, 0x1b, KEY_CHANNELUP }, - { 0x04, 0x1f, KEY_CHANNELDOWN }, - { 0x04, 0x40, KEY_PAUSE }, - { 0x04, 0x4c, KEY_PLAY }, - { 0x04, 0x58, KEY_RECORD }, - { 0x04, 0x54, KEY_PREVIOUS }, - { 0x04, 0x48, KEY_STOP }, - { 0x04, 0x5c, KEY_NEXT } -}; - -/* Number of keypresses to ignore before detect repeating */ -#define RC_REPEAT_DELAY 3 - -static int repeatable_keys[] = { - KEY_UP, - KEY_DOWN, - KEY_LEFT, - KEY_RIGHT, - KEY_VOLUMEUP, - KEY_VOLUMEDOWN, - KEY_CHANNELUP, - KEY_CHANNELDOWN -}; - -static int cinergyt2_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct cinergyt2_state *st = d->priv; - u8 key[5] = {0, 0, 0, 0, 0}, cmd = CINERGYT2_EP1_GET_RC_EVENTS; - int i; - - *state = REMOTE_NO_KEY_PRESSED; - - dvb_usb_generic_rw(d, &cmd, 1, key, sizeof(key), 0); - if (key[4] == 0xff) { - /* key repeat */ - st->rc_counter++; - if (st->rc_counter > RC_REPEAT_DELAY) { - for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) { - if (d->last_event == repeatable_keys[i]) { - *state = REMOTE_KEY_REPEAT; - *event = d->last_event; - deb_rc("repeat key, event %x\n", - *event); - return 0; - } - } - deb_rc("repeated key (non repeatable)\n"); - } - return 0; - } - - /* hack to pass checksum on the custom field */ - key[2] = ~key[1]; - dvb_usb_nec_rc_key_to_event(d, key, event, state); - if (key[0] != 0) { - if (*event != d->last_event) - st->rc_counter = 0; - - deb_rc("key: %x %x %x %x %x\n", - key[0], key[1], key[2], key[3], key[4]); - } - return 0; -} - -static int cinergyt2_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &cinergyt2_properties, - THIS_MODULE, NULL, adapter_nr); -} - - -static struct usb_device_id cinergyt2_usb_table[] = { - { USB_DEVICE(USB_VID_TERRATEC, 0x0038) }, - { 0 } -}; - -MODULE_DEVICE_TABLE(usb, cinergyt2_usb_table); - -static struct dvb_usb_device_properties cinergyt2_properties = { - .size_of_priv = sizeof(struct cinergyt2_state), - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cinergyt2_streaming_ctrl, - .frontend_attach = cinergyt2_frontend_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - } - }, - - .power_ctrl = cinergyt2_power_ctrl, - - .rc_interval = 50, - .rc_key_map = cinergyt2_rc_keys, - .rc_key_map_size = ARRAY_SIZE(cinergyt2_rc_keys), - .rc_query = cinergyt2_rc_query, - - .generic_bulk_ctrl_endpoint = 1, - - .num_device_descs = 1, - .devices = { - { .name = "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver", - .cold_ids = {NULL}, - .warm_ids = { &cinergyt2_usb_table[0], NULL }, - }, - { NULL }, - } -}; - - -static struct usb_driver cinergyt2_driver = { - .name = "cinergyT2", - .probe = cinergyt2_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = cinergyt2_usb_table -}; - -static int __init cinergyt2_usb_init(void) -{ - int err; - - err = usb_register(&cinergyt2_driver); - if (err) { - err("usb_register() failed! (err %i)\n", err); - return err; - } - return 0; -} - -static void __exit cinergyt2_usb_exit(void) -{ - usb_deregister(&cinergyt2_driver); -} - -module_init(cinergyt2_usb_init); -module_exit(cinergyt2_usb_exit); - -MODULE_DESCRIPTION("Terratec Cinergy T2 DVB-T driver"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tomi Orava"); diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c deleted file mode 100644 index 649f25cca49..00000000000 --- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * TerraTec Cinergy T2/qanu USB2 DVB-T adapter. - * - * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi) - * - * Based on the dvb-usb-framework code and the - * original Terratec Cinergy T2 driver by: - * - * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and - * Holger Waechtler <holger@qanu.de> - * - * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "cinergyT2.h" - - -/** - * convert linux-dvb frontend parameter set into TPS. - * See ETSI ETS-300744, section 4.6.2, table 9 for details. - * - * This function is probably reusable and may better get placed in a support - * library. - * - * We replace errornous fields by default TPS fields (the ones with value 0). - */ - -static uint16_t compute_tps(struct dvb_frontend_parameters *p) -{ - struct dvb_ofdm_parameters *op = &p->u.ofdm; - uint16_t tps = 0; - - switch (op->code_rate_HP) { - case FEC_2_3: - tps |= (1 << 7); - break; - case FEC_3_4: - tps |= (2 << 7); - break; - case FEC_5_6: - tps |= (3 << 7); - break; - case FEC_7_8: - tps |= (4 << 7); - break; - case FEC_1_2: - case FEC_AUTO: - default: - /* tps |= (0 << 7) */; - } - - switch (op->code_rate_LP) { - case FEC_2_3: - tps |= (1 << 4); - break; - case FEC_3_4: - tps |= (2 << 4); - break; - case FEC_5_6: - tps |= (3 << 4); - break; - case FEC_7_8: - tps |= (4 << 4); - break; - case FEC_1_2: - case FEC_AUTO: - default: - /* tps |= (0 << 4) */; - } - - switch (op->constellation) { - case QAM_16: - tps |= (1 << 13); - break; - case QAM_64: - tps |= (2 << 13); - break; - case QPSK: - default: - /* tps |= (0 << 13) */; - } - - switch (op->transmission_mode) { - case TRANSMISSION_MODE_8K: - tps |= (1 << 0); - break; - case TRANSMISSION_MODE_2K: - default: - /* tps |= (0 << 0) */; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_16: - tps |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - tps |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - tps |= (3 << 2); - break; - case GUARD_INTERVAL_1_32: - default: - /* tps |= (0 << 2) */; - } - - switch (op->hierarchy_information) { - case HIERARCHY_1: - tps |= (1 << 10); - break; - case HIERARCHY_2: - tps |= (2 << 10); - break; - case HIERARCHY_4: - tps |= (3 << 10); - break; - case HIERARCHY_NONE: - default: - /* tps |= (0 << 10) */; - } - - return tps; -} - -struct cinergyt2_fe_state { - struct dvb_frontend fe; - struct dvb_usb_device *d; -}; - -static int cinergyt2_fe_read_status(struct dvb_frontend *fe, - fe_status_t *status) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg result; - u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&result, - sizeof(result), 0); - if (ret < 0) - return ret; - - *status = 0; - - if (0xffff - le16_to_cpu(result.gain) > 30) - *status |= FE_HAS_SIGNAL; - if (result.lock_bits & (1 << 6)) - *status |= FE_HAS_LOCK; - if (result.lock_bits & (1 << 5)) - *status |= FE_HAS_SYNC; - if (result.lock_bits & (1 << 4)) - *status |= FE_HAS_CARRIER; - if (result.lock_bits & (1 << 1)) - *status |= FE_HAS_VITERBI; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int cinergyt2_fe_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, - sizeof(status), 0); - if (ret < 0) - return ret; - - *ber = le32_to_cpu(status.viterbi_error_rate); - return 0; -} - -static int cinergyt2_fe_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - u8 cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (u8 *)&status, - sizeof(status), 0); - if (ret < 0) { - err("cinergyt2_fe_read_unc_blocks() Failed! (Error=%d)\n", - ret); - return ret; - } - *unc = le32_to_cpu(status.uncorrected_block_count); - return 0; -} - -static int cinergyt2_fe_read_signal_strength(struct dvb_frontend *fe, - u16 *strength) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, - sizeof(status), 0); - if (ret < 0) { - err("cinergyt2_fe_read_signal_strength() Failed!" - " (Error=%d)\n", ret); - return ret; - } - *strength = (0xffff - le16_to_cpu(status.gain)); - return 0; -} - -static int cinergyt2_fe_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_get_status_msg status; - char cmd[] = { CINERGYT2_EP1_GET_TUNER_STATUS }; - int ret; - - ret = dvb_usb_generic_rw(state->d, cmd, sizeof(cmd), (char *)&status, - sizeof(status), 0); - if (ret < 0) { - err("cinergyt2_fe_read_snr() Failed! (Error=%d)\n", ret); - return ret; - } - *snr = (status.snr << 8) | status.snr; - return 0; -} - -static int cinergyt2_fe_init(struct dvb_frontend *fe) -{ - return 0; -} - -static int cinergyt2_fe_sleep(struct dvb_frontend *fe) -{ - deb_info("cinergyt2_fe_sleep() Called\n"); - return 0; -} - -static int cinergyt2_fe_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 800; - return 0; -} - -static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - struct dvbt_set_parameters_msg param; - char result[2]; - int err; - - param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; - param.tps = cpu_to_le16(compute_tps(fep)); - param.freq = cpu_to_le32(fep->frequency / 1000); - param.bandwidth = 8 - fep->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; - - err = dvb_usb_generic_rw(state->d, - (char *)¶m, sizeof(param), - result, sizeof(result), 0); - if (err < 0) - err("cinergyt2_fe_set_frontend() Failed! err=%d\n", err); - - return (err < 0) ? err : 0; -} - -static int cinergyt2_fe_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - -static void cinergyt2_fe_release(struct dvb_frontend *fe) -{ - struct cinergyt2_fe_state *state = fe->demodulator_priv; - if (state != NULL) - kfree(state); -} - -static struct dvb_frontend_ops cinergyt2_fe_ops; - -struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) -{ - struct cinergyt2_fe_state *s = kzalloc(sizeof( - struct cinergyt2_fe_state), GFP_KERNEL); - if (s == NULL) - return NULL; - - s->d = d; - memcpy(&s->fe.ops, &cinergyt2_fe_ops, sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; - return &s->fe; -} - - -static struct dvb_frontend_ops cinergyt2_fe_ops = { - .info = { - .name = DRIVER_NAME, - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 - | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 - | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 - | FE_CAN_FEC_AUTO | FE_CAN_QPSK - | FE_CAN_QAM_16 | FE_CAN_QAM_64 - | FE_CAN_QAM_AUTO - | FE_CAN_TRANSMISSION_MODE_AUTO - | FE_CAN_GUARD_INTERVAL_AUTO - | FE_CAN_HIERARCHY_AUTO - | FE_CAN_RECOVER - | FE_CAN_MUTE_TS - }, - - .release = cinergyt2_fe_release, - - .init = cinergyt2_fe_init, - .sleep = cinergyt2_fe_sleep, - - .set_frontend = cinergyt2_fe_set_frontend, - .get_frontend = cinergyt2_fe_get_frontend, - .get_tune_settings = cinergyt2_fe_get_tune_settings, - - .read_status = cinergyt2_fe_read_status, - .read_ber = cinergyt2_fe_read_ber, - .read_signal_strength = cinergyt2_fe_read_signal_strength, - .read_snr = cinergyt2_fe_read_snr, - .read_ucblocks = cinergyt2_fe_read_unc_blocks, -}; diff --git a/drivers/media/dvb/dvb-usb/cinergyT2.h b/drivers/media/dvb/dvb-usb/cinergyT2.h deleted file mode 100644 index 84efe03771e..00000000000 --- a/drivers/media/dvb/dvb-usb/cinergyT2.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * TerraTec Cinergy T2/qanu USB2 DVB-T adapter. - * - * Copyright (C) 2007 Tomi Orava (tomimo@ncircle.nullnet.fi) - * - * Based on the dvb-usb-framework code and the - * original Terratec Cinergy T2 driver by: - * - * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and - * Holger Waechtler <holger@qanu.de> - * - * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _DVB_USB_CINERGYT2_H_ -#define _DVB_USB_CINERGYT2_H_ - -#include <linux/usb/input.h> - -#define DVB_USB_LOG_PREFIX "cinergyT2" -#include "dvb-usb.h" - -#define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver" - -extern int dvb_usb_cinergyt2_debug; - -#define deb_info(args...) dprintk(dvb_usb_cinergyt2_debug, 0x001, args) -#define deb_xfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x002, args) -#define deb_pll(args...) dprintk(dvb_usb_cinergyt2_debug, 0x004, args) -#define deb_ts(args...) dprintk(dvb_usb_cinergyt2_debug, 0x008, args) -#define deb_err(args...) dprintk(dvb_usb_cinergyt2_debug, 0x010, args) -#define deb_rc(args...) dprintk(dvb_usb_cinergyt2_debug, 0x020, args) -#define deb_fw(args...) dprintk(dvb_usb_cinergyt2_debug, 0x040, args) -#define deb_mem(args...) dprintk(dvb_usb_cinergyt2_debug, 0x080, args) -#define deb_uxfer(args...) dprintk(dvb_usb_cinergyt2_debug, 0x100, args) - - - -enum cinergyt2_ep1_cmd { - CINERGYT2_EP1_PID_TABLE_RESET = 0x01, - CINERGYT2_EP1_PID_SETUP = 0x02, - CINERGYT2_EP1_CONTROL_STREAM_TRANSFER = 0x03, - CINERGYT2_EP1_SET_TUNER_PARAMETERS = 0x04, - CINERGYT2_EP1_GET_TUNER_STATUS = 0x05, - CINERGYT2_EP1_START_SCAN = 0x06, - CINERGYT2_EP1_CONTINUE_SCAN = 0x07, - CINERGYT2_EP1_GET_RC_EVENTS = 0x08, - CINERGYT2_EP1_SLEEP_MODE = 0x09, - CINERGYT2_EP1_GET_FIRMWARE_VERSION = 0x0A -}; - - -struct dvbt_get_status_msg { - uint32_t freq; - uint8_t bandwidth; - uint16_t tps; - uint8_t flags; - __le16 gain; - uint8_t snr; - __le32 viterbi_error_rate; - uint32_t rs_error_rate; - __le32 uncorrected_block_count; - uint8_t lock_bits; - uint8_t prev_lock_bits; -} __attribute__((packed)); - - -struct dvbt_set_parameters_msg { - uint8_t cmd; - __le32 freq; - uint8_t bandwidth; - __le16 tps; - uint8_t flags; -} __attribute__((packed)); - - -extern struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d); - -#endif /* _DVB_USB_CINERGYT2_H_ */ - diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c deleted file mode 100644 index 406d7fba369..00000000000 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ /dev/null @@ -1,1855 +0,0 @@ -/* DVB USB compliant linux driver for Conexant USB reference design. - * - * The Conexant reference design I saw on their website was only for analogue - * capturing (using the cx25842). The box I took to write this driver (reverse - * engineered) is the one labeled Medion MD95700. In addition to the cx25842 - * for analogue capturing it also has a cx22702 DVB-T demodulator on the main - * board. Besides it has a atiremote (X10) and a USB2.0 hub onboard. - * - * Maybe it is a little bit premature to call this driver cxusb, but I assume - * the USB protocol is identical or at least inherited from the reference - * design, so it can be reused for the "analogue-only" device (if it will - * appear at all). - * - * TODO: Use the cx25840-driver for the analogue part - * - * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) - * Copyright (C) 2006 Michael Krufky (mkrufky@linuxtv.org) - * Copyright (C) 2006, 2007 Chris Pascoe (c.pascoe@itee.uq.edu.au) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include <media/tuner.h> -#include <linux/vmalloc.h> - -#include "cxusb.h" - -#include "cx22702.h" -#include "lgdt330x.h" -#include "mt352.h" -#include "mt352_priv.h" -#include "zl10353.h" -#include "tuner-xc2028.h" -#include "tuner-simple.h" -#include "mxl5005s.h" -#include "dib7000p.h" -#include "dib0070.h" -#include "lgs8gl5.h" - -/* debug */ -static int dvb_usb_cxusb_debug; -module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define deb_info(args...) dprintk(dvb_usb_cxusb_debug, 0x03, args) -#define deb_i2c(args...) dprintk(dvb_usb_cxusb_debug, 0x02, args) - -static int cxusb_ctrl_msg(struct dvb_usb_device *d, - u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) -{ - int wo = (rbuf == NULL || rlen == 0); /* write-only */ - u8 sndbuf[1+wlen]; - memset(sndbuf, 0, 1+wlen); - - sndbuf[0] = cmd; - memcpy(&sndbuf[1], wbuf, wlen); - if (wo) - return dvb_usb_generic_write(d, sndbuf, 1+wlen); - else - return dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0); -} - -/* GPIO */ -static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff) -{ - struct cxusb_state *st = d->priv; - u8 o[2], i; - - if (st->gpio_write_state[GPIO_TUNER] == onoff) - return; - - o[0] = GPIO_TUNER; - o[1] = onoff; - cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - - if (i != 0x01) - deb_info("gpio_write failed.\n"); - - st->gpio_write_state[GPIO_TUNER] = onoff; -} - -static int cxusb_bluebird_gpio_rw(struct dvb_usb_device *d, u8 changemask, - u8 newval) -{ - u8 o[2], gpio_state; - int rc; - - o[0] = 0xff & ~changemask; /* mask of bits to keep */ - o[1] = newval & changemask; /* new values for bits */ - - rc = cxusb_ctrl_msg(d, CMD_BLUEBIRD_GPIO_RW, o, 2, &gpio_state, 1); - if (rc < 0 || (gpio_state & changemask) != (newval & changemask)) - deb_info("bluebird_gpio_write failed.\n"); - - return rc < 0 ? rc : gpio_state; -} - -static void cxusb_bluebird_gpio_pulse(struct dvb_usb_device *d, u8 pin, int low) -{ - cxusb_bluebird_gpio_rw(d, pin, low ? 0 : pin); - msleep(5); - cxusb_bluebird_gpio_rw(d, pin, low ? pin : 0); -} - -static void cxusb_nano2_led(struct dvb_usb_device *d, int onoff) -{ - cxusb_bluebird_gpio_rw(d, 0x40, onoff ? 0 : 0x40); -} - -static int cxusb_d680_dmb_gpio_tuner(struct dvb_usb_device *d, - u8 addr, int onoff) -{ - u8 o[2] = {addr, onoff}; - u8 i; - int rc; - - rc = cxusb_ctrl_msg(d, CMD_GPIO_WRITE, o, 2, &i, 1); - - if (rc < 0) - return rc; - if (i == 0x01) - return 0; - else { - deb_info("gpio_write failed.\n"); - return -EIO; - } -} - -/* I2C */ -static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - - if (d->udev->descriptor.idVendor == USB_VID_MEDION) - switch (msg[i].addr) { - case 0x63: - cxusb_gpio_tuner(d, 0); - break; - default: - cxusb_gpio_tuner(d, 1); - break; - } - - if (msg[i].flags & I2C_M_RD) { - /* read only */ - u8 obuf[3], ibuf[1+msg[i].len]; - obuf[0] = 0; - obuf[1] = msg[i].len; - obuf[2] = msg[i].addr; - if (cxusb_ctrl_msg(d, CMD_I2C_READ, - obuf, 3, - ibuf, 1+msg[i].len) < 0) { - warn("i2c read failed"); - break; - } - memcpy(msg[i].buf, &ibuf[1], msg[i].len); - } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) && - msg[i].addr == msg[i+1].addr) { - /* write to then read from same address */ - u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len]; - obuf[0] = msg[i].len; - obuf[1] = msg[i+1].len; - obuf[2] = msg[i].addr; - memcpy(&obuf[3], msg[i].buf, msg[i].len); - - if (cxusb_ctrl_msg(d, CMD_I2C_READ, - obuf, 3+msg[i].len, - ibuf, 1+msg[i+1].len) < 0) - break; - - if (ibuf[0] != 0x08) - deb_i2c("i2c read may have failed\n"); - - memcpy(msg[i+1].buf, &ibuf[1], msg[i+1].len); - - i++; - } else { - /* write only */ - u8 obuf[2+msg[i].len], ibuf; - obuf[0] = msg[i].addr; - obuf[1] = msg[i].len; - memcpy(&obuf[2], msg[i].buf, msg[i].len); - - if (cxusb_ctrl_msg(d, CMD_I2C_WRITE, obuf, - 2+msg[i].len, &ibuf,1) < 0) - break; - if (ibuf != 0x08) - deb_i2c("i2c write may have failed\n"); - } - } - - mutex_unlock(&d->i2c_mutex); - return i == num ? num : -EREMOTEIO; -} - -static u32 cxusb_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm cxusb_i2c_algo = { - .master_xfer = cxusb_i2c_xfer, - .functionality = cxusb_i2c_func, -}; - -static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 b = 0; - if (onoff) - return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); - else - return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); -} - -static int cxusb_aver_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - int ret; - if (!onoff) - return cxusb_ctrl_msg(d, CMD_POWER_OFF, NULL, 0, NULL, 0); - if (d->state == DVB_USB_STATE_INIT && - usb_set_interface(d->udev, 0, 0) < 0) - err("set interface failed"); - do {} while (!(ret = cxusb_ctrl_msg(d, CMD_POWER_ON, NULL, 0, NULL, 0)) && - !(ret = cxusb_ctrl_msg(d, 0x15, NULL, 0, NULL, 0)) && - !(ret = cxusb_ctrl_msg(d, 0x17, NULL, 0, NULL, 0)) && 0); - if (!ret) { - /* FIXME: We don't know why, but we need to configure the - * lgdt3303 with the register settings below on resume */ - int i; - u8 buf, bufs[] = { - 0x0e, 0x2, 0x00, 0x7f, - 0x0e, 0x2, 0x02, 0xfe, - 0x0e, 0x2, 0x02, 0x01, - 0x0e, 0x2, 0x00, 0x03, - 0x0e, 0x2, 0x0d, 0x40, - 0x0e, 0x2, 0x0e, 0x87, - 0x0e, 0x2, 0x0f, 0x8e, - 0x0e, 0x2, 0x10, 0x01, - 0x0e, 0x2, 0x14, 0xd7, - 0x0e, 0x2, 0x47, 0x88, - }; - msleep(20); - for (i = 0; i < sizeof(bufs)/sizeof(u8); i += 4/sizeof(u8)) { - ret = cxusb_ctrl_msg(d, CMD_I2C_WRITE, - bufs+i, 4, &buf, 1); - if (ret) - break; - if (buf != 0x8) - return -EREMOTEIO; - } - } - return ret; -} - -static int cxusb_bluebird_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 b = 0; - if (onoff) - return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); - else - return 0; -} - -static int cxusb_nano2_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - int rc = 0; - - rc = cxusb_power_ctrl(d, onoff); - if (!onoff) - cxusb_nano2_led(d, 0); - - return rc; -} - -static int cxusb_d680_dmb_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - int ret; - u8 b; - ret = cxusb_power_ctrl(d, onoff); - if (!onoff) - return ret; - - msleep(128); - cxusb_ctrl_msg(d, CMD_DIGITAL, NULL, 0, &b, 1); - msleep(100); - return ret; -} - -static int cxusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - u8 buf[2] = { 0x03, 0x00 }; - if (onoff) - cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, buf, 2, NULL, 0); - else - cxusb_ctrl_msg(adap->dev, CMD_STREAMING_OFF, NULL, 0, NULL, 0); - - return 0; -} - -static int cxusb_aver_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - if (onoff) - cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_ON, NULL, 0, NULL, 0); - else - cxusb_ctrl_msg(adap->dev, CMD_AVER_STREAM_OFF, - NULL, 0, NULL, 0); - return 0; -} - -static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) -{ - int ep = d->props.generic_bulk_ctrl_endpoint; - const int timeout = 100; - const int junk_len = 32; - u8 *junk; - int rd_count; - - /* Discard remaining data in video pipe */ - junk = kmalloc(junk_len, GFP_KERNEL); - if (!junk) - return; - while (1) { - if (usb_bulk_msg(d->udev, - usb_rcvbulkpipe(d->udev, ep), - junk, junk_len, &rd_count, timeout) < 0) - break; - if (!rd_count) - break; - } - kfree(junk); -} - -static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) -{ - struct usb_data_stream_properties *p = &d->props.adapter[0].stream; - const int timeout = 100; - const int junk_len = p->u.bulk.buffersize; - u8 *junk; - int rd_count; - - /* Discard remaining data in video pipe */ - junk = kmalloc(junk_len, GFP_KERNEL); - if (!junk) - return; - while (1) { - if (usb_bulk_msg(d->udev, - usb_rcvbulkpipe(d->udev, p->endpoint), - junk, junk_len, &rd_count, timeout) < 0) - break; - if (!rd_count) - break; - } - kfree(junk); -} - -static int cxusb_d680_dmb_streaming_ctrl( - struct dvb_usb_adapter *adap, int onoff) -{ - if (onoff) { - u8 buf[2] = { 0x03, 0x00 }; - cxusb_d680_dmb_drain_video(adap->dev); - return cxusb_ctrl_msg(adap->dev, CMD_STREAMING_ON, - buf, sizeof(buf), NULL, 0); - } else { - int ret = cxusb_ctrl_msg(adap->dev, - CMD_STREAMING_OFF, NULL, 0, NULL, 0); - return ret; - } -} - -static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - u8 ircode[4]; - int i; - - cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == ircode[2] && - keymap[i].data == ircode[3]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - - return 0; - } - } - - return 0; -} - -static int cxusb_bluebird2_rc_query(struct dvb_usb_device *d, u32 *event, - int *state) -{ - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - u8 ircode[4]; - int i; - struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, - .buf = ircode, .len = 4 }; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - if (cxusb_i2c_xfer(&d->i2c_adap, &msg, 1) != 1) - return 0; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == ircode[1] && - keymap[i].data == ircode[2]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - - return 0; - } - } - - return 0; -} - -static int cxusb_d680_dmb_rc_query(struct dvb_usb_device *d, u32 *event, - int *state) -{ - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - u8 ircode[2]; - int i; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - if (cxusb_ctrl_msg(d, 0x10, NULL, 0, ircode, 2) < 0) - return 0; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == ircode[0] && - keymap[i].data == ircode[1]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - - return 0; - } - } - - return 0; -} - -static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { - { 0xfe, 0x02, KEY_TV }, - { 0xfe, 0x0e, KEY_MP3 }, - { 0xfe, 0x1a, KEY_DVD }, - { 0xfe, 0x1e, KEY_FAVORITES }, - { 0xfe, 0x16, KEY_SETUP }, - { 0xfe, 0x46, KEY_POWER2 }, - { 0xfe, 0x0a, KEY_EPG }, - { 0xfe, 0x49, KEY_BACK }, - { 0xfe, 0x4d, KEY_MENU }, - { 0xfe, 0x51, KEY_UP }, - { 0xfe, 0x5b, KEY_LEFT }, - { 0xfe, 0x5f, KEY_RIGHT }, - { 0xfe, 0x53, KEY_DOWN }, - { 0xfe, 0x5e, KEY_OK }, - { 0xfe, 0x59, KEY_INFO }, - { 0xfe, 0x55, KEY_TAB }, - { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */ - { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */ - { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */ - { 0xfe, 0x15, KEY_VOLUMEUP }, - { 0xfe, 0x05, KEY_VOLUMEDOWN }, - { 0xfe, 0x11, KEY_CHANNELUP }, - { 0xfe, 0x09, KEY_CHANNELDOWN }, - { 0xfe, 0x52, KEY_CAMERA }, - { 0xfe, 0x5a, KEY_TUNER }, /* Live */ - { 0xfe, 0x19, KEY_OPEN }, - { 0xfe, 0x0b, KEY_1 }, - { 0xfe, 0x17, KEY_2 }, - { 0xfe, 0x1b, KEY_3 }, - { 0xfe, 0x07, KEY_4 }, - { 0xfe, 0x50, KEY_5 }, - { 0xfe, 0x54, KEY_6 }, - { 0xfe, 0x48, KEY_7 }, - { 0xfe, 0x4c, KEY_8 }, - { 0xfe, 0x58, KEY_9 }, - { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */ - { 0xfe, 0x03, KEY_0 }, - { 0xfe, 0x1f, KEY_ZOOM }, - { 0xfe, 0x43, KEY_REWIND }, - { 0xfe, 0x47, KEY_PLAYPAUSE }, - { 0xfe, 0x4f, KEY_FASTFORWARD }, - { 0xfe, 0x57, KEY_MUTE }, - { 0xfe, 0x0d, KEY_STOP }, - { 0xfe, 0x01, KEY_RECORD }, - { 0xfe, 0x4e, KEY_POWER }, -}; - -static struct dvb_usb_rc_key dvico_portable_rc_keys[] = { - { 0xfc, 0x02, KEY_SETUP }, /* Profile */ - { 0xfc, 0x43, KEY_POWER2 }, - { 0xfc, 0x06, KEY_EPG }, - { 0xfc, 0x5a, KEY_BACK }, - { 0xfc, 0x05, KEY_MENU }, - { 0xfc, 0x47, KEY_INFO }, - { 0xfc, 0x01, KEY_TAB }, - { 0xfc, 0x42, KEY_PREVIOUSSONG },/* Replay */ - { 0xfc, 0x49, KEY_VOLUMEUP }, - { 0xfc, 0x09, KEY_VOLUMEDOWN }, - { 0xfc, 0x54, KEY_CHANNELUP }, - { 0xfc, 0x0b, KEY_CHANNELDOWN }, - { 0xfc, 0x16, KEY_CAMERA }, - { 0xfc, 0x40, KEY_TUNER }, /* ATV/DTV */ - { 0xfc, 0x45, KEY_OPEN }, - { 0xfc, 0x19, KEY_1 }, - { 0xfc, 0x18, KEY_2 }, - { 0xfc, 0x1b, KEY_3 }, - { 0xfc, 0x1a, KEY_4 }, - { 0xfc, 0x58, KEY_5 }, - { 0xfc, 0x59, KEY_6 }, - { 0xfc, 0x15, KEY_7 }, - { 0xfc, 0x14, KEY_8 }, - { 0xfc, 0x17, KEY_9 }, - { 0xfc, 0x44, KEY_ANGLE }, /* Aspect */ - { 0xfc, 0x55, KEY_0 }, - { 0xfc, 0x07, KEY_ZOOM }, - { 0xfc, 0x0a, KEY_REWIND }, - { 0xfc, 0x08, KEY_PLAYPAUSE }, - { 0xfc, 0x4b, KEY_FASTFORWARD }, - { 0xfc, 0x5b, KEY_MUTE }, - { 0xfc, 0x04, KEY_STOP }, - { 0xfc, 0x56, KEY_RECORD }, - { 0xfc, 0x57, KEY_POWER }, - { 0xfc, 0x41, KEY_UNKNOWN }, /* INPUT */ - { 0xfc, 0x00, KEY_UNKNOWN }, /* HD */ -}; - -static struct dvb_usb_rc_key d680_dmb_rc_keys[] = { - { 0x00, 0x38, KEY_UNKNOWN }, /* TV/AV */ - { 0x08, 0x0c, KEY_ZOOM }, - { 0x08, 0x00, KEY_0 }, - { 0x00, 0x01, KEY_1 }, - { 0x08, 0x02, KEY_2 }, - { 0x00, 0x03, KEY_3 }, - { 0x08, 0x04, KEY_4 }, - { 0x00, 0x05, KEY_5 }, - { 0x08, 0x06, KEY_6 }, - { 0x00, 0x07, KEY_7 }, - { 0x08, 0x08, KEY_8 }, - { 0x00, 0x09, KEY_9 }, - { 0x00, 0x0a, KEY_MUTE }, - { 0x08, 0x29, KEY_BACK }, - { 0x00, 0x12, KEY_CHANNELUP }, - { 0x08, 0x13, KEY_CHANNELDOWN }, - { 0x00, 0x2b, KEY_VOLUMEUP }, - { 0x08, 0x2c, KEY_VOLUMEDOWN }, - { 0x00, 0x20, KEY_UP }, - { 0x08, 0x21, KEY_DOWN }, - { 0x00, 0x11, KEY_LEFT }, - { 0x08, 0x10, KEY_RIGHT }, - { 0x00, 0x0d, KEY_OK }, - { 0x08, 0x1f, KEY_RECORD }, - { 0x00, 0x17, KEY_PLAYPAUSE }, - { 0x08, 0x16, KEY_PLAYPAUSE }, - { 0x00, 0x0b, KEY_STOP }, - { 0x08, 0x27, KEY_FASTFORWARD }, - { 0x00, 0x26, KEY_REWIND }, - { 0x08, 0x1e, KEY_UNKNOWN }, /* Time Shift */ - { 0x00, 0x0e, KEY_UNKNOWN }, /* Snapshot */ - { 0x08, 0x2d, KEY_UNKNOWN }, /* Mouse Cursor */ - { 0x00, 0x0f, KEY_UNKNOWN }, /* Minimize/Maximize */ - { 0x08, 0x14, KEY_UNKNOWN }, /* Shuffle */ - { 0x00, 0x25, KEY_POWER }, -}; - -static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) -{ - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; - static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; - static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; - - mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(200); - mt352_write(fe, reset, sizeof(reset)); - mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); - - mt352_write(fe, agc_cfg, sizeof(agc_cfg)); - mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); - mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - - return 0; -} - -static int cxusb_mt352_demod_init(struct dvb_frontend* fe) -{ /* used in both lgz201 and th7579 */ - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; - static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; - static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; - - mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(200); - mt352_write(fe, reset, sizeof(reset)); - mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); - - mt352_write(fe, agc_cfg, sizeof(agc_cfg)); - mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); - mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - return 0; -} - -static struct cx22702_config cxusb_cx22702_config = { - .demod_address = 0x63, - .output_mode = CX22702_PARALLEL_OUTPUT, -}; - -static struct lgdt330x_config cxusb_lgdt3303_config = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, -}; - -static struct lgdt330x_config cxusb_aver_lgdt3303_config = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, - .clock_polarity_flip = 2, -}; - -static struct mt352_config cxusb_dee1601_config = { - .demod_address = 0x0f, - .demod_init = cxusb_dee1601_demod_init, -}; - -static struct zl10353_config cxusb_zl10353_dee1601_config = { - .demod_address = 0x0f, - .parallel_ts = 1, -}; - -static struct mt352_config cxusb_mt352_config = { - /* used in both lgz201 and th7579 */ - .demod_address = 0x0f, - .demod_init = cxusb_mt352_demod_init, -}; - -static struct zl10353_config cxusb_zl10353_xc3028_config = { - .demod_address = 0x0f, - .if2 = 45600, - .no_tuner = 1, - .parallel_ts = 1, -}; - -static struct mt352_config cxusb_mt352_xc3028_config = { - .demod_address = 0x0f, - .if2 = 4560, - .no_tuner = 1, - .demod_init = cxusb_mt352_demod_init, -}; - -/* FIXME: needs tweaking */ -static struct mxl5005s_config aver_a868r_tuner = { - .i2c_address = 0x63, - .if_freq = 6000000UL, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_C, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -/* FIXME: needs tweaking */ -static struct mxl5005s_config d680_dmb_tuner = { - .i2c_address = 0x63, - .if_freq = 36125000UL, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_C, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -/* Callbacks for DVB USB */ -static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(simple_tuner_attach, adap->fe, - &adap->dev->i2c_adap, 0x61, - TUNER_PHILIPS_FMD1216ME_MK3); - return 0; -} - -static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(dvb_pll_attach, adap->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); - return 0; -} - -static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(dvb_pll_attach, adap->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, - &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); - return 0; -} - -static int dvico_bluebird_xc2028_callback(void *ptr, int component, - int command, int arg) -{ - struct dvb_usb_adapter *adap = ptr; - struct dvb_usb_device *d = adap->dev; - - switch (command) { - case XC2028_TUNER_RESET: - deb_info("%s: XC2028_TUNER_RESET %d\n", __func__, arg); - cxusb_bluebird_gpio_pulse(d, 0x01, 1); - break; - case XC2028_RESET_CLK: - deb_info("%s: XC2028_RESET_CLK %d\n", __func__, arg); - break; - default: - deb_info("%s: unknown command %d, arg %d\n", __func__, - command, arg); - return -EINVAL; - } - - return 0; -} - -static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &adap->dev->i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - /* FIXME: generalize & move to common area */ - adap->fe->callback = dvico_bluebird_xc2028_callback; - - fe = dvb_attach(xc2028_attach, adap->fe, &cfg); - if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) - return -EIO; - - fe->ops.tuner_ops.set_config(fe, &ctl); - - return 0; -} - -static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(mxl5005s_attach, adap->fe, - &adap->dev->i2c_adap, &aver_a868r_tuner); - return 0; -} - -static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_frontend *fe; - fe = dvb_attach(mxl5005s_attach, adap->fe, - &adap->dev->i2c_adap, &d680_dmb_tuner); - return (fe == NULL) ? -EIO : 0; -} - -static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) -{ - u8 b; - if (usb_set_interface(adap->dev->udev, 0, 6) < 0) - err("set interface failed"); - - 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) - return 0; - - return -EIO; -} - -static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (usb_set_interface(adap->dev->udev, 0, 7) < 0) - err("set interface failed"); - - 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) - return 0; - - return -EIO; -} - -static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) -{ - adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config, - &adap->dev->i2c_adap); - if (adap->fe != NULL) - return 0; - - return -EIO; -} - -static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) -{ - /* used in both lgz201 and th7579 */ - if (usb_set_interface(adap->dev->udev, 0, 0) < 0) - err("set interface failed"); - - 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) - return 0; - - return -EIO; -} - -static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (usb_set_interface(adap->dev->udev, 0, 0) < 0) - err("set interface failed"); - - 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)) - return 0; - - return -EIO; -} - -static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) -{ - u8 ircode[4]; - int i; - struct i2c_msg msg = { .addr = 0x6b, .flags = I2C_M_RD, - .buf = ircode, .len = 4 }; - - if (usb_set_interface(adap->dev->udev, 0, 1) < 0) - err("set interface failed"); - - cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - - /* reset the tuner and demodulator */ - cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); - 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) - return -EIO; - - /* try to determine if there is no IR decoder on the I2C bus */ - for (i = 0; adap->dev->props.rc_key_map != NULL && i < 5; i++) { - msleep(20); - if (cxusb_i2c_xfer(&adap->dev->i2c_adap, &msg, 1) != 1) - goto no_IR; - if (ircode[0] == 0 && ircode[1] == 0) - continue; - if (ircode[2] + ircode[3] != 0xff) { -no_IR: - adap->dev->props.rc_key_map = NULL; - info("No IR receiver detected on this device."); - break; - } - } - - return 0; -} - -static struct dibx000_agc_config dib7070_agc_config = { - .band_caps = BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, - - /* - * P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, - * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 - */ - .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | - (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), - .inv_gain = 600, - .time_stabiliz = 10, - .alpha_level = 0, - .thlock = 118, - .wbd_inv = 0, - .wbd_ref = 3530, - .wbd_sel = 1, - .wbd_alpha = 5, - .agc1_max = 65535, - .agc1_min = 0, - .agc2_max = 65535, - .agc2_min = 0, - .agc1_pt1 = 0, - .agc1_pt2 = 40, - .agc1_pt3 = 183, - .agc1_slope1 = 206, - .agc1_slope2 = 255, - .agc2_pt1 = 72, - .agc2_pt2 = 152, - .agc2_slope1 = 88, - .agc2_slope2 = 90, - .alpha_mant = 17, - .alpha_exp = 27, - .beta_mant = 23, - .beta_exp = 51, - .perform_agc_softsplit = 0, -}; - -static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { - .internal = 60000, - .sampling = 15000, - .pll_prediv = 1, - .pll_ratio = 20, - .pll_range = 3, - .pll_reset = 1, - .pll_bypass = 0, - .enable_refdiv = 0, - .bypclk_div = 0, - .IO_CLK_en_core = 1, - .ADClkSrc = 1, - .modulo = 2, - /* refsel, sel, freq_15k */ - .sad_cfg = (3 << 14) | (1 << 12) | (524 << 0), - .ifreq = (0 << 25) | 0, - .timf = 20452225, - .xtal_hz = 12000000, -}; - -static struct dib7000p_config cxusb_dualdig4_rev2_config = { - .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK, - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 1, - .agc = &dib7070_agc_config, - .bw = &dib7070_bw_config_12_mhz, - .tuner_is_baseband = 1, - .spur_protect = 1, - - .gpio_dir = 0xfcef, - .gpio_val = 0x0110, - - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .hostbus_diversity = 1, -}; - -static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (usb_set_interface(adap->dev->udev, 0, 1) < 0) - err("set interface failed"); - - cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - - cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); - - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &cxusb_dualdig4_rev2_config); - - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, - &cxusb_dualdig4_rev2_config); - if (adap->fe == NULL) - return -EIO; - - return 0; -} - -static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) -{ - return dib7000p_set_gpio(fe, 8, 0, !onoff); -} - -static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) -{ - return 0; -} - -static struct dib0070_config dib7070p_dib0070_config = { - .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, - .reset = dib7070_tuner_reset, - .sleep = dib7070_tuner_sleep, - .clock_khz = 12000, -}; - -struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, - struct dvb_frontend_parameters *); -}; - -static int dib7070_set_param_override(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dib0700_adapter_state *state = adap->priv; - - u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); - switch (band) { - case BAND_VHF: offset = 950; break; - default: - case BAND_UHF: offset = 550; break; - } - - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - - return state->set_param_save(fe, fep); -} - -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, - DIBX000_I2C_INTERFACE_TUNER, 1); - - if (dvb_attach(dib0070_attach, adap->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; - return 0; -} - -static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (usb_set_interface(adap->dev->udev, 0, 1) < 0) - err("set interface failed"); - - cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - - /* reset the tuner and demodulator */ - cxusb_bluebird_gpio_rw(adap->dev, 0x04, 0); - 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) - return 0; - - if ((adap->fe = dvb_attach(mt352_attach, - &cxusb_mt352_xc3028_config, - &adap->dev->i2c_adap)) != NULL) - return 0; - - return -EIO; -} - -static struct lgs8gl5_config lgs8gl5_cfg = { - .demod_address = 0x19, -}; - -static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dvb_usb_device *d = adap->dev; - int n; - - /* Select required USB configuration */ - if (usb_set_interface(d->udev, 0, 0) < 0) - err("set interface failed"); - - /* Unblock all USB pipes */ - usb_clear_halt(d->udev, - usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); - 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)); - - /* Drain USB pipes to avoid hang after reboot */ - for (n = 0; n < 5; n++) { - cxusb_d680_dmb_drain_message(d); - cxusb_d680_dmb_drain_video(d); - msleep(200); - } - - /* Reset the tuner */ - if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 0) < 0) { - err("clear tuner gpio failed"); - return -EIO; - } - msleep(100); - if (cxusb_d680_dmb_gpio_tuner(d, 0x07, 1) < 0) { - err("set tuner gpio failed"); - return -EIO; - } - msleep(100); - - /* Attach frontend */ - adap->fe = dvb_attach(lgs8gl5_attach, &lgs8gl5_cfg, &d->i2c_adap); - if (adap->fe == NULL) - return -EIO; - - return 0; -} - -/* - * DViCO has shipped two devices with the same USB ID, but only one of them - * needs a firmware download. Check the device class details to see if they - * have non-default values to decide whether the device is actually cold or - * not, and forget a match if it turns out we selected the wrong device. - */ -static int bluebird_fx2_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - int wascold = *cold; - - *cold = udev->descriptor.bDeviceClass == 0xff && - udev->descriptor.bDeviceSubClass == 0xff && - udev->descriptor.bDeviceProtocol == 0xff; - - if (*cold && !wascold) - *desc = NULL; - - return 0; -} - -/* - * DViCO bluebird firmware needs the "warm" product ID to be patched into the - * firmware file before download. - */ - -static const int dvico_firmware_id_offsets[] = { 6638, 3204 }; -static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, - const struct firmware *fw) -{ - int pos; - - for (pos = 0; pos < ARRAY_SIZE(dvico_firmware_id_offsets); pos++) { - int idoff = dvico_firmware_id_offsets[pos]; - - if (fw->size < idoff + 4) - continue; - - if (fw->data[idoff] == (USB_VID_DVICO & 0xff) && - fw->data[idoff + 1] == USB_VID_DVICO >> 8) { - struct firmware new_fw; - u8 *new_fw_data = vmalloc(fw->size); - int ret; - - if (!new_fw_data) - return -ENOMEM; - - memcpy(new_fw_data, fw->data, fw->size); - new_fw.size = fw->size; - new_fw.data = new_fw_data; - - new_fw_data[idoff + 2] = - le16_to_cpu(udev->descriptor.idProduct) + 1; - new_fw_data[idoff + 3] = - le16_to_cpu(udev->descriptor.idProduct) >> 8; - - ret = usb_cypress_load_firmware(udev, &new_fw, - CYPRESS_FX2); - vfree(new_fw_data); - return ret; - } - } - - return -EINVAL; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties cxusb_medion_properties; -static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties; -static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties; -static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties; -static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties; -static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties; -static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties; -static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties; -static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties; -static struct dvb_usb_device_properties cxusb_aver_a868r_properties; -static struct dvb_usb_device_properties cxusb_d680_dmb_properties; - -static int cxusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - if (0 == dvb_usb_device_init(intf, &cxusb_medion_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgh064f_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dee1601_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_bluebird_lgz201_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dtt7579_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_bluebird_dualdig4_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_bluebird_nano2_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, - &cxusb_bluebird_nano2_needsfirmware_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_aver_a868r_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, - &cxusb_bluebird_dualdig4_rev2_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &cxusb_d680_dmb_properties, - THIS_MODULE, NULL, adapter_nr) || - 0) - return 0; - - return -EINVAL; -} - -static struct usb_device_id cxusb_table [] = { - { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LGZ201_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_TH7579_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM) }, - { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_A868R) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2) }, - { USB_DEVICE(USB_VID_CONEXANT, USB_PID_CONEXANT_D680_DMB) }, - {} /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, cxusb_table); - -static struct dvb_usb_device_properties cxusb_medion_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_cx22702_frontend_attach, - .tuner_attach = cxusb_fmd1216me_tuner_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - - }, - }, - .power_ctrl = cxusb_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "Medion MD95700 (MDUSBTV-HYBRID)", - { NULL }, - { &cxusb_table[0], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-01.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - /* use usb alt setting 0 for EP4 transfer (dvb-t), - use usb alt setting 7 for EP2 transfer (atsc) */ - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_lgdt3303_frontend_attach, - .tuner_attach = cxusb_lgh064f_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_bluebird_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV5 USB Gold", - { &cxusb_table[1], NULL }, - { &cxusb_table[2], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-01.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - /* use usb alt setting 0 for EP4 transfer (dvb-t), - use usb alt setting 7 for EP2 transfer (atsc) */ - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_dee1601_frontend_attach, - .tuner_attach = cxusb_dee1601_tuner_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x04, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_bluebird_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .rc_interval = 150, - .rc_key_map = dvico_mce_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), - .rc_query = cxusb_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 3, - .devices = { - { "DViCO FusionHDTV DVB-T Dual USB", - { &cxusb_table[3], NULL }, - { &cxusb_table[4], NULL }, - }, - { "DigitalNow DVB-T Dual USB", - { &cxusb_table[9], NULL }, - { &cxusb_table[10], NULL }, - }, - { "DViCO FusionHDTV DVB-T Dual Digital 2", - { &cxusb_table[11], NULL }, - { &cxusb_table[12], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-01.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - /* use usb alt setting 0 for EP4 transfer (dvb-t), - use usb alt setting 7 for EP2 transfer (atsc) */ - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 2, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_mt352_frontend_attach, - .tuner_attach = cxusb_lgz201_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x04, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - .power_ctrl = cxusb_bluebird_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T USB (LGZ201)", - { &cxusb_table[5], NULL }, - { &cxusb_table[6], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-01.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - /* use usb alt setting 0 for EP4 transfer (dvb-t), - use usb alt setting 7 for EP2 transfer (atsc) */ - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_mt352_frontend_attach, - .tuner_attach = cxusb_dtt7579_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x04, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - .power_ctrl = cxusb_bluebird_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T USB (TH7579)", - { &cxusb_table[7], NULL }, - { &cxusb_table[8], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_dualdig4_frontend_attach, - .tuner_attach = cxusb_dvico_xc3028_tuner_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = dvico_mce_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), - .rc_query = cxusb_bluebird2_rc_query, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T Dual Digital 4", - { NULL }, - { &cxusb_table[13], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .identify_state = bluebird_fx2_identify_state, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_nano2_frontend_attach, - .tuner_attach = cxusb_dvico_xc3028_tuner_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_nano2_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_bluebird2_rc_query, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T NANO2", - { NULL }, - { &cxusb_table[14], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-02.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - .identify_state = bluebird_fx2_identify_state, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_streaming_ctrl, - .frontend_attach = cxusb_nano2_frontend_attach, - .tuner_attach = cxusb_dvico_xc3028_tuner_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_nano2_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = dvico_portable_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_portable_rc_keys), - .rc_query = cxusb_rc_query, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T NANO2 w/o firmware", - { &cxusb_table[14], NULL }, - { &cxusb_table[15], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_aver_streaming_ctrl, - .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, - .tuner_attach = cxusb_mxl5003s_tuner_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x04, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - - }, - }, - .power_ctrl = cxusb_aver_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "AVerMedia AVerTVHD Volar (A868R)", - { NULL }, - { &cxusb_table[16], NULL }, - }, - } -}; - -static -struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .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, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - }, - }, - - .power_ctrl = cxusb_bluebird_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = dvico_mce_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), - .rc_query = cxusb_rc_query, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T Dual Digital 4 (rev 2)", - { NULL }, - { &cxusb_table[17], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .size_of_priv = sizeof(struct cxusb_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, - .frontend_attach = cxusb_d680_dmb_frontend_attach, - .tuner_attach = cxusb_d680_dmb_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - }, - }, - - .power_ctrl = cxusb_d680_dmb_power_ctrl, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .rc_interval = 100, - .rc_key_map = d680_dmb_rc_keys, - .rc_key_map_size = ARRAY_SIZE(d680_dmb_rc_keys), - .rc_query = cxusb_d680_dmb_rc_query, - - .num_device_descs = 1, - .devices = { - { - "Conexant DMB-TH Stick", - { NULL }, - { &cxusb_table[18], NULL }, - }, - } -}; - -static struct usb_driver cxusb_driver = { - .name = "dvb_usb_cxusb", - .probe = cxusb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = cxusb_table, -}; - -/* module stuff */ -static int __init cxusb_module_init(void) -{ - int result; - if ((result = usb_register(&cxusb_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit cxusb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&cxusb_driver); -} - -module_init (cxusb_module_init); -module_exit (cxusb_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); -MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); -MODULE_DESCRIPTION("Driver for Conexant USB2.0 hybrid reference design"); -MODULE_VERSION("1.0-alpha"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h deleted file mode 100644 index 1a51eafd31b..00000000000 --- a/drivers/media/dvb/dvb-usb/cxusb.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _DVB_USB_CXUSB_H_ -#define _DVB_USB_CXUSB_H_ - -#define DVB_USB_LOG_PREFIX "cxusb" -#include "dvb-usb.h" - -/* usb commands - some of it are guesses, don't have a reference yet */ -#define CMD_BLUEBIRD_GPIO_RW 0x05 - -#define CMD_I2C_WRITE 0x08 -#define CMD_I2C_READ 0x09 - -#define CMD_GPIO_READ 0x0d -#define CMD_GPIO_WRITE 0x0e -#define GPIO_TUNER 0x02 - -#define CMD_POWER_OFF 0xdc -#define CMD_POWER_ON 0xde - -#define CMD_STREAMING_ON 0x36 -#define CMD_STREAMING_OFF 0x37 - -#define CMD_AVER_STREAM_ON 0x18 -#define CMD_AVER_STREAM_OFF 0x19 - -#define CMD_GET_IR_CODE 0x47 - -#define CMD_ANALOG 0x50 -#define CMD_DIGITAL 0x51 - -struct cxusb_state { - u8 gpio_write_state[3]; -}; - -#endif diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h deleted file mode 100644 index 8b544fe79b0..00000000000 --- a/drivers/media/dvb/dvb-usb/dib0700.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Linux driver for devices based on the DiBcom DiB0700 USB bridge - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * Copyright (C) 2005-6 DiBcom, SA - */ -#ifndef _DIB0700_H_ -#define _DIB0700_H_ - -#define DVB_USB_LOG_PREFIX "dib0700" -#include "dvb-usb.h" - -#include "dib07x0.h" - -extern int dvb_usb_dib0700_debug; -#define deb_info(args...) dprintk(dvb_usb_dib0700_debug,0x01,args) -#define deb_fw(args...) dprintk(dvb_usb_dib0700_debug,0x02,args) -#define deb_fwdata(args...) dprintk(dvb_usb_dib0700_debug,0x04,args) -#define deb_data(args...) dprintk(dvb_usb_dib0700_debug,0x08,args) - -#define REQUEST_I2C_READ 0x2 -#define REQUEST_I2C_WRITE 0x3 -#define REQUEST_POLL_RC 0x4 /* deprecated in firmware v1.20 */ -#define REQUEST_JUMPRAM 0x8 -#define REQUEST_SET_CLOCK 0xB -#define REQUEST_SET_GPIO 0xC -#define REQUEST_ENABLE_VIDEO 0xF - // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) - // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) - // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) -#define REQUEST_SET_RC 0x11 -#define REQUEST_NEW_I2C_READ 0x12 -#define REQUEST_NEW_I2C_WRITE 0x13 -#define REQUEST_GET_VERSION 0x15 - -struct dib0700_state { - u8 channel_state; - u16 mt2060_if1[2]; - u8 rc_toggle; - u8 rc_counter; - u8 rc_func_version; - u8 is_dib7000pc; - u8 fw_use_new_i2c_api; - u8 disable_streaming_master_mode; -}; - -extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, - u32 *romversion, u32 *ramversion, u32 *fwtype); -extern int dib0700_set_gpio(struct dvb_usb_device *, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val); -extern int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3); -extern int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen); -extern int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw); -extern int dib0700_rc_setup(struct dvb_usb_device *d); -extern int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); -extern struct i2c_algorithm dib0700_i2c_algo; -extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, int *cold); - -extern int dib0700_device_count; -extern int dvb_usb_dib0700_ir_proto; -extern struct dvb_usb_device_properties dib0700_devices[]; -extern struct usb_device_id dib0700_usb_id_table[]; - -#endif diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c deleted file mode 100644 index 200b215f4d8..00000000000 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ /dev/null @@ -1,451 +0,0 @@ -/* Linux driver for devices based on the DiBcom DiB0700 USB bridge - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * Copyright (C) 2005-6 DiBcom, SA - */ -#include "dib0700.h" - -/* debug */ -int dvb_usb_dib0700_debug; -module_param_named(debug,dvb_usb_dib0700_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=fw,4=fwdata,8=data (or-able))." DVB_USB_DEBUG_STATUS); - -int dvb_usb_dib0700_ir_proto = 1; -module_param(dvb_usb_dib0700_ir_proto, int, 0644); -MODULE_PARM_DESC(dvb_usb_dib0700_ir_proto, "set ir protocol (0=NEC, 1=RC5 (default), 2=RC6)."); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - - -int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, - u32 *romversion, u32 *ramversion, u32 *fwtype) -{ - u8 b[16]; - int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), - REQUEST_GET_VERSION, - USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, - b, sizeof(b), USB_CTRL_GET_TIMEOUT); - *hwversion = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; - *romversion = (b[4] << 24) | (b[5] << 16) | (b[6] << 8) | b[7]; - *ramversion = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11]; - *fwtype = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15]; - return ret; -} - -/* expecting rx buffer: request data[0] data[1] ... data[2] */ -static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen) -{ - int status; - - deb_data(">>> "); - debug_dump(tx,txlen,deb_data); - - status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), - tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen, - USB_CTRL_GET_TIMEOUT); - - if (status != txlen) - deb_data("ep 0 write error (status = %d, len: %d)\n",status,txlen); - - return status < 0 ? status : 0; -} - -/* expecting tx buffer: request data[0] ... data[n] (n <= 4) */ -int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen) -{ - u16 index, value; - int status; - - if (txlen < 2) { - err("tx buffer length is smaller than 2. Makes no sense."); - return -EINVAL; - } - if (txlen > 4) { - err("tx buffer length is larger than 4. Not supported."); - return -EINVAL; - } - - deb_data(">>> "); - debug_dump(tx,txlen,deb_data); - - value = ((txlen - 2) << 8) | tx[1]; - index = 0; - if (txlen > 2) - index |= (tx[2] << 8); - if (txlen > 3) - index |= tx[3]; - - status = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), tx[0], - USB_TYPE_VENDOR | USB_DIR_IN, value, index, rx, rxlen, - USB_CTRL_GET_TIMEOUT); - - if (status < 0) - deb_info("ep 0 read error (status = %d)\n",status); - - deb_data("<<< "); - debug_dump(rx,rxlen,deb_data); - - return status; /* length in case of success */ -} - -int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val) -{ - u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) }; - return dib0700_ctrl_wr(d,buf,3); -} - -/* - * I2C master xfer function (supported in 1.20 firmware) - */ -static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, - int num) -{ - /* The new i2c firmware messages are more reliable and in particular - properly support i2c read calls not preceded by a write */ - - struct dvb_usb_device *d = i2c_get_adapdata(adap); - uint8_t bus_mode = 1; /* 0=eeprom bus, 1=frontend bus */ - uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */ - uint8_t en_start = 0; - uint8_t en_stop = 0; - uint8_t buf[255]; /* TBV: malloc ? */ - int result, i; - - /* Ensure nobody else hits the i2c bus while we're sending our - sequence of messages, (such as the remote control thread) */ - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - if (i == 0) { - /* First message in the transaction */ - en_start = 1; - } else if (!(msg[i].flags & I2C_M_NOSTART)) { - /* Device supports repeated-start */ - en_start = 1; - } else { - /* Not the first packet and device doesn't support - repeated start */ - en_start = 0; - } - if (i == (num - 1)) { - /* Last message in the transaction */ - en_stop = 1; - } - - if (msg[i].flags & I2C_M_RD) { - /* Read request */ - u16 index, value; - uint8_t i2c_dest; - - i2c_dest = (msg[i].addr << 1); - value = ((en_start << 7) | (en_stop << 6) | - (msg[i].len & 0x3F)) << 8 | i2c_dest; - /* I2C ctrl + FE bus; */ - index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30); - - result = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev, 0), - REQUEST_NEW_I2C_READ, - USB_TYPE_VENDOR | USB_DIR_IN, - value, index, msg[i].buf, - msg[i].len, - USB_CTRL_GET_TIMEOUT); - if (result < 0) { - err("i2c read error (status = %d)\n", result); - break; - } - } else { - /* Write request */ - buf[0] = REQUEST_NEW_I2C_WRITE; - buf[1] = (msg[i].addr << 1); - buf[2] = (en_start << 7) | (en_stop << 6) | - (msg[i].len & 0x3F); - /* I2C ctrl + FE bus; */ - buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30); - /* The Actual i2c payload */ - memcpy(&buf[4], msg[i].buf, msg[i].len); - - result = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev, 0), - REQUEST_NEW_I2C_WRITE, - USB_TYPE_VENDOR | USB_DIR_OUT, - 0, 0, buf, msg[i].len + 4, - USB_CTRL_GET_TIMEOUT); - if (result < 0) { - err("i2c write error (status = %d)\n", result); - break; - } - } - } - mutex_unlock(&d->i2c_mutex); - return i; -} - -/* - * I2C master xfer function (pre-1.20 firmware) - */ -static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, - struct i2c_msg *msg, int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i,len; - u8 buf[255]; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* fill in the address */ - buf[1] = (msg[i].addr << 1); - /* fill the buffer */ - memcpy(&buf[2], msg[i].buf, msg[i].len); - - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - buf[0] = REQUEST_I2C_READ; - buf[1] |= 1; - - /* special thing in the current firmware: when length is zero the read-failed */ - if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) { - deb_info("I2C read failed on address %x\n", msg[i].addr); - break; - } - - msg[i+1].len = len; - - i++; - } else { - buf[0] = REQUEST_I2C_WRITE; - if (dib0700_ctrl_wr(d, buf, msg[i].len + 2) < 0) - break; - } - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static int dib0700_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - struct dib0700_state *st = d->priv; - - if (st->fw_use_new_i2c_api == 1) { - /* User running at least fw 1.20 */ - return dib0700_i2c_xfer_new(adap, msg, num); - } else { - /* Use legacy calls */ - return dib0700_i2c_xfer_legacy(adap, msg, num); - } -} - -static u32 dib0700_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -struct i2c_algorithm dib0700_i2c_algo = { - .master_xfer = dib0700_i2c_xfer, - .functionality = dib0700_i2c_func, -}; - -int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, int *cold) -{ - u8 b[16]; - s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), - REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT); - - deb_info("FW GET_VERSION length: %d\n",ret); - - *cold = ret <= 0; - - deb_info("cold: %d\n", *cold); - return 0; -} - -static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, - u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv, - u16 pll_loopdiv, u16 free_div, u16 dsuScaler) -{ - u8 b[10]; - b[0] = REQUEST_SET_CLOCK; - b[1] = (en_pll << 7) | (pll_src << 6) | (pll_range << 5) | (clock_gpio3 << 4); - b[2] = (pll_prediv >> 8) & 0xff; // MSB - b[3] = pll_prediv & 0xff; // LSB - b[4] = (pll_loopdiv >> 8) & 0xff; // MSB - b[5] = pll_loopdiv & 0xff; // LSB - b[6] = (free_div >> 8) & 0xff; // MSB - b[7] = free_div & 0xff; // LSB - b[8] = (dsuScaler >> 8) & 0xff; // MSB - b[9] = dsuScaler & 0xff; // LSB - - return dib0700_ctrl_wr(d, b, 10); -} - -int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) -{ - switch (clk_MHz) { - case 72: dib0700_set_clock(d, 1, 0, 1, clock_out_gp3, 2, 24, 0, 0x4c); break; - default: return -EINVAL; - } - return 0; -} - -static int dib0700_jumpram(struct usb_device *udev, u32 address) -{ - int ret, actlen; - u8 buf[8] = { REQUEST_JUMPRAM, 0, 0, 0, - (address >> 24) & 0xff, - (address >> 16) & 0xff, - (address >> 8) & 0xff, - address & 0xff }; - - if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) { - deb_fw("jumpram to 0x%x failed\n",address); - return ret; - } - if (actlen != 8) { - deb_fw("jumpram to 0x%x failed\n",address); - return -EIO; - } - return 0; -} - -int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw) -{ - struct hexline hx; - int pos = 0, ret, act_len; - - u8 buf[260]; - - while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) { - deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",hx.addr, hx.len, hx.chk); - - buf[0] = hx.len; - buf[1] = (hx.addr >> 8) & 0xff; - buf[2] = hx.addr & 0xff; - buf[3] = hx.type; - memcpy(&buf[4],hx.data,hx.len); - buf[4+hx.len] = hx.chk; - - ret = usb_bulk_msg(udev, - usb_sndbulkpipe(udev, 0x01), - buf, - hx.len + 5, - &act_len, - 1000); - - if (ret < 0) { - err("firmware download failed at %d with %d",pos,ret); - return ret; - } - } - - if (ret == 0) { - /* start the firmware */ - if ((ret = dib0700_jumpram(udev, 0x70000000)) == 0) { - info("firmware started successfully."); - msleep(500); - } - } else - ret = -EIO; - - return ret; -} - -int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - struct dib0700_state *st = adap->dev->priv; - u8 b[4]; - - b[0] = REQUEST_ENABLE_VIDEO; - b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */ - - if (st->disable_streaming_master_mode == 1) - b[2] = 0x00; - else - b[2] = (0x01 << 4); /* Master mode */ - - b[3] = 0x00; - - deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); - - if (onoff) - st->channel_state |= 1 << adap->id; - else - st->channel_state &= ~(1 << adap->id); - - b[2] |= st->channel_state; - - deb_info("data for streaming: %x %x\n",b[1],b[2]); - - return dib0700_ctrl_wr(adap->dev, b, 4); -} - -int dib0700_rc_setup(struct dvb_usb_device *d) -{ - u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0}; - int i = dib0700_ctrl_wr(d, rc_setup, 3); - if (i<0) { - err("ir protocol setup failed"); - return -1; - } - return 0; -} - -static int dib0700_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int i; - struct dvb_usb_device *dev; - - for (i = 0; i < dib0700_device_count; i++) - if (dvb_usb_device_init(intf, &dib0700_devices[i], THIS_MODULE, - &dev, adapter_nr) == 0) - { - dib0700_rc_setup(dev); - return 0; - } - - return -ENODEV; -} - -static struct usb_driver dib0700_driver = { - .name = "dvb_usb_dib0700", - .probe = dib0700_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dib0700_usb_id_table, -}; - -/* module stuff */ -static int __init dib0700_module_init(void) -{ - int result; - info("loaded with support for %d different device-types", dib0700_device_count); - if ((result = usb_register(&dib0700_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit dib0700_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dib0700_driver); -} - -module_init (dib0700_module_init); -module_exit (dib0700_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for devices based on DiBcom DiB0700 - USB bridge"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c deleted file mode 100644 index 39173278891..00000000000 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ /dev/null @@ -1,1753 +0,0 @@ -/* Linux driver for devices based on the DiBcom DiB0700 USB bridge - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * Copyright (C) 2005-7 DiBcom, SA - */ -#include "dib0700.h" - -#include "dib3000mc.h" -#include "dib7000m.h" -#include "dib7000p.h" -#include "mt2060.h" -#include "mt2266.h" -#include "tuner-xc2028.h" -#include "xc5000.h" -#include "s5h1411.h" -#include "dib0070.h" - -static int force_lna_activation; -module_param(force_lna_activation, int, 0644); -MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplifyer(s) (LNA), " - "if applicable for the device (default: 0=automatic/off)."); - -struct dib0700_adapter_state { - int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); -}; - -/* Hauppauge Nova-T 500 (aka Bristol) - * has a LNA on GPIO0 which is enabled by setting 1 */ -static struct mt2060_config bristol_mt2060_config[2] = { - { - .i2c_address = 0x60, - .clock_out = 3, - }, { - .i2c_address = 0x61, - } -}; - - -static struct dibx000_agc_config bristol_dib3000p_mt2060_agc_config = { - .band_caps = BAND_VHF | BAND_UHF, - .setup = (1 << 8) | (5 << 5) | (0 << 4) | (0 << 3) | (0 << 2) | (2 << 0), - - .agc1_max = 42598, - .agc1_min = 17694, - .agc2_max = 45875, - .agc2_min = 0, - - .agc1_pt1 = 0, - .agc1_pt2 = 59, - - .agc1_slope1 = 0, - .agc1_slope2 = 69, - - .agc2_pt1 = 0, - .agc2_pt2 = 59, - - .agc2_slope1 = 111, - .agc2_slope2 = 28, -}; - -static struct dib3000mc_config bristol_dib3000mc_config[2] = { - { .agc = &bristol_dib3000p_mt2060_agc_config, - .max_time = 0x196, - .ln_adc_level = 0x1cc7, - .output_mpeg2_in_188_bytes = 1, - }, - { .agc = &bristol_dib3000p_mt2060_agc_config, - .max_time = 0x196, - .ln_adc_level = 0x1cc7, - .output_mpeg2_in_188_bytes = 1, - } -}; - -static int bristol_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dib0700_state *st = adap->dev->priv; - if (adap->id == 0) { - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10); - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(10); - - if (force_lna_activation) - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - else - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0); - - if (dib3000mc_i2c_enumeration(&adap->dev->i2c_adap, 2, DEFAULT_DIB3000P_I2C_ADDRESS, bristol_dib3000mc_config) != 0) { - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(10); - return -ENODEV; - } - } - st->mt2060_if1[adap->id] = 1220; - return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, - (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0; -} - -static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval) -{ - struct i2c_msg msg[2] = { - { .addr = 0x50, .flags = 0, .buf = &adrs, .len = 1 }, - { .addr = 0x50, .flags = I2C_M_RD, .buf = pval, .len = 1 }, - }; - if (i2c_transfer(adap, msg, 2) != 2) return -EREMOTEIO; - return 0; -} - -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); - 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; -} - -/* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */ - -/* MT226x */ -static struct dibx000_agc_config stk7700d_7000p_mt2266_agc_config[2] = { - { - BAND_UHF, // band_caps - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup - - 1130, // inv_gain - 21, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 0, // wbd_alpha - - 65535, // agc1_max - 33770, // agc1_min - 65535, // agc2_max - 23592, // agc2_min - - 0, // agc1_pt1 - 62, // agc1_pt2 - 255, // agc1_pt3 - 64, // agc1_slope1 - 64, // agc1_slope2 - 132, // agc2_pt1 - 192, // agc2_pt2 - 80, // agc2_slope1 - 80, // agc2_slope2 - - 17, // alpha_mant - 27, // alpha_exp - 23, // beta_mant - 51, // beta_exp - - 1, // perform_agc_softsplit - }, { - BAND_VHF | BAND_LBAND, // band_caps - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=1, P_agc_inv_pwm2=1, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (1 << 11) | (1 << 10) | (1 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup - - 2372, // inv_gain - 21, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 0, // wbd_alpha - - 65535, // agc1_max - 0, // agc1_min - 65535, // agc2_max - 23592, // agc2_min - - 0, // agc1_pt1 - 128, // agc1_pt2 - 128, // agc1_pt3 - 128, // agc1_slope1 - 0, // agc1_slope2 - 128, // agc2_pt1 - 253, // agc2_pt2 - 81, // agc2_slope1 - 0, // agc2_slope2 - - 17, // alpha_mant - 27, // alpha_exp - 23, // beta_mant - 51, // beta_exp - - 1, // perform_agc_softsplit - } -}; - -static struct dibx000_bandwidth_config stk7700d_mt2266_pll_config = { - 60000, 30000, // internal, sampling - 1, 8, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k - 0, // ifreq - 20452225, // timf -}; - -static struct dib7000p_config stk7700d_dib7000p_mt2266_config[] = { - { .output_mpeg2_in_188_bytes = 1, - .hostbus_diversity = 1, - .tuner_is_baseband = 1, - - .agc_config_count = 2, - .agc = stk7700d_7000p_mt2266_agc_config, - .bw = &stk7700d_mt2266_pll_config, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - }, - { .output_mpeg2_in_188_bytes = 1, - .hostbus_diversity = 1, - .tuner_is_baseband = 1, - - .agc_config_count = 2, - .agc = stk7700d_7000p_mt2266_agc_config, - .bw = &stk7700d_mt2266_pll_config, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - } -}; - -static struct mt2266_config stk7700d_mt2266_config[2] = { - { .i2c_address = 0x60 - }, - { .i2c_address = 0x60 - } -}; - -static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (adap->id == 0) { - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config); - } - - adap->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; -} - -static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) -{ - if (adap->id == 0) { - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config); - } - - adap->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; -} - -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, - &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;; -} - -/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */ -static struct dibx000_agc_config xc3028_agc_config = { - BAND_VHF | BAND_UHF, /* band_caps */ - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, - * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | - (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ - - 712, /* inv_gain */ - 21, /* time_stabiliz */ - - 0, /* alpha_level */ - 118, /* thlock */ - - 0, /* wbd_inv */ - 2867, /* wbd_ref */ - 0, /* wbd_sel */ - 2, /* wbd_alpha */ - - 0, /* agc1_max */ - 0, /* agc1_min */ - 39718, /* agc2_max */ - 9930, /* agc2_min */ - 0, /* agc1_pt1 */ - 0, /* agc1_pt2 */ - 0, /* agc1_pt3 */ - 0, /* agc1_slope1 */ - 0, /* agc1_slope2 */ - 0, /* agc2_pt1 */ - 128, /* agc2_pt2 */ - 29, /* agc2_slope1 */ - 29, /* agc2_slope2 */ - - 17, /* alpha_mant */ - 27, /* alpha_exp */ - 23, /* beta_mant */ - 51, /* beta_exp */ - - 1, /* perform_agc_softsplit */ -}; - -/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */ -static struct dibx000_bandwidth_config xc3028_bw_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 << 0), /* sad_cfg: refsel, sel, freq_15k */ - (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ - 20452225, /* timf */ - 30000000, /* xtal_hz */ -}; - -static struct dib7000p_config stk7700ph_dib7700_xc3028_config = { - .output_mpeg2_in_188_bytes = 1, - .tuner_is_baseband = 1, - - .agc_config_count = 1, - .agc = &xc3028_agc_config, - .bw = &xc3028_bw_config, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, -}; - -static int stk7700ph_xc3028_callback(void *ptr, int component, - int command, int arg) -{ - struct dvb_usb_adapter *adap = ptr; - - 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); - break; - case XC2028_RESET_CLK: - break; - default: - err("%s: unknown command %d, arg %d\n", __func__, - command, arg); - return -EINVAL; - } - return 0; -} - -static struct xc2028_ctrl stk7700ph_xc3028_ctrl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_DIBCOM52, -}; - -static struct xc2028_config stk7700ph_xc3028_config = { - .i2c_addr = 0x61, - .ctrl = &stk7700ph_xc3028_ctrl, -}; - -static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; - - if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) && - desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX)) - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); - else - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(20); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(20); - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - msleep(10); - - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &stk7700ph_dib7700_xc3028_config); - - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, - &stk7700ph_dib7700_xc3028_config); - - return adap->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, - DIBX000_I2C_INTERFACE_TUNER, 1); - - stk7700ph_xc3028_config.i2c_adap = tun_i2c; - - /* FIXME: generalize & move to common area */ - adap->fe->callback = stk7700ph_xc3028_callback; - - return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) - == NULL ? -ENODEV : 0; -} - -#define DEFAULT_RC_INTERVAL 50 - -static u8 rc_request[] = { REQUEST_POLL_RC, 0 }; - -/* Number of keypresses to ignore before start repeating */ -#define RC_REPEAT_DELAY 6 -#define RC_REPEAT_DELAY_V1_20 10 - - - -/* Used by firmware versions < 1.20 (deprecated) */ -static int dib0700_rc_query_legacy(struct dvb_usb_device *d, u32 *event, - int *state) -{ - u8 key[4]; - int i; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - struct dib0700_state *st = d->priv; - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - i=dib0700_ctrl_rd(d,rc_request,2,key,4); - if (i<=0) { - err("RC Query Failed"); - return -1; - } - - /* losing half of KEY_0 events from Philipps rc5 remotes.. */ - if (key[0]==0 && key[1]==0 && key[2]==0 && key[3]==0) return 0; - - /* info("%d: %2X %2X %2X %2X",dvb_usb_dib0700_ir_proto,(int)key[3-2],(int)key[3-3],(int)key[3-1],(int)key[3]); */ - - dib0700_rc_setup(d); /* reset ir sensor data to prevent false events */ - - switch (dvb_usb_dib0700_ir_proto) { - case 0: { - /* NEC protocol sends repeat code as 0 0 0 FF */ - if ((key[3-2] == 0x00) && (key[3-3] == 0x00) && - (key[3] == 0xFF)) { - st->rc_counter++; - if (st->rc_counter > RC_REPEAT_DELAY) { - *event = d->last_event; - *state = REMOTE_KEY_PRESSED; - st->rc_counter = RC_REPEAT_DELAY; - } - return 0; - } - for (i=0;i<d->props.rc_key_map_size; i++) { - if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { - st->rc_counter = 0; - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - d->last_event = keymap[i].event; - return 0; - } - } - break; - } - default: { - /* RC-5 protocol changes toggle bit on new keypress */ - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == key[3-2] && keymap[i].data == key[3-3]) { - if (d->last_event == keymap[i].event && - key[3-1] == st->rc_toggle) { - st->rc_counter++; - /* prevents unwanted double hits */ - if (st->rc_counter > RC_REPEAT_DELAY) { - *event = d->last_event; - *state = REMOTE_KEY_PRESSED; - st->rc_counter = RC_REPEAT_DELAY; - } - - return 0; - } - st->rc_counter = 0; - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - st->rc_toggle = key[3-1]; - d->last_event = keymap[i].event; - return 0; - } - } - break; - } - } - err("Unknown remote controller key: %2X %2X %2X %2X", (int) key[3-2], (int) key[3-3], (int) key[3-1], (int) key[3]); - d->last_event = 0; - return 0; -} - -/* This is the structure of the RC response packet starting in firmware 1.20 */ -struct dib0700_rc_response { - u8 report_id; - u8 data_state; - u8 system_msb; - u8 system_lsb; - u8 data; - u8 not_data; -}; - -/* This supports the new IR response format for firmware v1.20 */ -static int dib0700_rc_query_v1_20(struct dvb_usb_device *d, u32 *event, - int *state) -{ - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - struct dib0700_state *st = d->priv; - struct dib0700_rc_response poll_reply; - u8 buf[6]; - int i; - int status; - int actlen; - int found = 0; - - /* Set initial results in case we exit the function early */ - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - /* Firmware v1.20 provides RC data via bulk endpoint 1 */ - status = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 1), buf, - sizeof(buf), &actlen, 50); - if (status < 0) { - /* No data available (meaning no key press) */ - return 0; - } - - if (actlen != sizeof(buf)) { - /* We didn't get back the 6 byte message we expected */ - err("Unexpected RC response size [%d]", actlen); - return -1; - } - - poll_reply.report_id = buf[0]; - poll_reply.data_state = buf[1]; - poll_reply.system_msb = buf[2]; - poll_reply.system_lsb = buf[3]; - poll_reply.data = buf[4]; - poll_reply.not_data = buf[5]; - - /* - info("rid=%02x ds=%02x sm=%02x sl=%02x d=%02x nd=%02x\n", - poll_reply.report_id, poll_reply.data_state, - poll_reply.system_msb, poll_reply.system_lsb, - poll_reply.data, poll_reply.not_data); - */ - - if ((poll_reply.data + poll_reply.not_data) != 0xff) { - /* Key failed integrity check */ - err("key failed integrity check: %02x %02x %02x %02x", - poll_reply.system_msb, poll_reply.system_lsb, - poll_reply.data, poll_reply.not_data); - return -1; - } - - /* Find the key in the map */ - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == poll_reply.system_lsb && - keymap[i].data == poll_reply.data) { - *event = keymap[i].event; - found = 1; - break; - } - } - - if (found == 0) { - err("Unknown remote controller key: %02x %02x %02x %02x", - poll_reply.system_msb, poll_reply.system_lsb, - poll_reply.data, poll_reply.not_data); - d->last_event = 0; - return 0; - } - - if (poll_reply.data_state == 1) { - /* New key hit */ - st->rc_counter = 0; - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - d->last_event = keymap[i].event; - } else if (poll_reply.data_state == 2) { - /* Key repeated */ - st->rc_counter++; - - /* prevents unwanted double hits */ - if (st->rc_counter > RC_REPEAT_DELAY_V1_20) { - *event = d->last_event; - *state = REMOTE_KEY_PRESSED; - st->rc_counter = RC_REPEAT_DELAY_V1_20; - } - } else { - err("Unknown data state [%d]", poll_reply.data_state); - } - - return 0; -} - -static int dib0700_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct dib0700_state *st = d->priv; - - /* Because some people may have improperly named firmware files, - let's figure out whether to use the new firmware call or the legacy - call based on the firmware version embedded in the file */ - if (st->rc_func_version == 0) { - u32 hwver, romver, ramver, fwtype; - int ret = dib0700_get_version(d, &hwver, &romver, &ramver, - &fwtype); - if (ret < 0) { - err("Could not determine version info"); - return -1; - } - if (ramver < 0x10200) - st->rc_func_version = 1; - else - st->rc_func_version = 2; - } - - if (st->rc_func_version == 2) - return dib0700_rc_query_v1_20(d, event, state); - else - return dib0700_rc_query_legacy(d, event, state); -} - -static struct dvb_usb_rc_key dib0700_rc_keys[] = { - /* Key codes for the tiny Pinnacle remote*/ - { 0x07, 0x00, KEY_MUTE }, - { 0x07, 0x01, KEY_MENU }, // Pinnacle logo - { 0x07, 0x39, KEY_POWER }, - { 0x07, 0x03, KEY_VOLUMEUP }, - { 0x07, 0x09, KEY_VOLUMEDOWN }, - { 0x07, 0x06, KEY_CHANNELUP }, - { 0x07, 0x0c, KEY_CHANNELDOWN }, - { 0x07, 0x0f, KEY_1 }, - { 0x07, 0x15, KEY_2 }, - { 0x07, 0x10, KEY_3 }, - { 0x07, 0x18, KEY_4 }, - { 0x07, 0x1b, KEY_5 }, - { 0x07, 0x1e, KEY_6 }, - { 0x07, 0x11, KEY_7 }, - { 0x07, 0x21, KEY_8 }, - { 0x07, 0x12, KEY_9 }, - { 0x07, 0x27, KEY_0 }, - { 0x07, 0x24, KEY_SCREEN }, // 'Square' key - { 0x07, 0x2a, KEY_TEXT }, // 'T' key - { 0x07, 0x2d, KEY_REWIND }, - { 0x07, 0x30, KEY_PLAY }, - { 0x07, 0x33, KEY_FASTFORWARD }, - { 0x07, 0x36, KEY_RECORD }, - { 0x07, 0x3c, KEY_STOP }, - { 0x07, 0x3f, KEY_CANCEL }, // '?' key - /* Key codes for the Terratec Cinergy DT XS Diversity, similar to cinergyT2.c */ - { 0xeb, 0x01, KEY_POWER }, - { 0xeb, 0x02, KEY_1 }, - { 0xeb, 0x03, KEY_2 }, - { 0xeb, 0x04, KEY_3 }, - { 0xeb, 0x05, KEY_4 }, - { 0xeb, 0x06, KEY_5 }, - { 0xeb, 0x07, KEY_6 }, - { 0xeb, 0x08, KEY_7 }, - { 0xeb, 0x09, KEY_8 }, - { 0xeb, 0x0a, KEY_9 }, - { 0xeb, 0x0b, KEY_VIDEO }, - { 0xeb, 0x0c, KEY_0 }, - { 0xeb, 0x0d, KEY_REFRESH }, - { 0xeb, 0x0f, KEY_EPG }, - { 0xeb, 0x10, KEY_UP }, - { 0xeb, 0x11, KEY_LEFT }, - { 0xeb, 0x12, KEY_OK }, - { 0xeb, 0x13, KEY_RIGHT }, - { 0xeb, 0x14, KEY_DOWN }, - { 0xeb, 0x16, KEY_INFO }, - { 0xeb, 0x17, KEY_RED }, - { 0xeb, 0x18, KEY_GREEN }, - { 0xeb, 0x19, KEY_YELLOW }, - { 0xeb, 0x1a, KEY_BLUE }, - { 0xeb, 0x1b, KEY_CHANNELUP }, - { 0xeb, 0x1c, KEY_VOLUMEUP }, - { 0xeb, 0x1d, KEY_MUTE }, - { 0xeb, 0x1e, KEY_VOLUMEDOWN }, - { 0xeb, 0x1f, KEY_CHANNELDOWN }, - { 0xeb, 0x40, KEY_PAUSE }, - { 0xeb, 0x41, KEY_HOME }, - { 0xeb, 0x42, KEY_MENU }, /* DVD Menu */ - { 0xeb, 0x43, KEY_SUBTITLE }, - { 0xeb, 0x44, KEY_TEXT }, /* Teletext */ - { 0xeb, 0x45, KEY_DELETE }, - { 0xeb, 0x46, KEY_TV }, - { 0xeb, 0x47, KEY_DVD }, - { 0xeb, 0x48, KEY_STOP }, - { 0xeb, 0x49, KEY_VIDEO }, - { 0xeb, 0x4a, KEY_AUDIO }, /* Music */ - { 0xeb, 0x4b, KEY_SCREEN }, /* Pic */ - { 0xeb, 0x4c, KEY_PLAY }, - { 0xeb, 0x4d, KEY_BACK }, - { 0xeb, 0x4e, KEY_REWIND }, - { 0xeb, 0x4f, KEY_FASTFORWARD }, - { 0xeb, 0x54, KEY_PREVIOUS }, - { 0xeb, 0x58, KEY_RECORD }, - { 0xeb, 0x5c, KEY_NEXT }, - - /* Key codes for the Haupauge WinTV Nova-TD, copied from nova-t-usb2.c (Nova-T USB2) */ - { 0x1e, 0x00, KEY_0 }, - { 0x1e, 0x01, KEY_1 }, - { 0x1e, 0x02, KEY_2 }, - { 0x1e, 0x03, KEY_3 }, - { 0x1e, 0x04, KEY_4 }, - { 0x1e, 0x05, KEY_5 }, - { 0x1e, 0x06, KEY_6 }, - { 0x1e, 0x07, KEY_7 }, - { 0x1e, 0x08, KEY_8 }, - { 0x1e, 0x09, KEY_9 }, - { 0x1e, 0x0a, KEY_KPASTERISK }, - { 0x1e, 0x0b, KEY_RED }, - { 0x1e, 0x0c, KEY_RADIO }, - { 0x1e, 0x0d, KEY_MENU }, - { 0x1e, 0x0e, KEY_GRAVE }, /* # */ - { 0x1e, 0x0f, KEY_MUTE }, - { 0x1e, 0x10, KEY_VOLUMEUP }, - { 0x1e, 0x11, KEY_VOLUMEDOWN }, - { 0x1e, 0x12, KEY_CHANNEL }, - { 0x1e, 0x14, KEY_UP }, - { 0x1e, 0x15, KEY_DOWN }, - { 0x1e, 0x16, KEY_LEFT }, - { 0x1e, 0x17, KEY_RIGHT }, - { 0x1e, 0x18, KEY_VIDEO }, - { 0x1e, 0x19, KEY_AUDIO }, - { 0x1e, 0x1a, KEY_MEDIA }, - { 0x1e, 0x1b, KEY_EPG }, - { 0x1e, 0x1c, KEY_TV }, - { 0x1e, 0x1e, KEY_NEXT }, - { 0x1e, 0x1f, KEY_BACK }, - { 0x1e, 0x20, KEY_CHANNELUP }, - { 0x1e, 0x21, KEY_CHANNELDOWN }, - { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */ - { 0x1e, 0x25, KEY_OK }, - { 0x1e, 0x29, KEY_BLUE}, - { 0x1e, 0x2e, KEY_GREEN }, - { 0x1e, 0x30, KEY_PAUSE }, - { 0x1e, 0x32, KEY_REWIND }, - { 0x1e, 0x34, KEY_FASTFORWARD }, - { 0x1e, 0x35, KEY_PLAY }, - { 0x1e, 0x36, KEY_STOP }, - { 0x1e, 0x37, KEY_RECORD }, - { 0x1e, 0x38, KEY_YELLOW }, - { 0x1e, 0x3b, KEY_GOTO }, - { 0x1e, 0x3d, KEY_POWER }, - - /* Key codes for the Leadtek Winfast DTV Dongle */ - { 0x00, 0x42, KEY_POWER }, - { 0x07, 0x7c, KEY_TUNER }, - { 0x0f, 0x4e, KEY_PRINT }, /* PREVIEW */ - { 0x08, 0x40, KEY_SCREEN }, /* full screen toggle*/ - { 0x0f, 0x71, KEY_DOT }, /* frequency */ - { 0x07, 0x43, KEY_0 }, - { 0x0c, 0x41, KEY_1 }, - { 0x04, 0x43, KEY_2 }, - { 0x0b, 0x7f, KEY_3 }, - { 0x0e, 0x41, KEY_4 }, - { 0x06, 0x43, KEY_5 }, - { 0x09, 0x7f, KEY_6 }, - { 0x0d, 0x7e, KEY_7 }, - { 0x05, 0x7c, KEY_8 }, - { 0x0a, 0x40, KEY_9 }, - { 0x0e, 0x4e, KEY_CLEAR }, - { 0x04, 0x7c, KEY_CHANNEL }, /* show channel number */ - { 0x0f, 0x41, KEY_LAST }, /* recall */ - { 0x03, 0x42, KEY_MUTE }, - { 0x06, 0x4c, KEY_RESERVED }, /* PIP button*/ - { 0x01, 0x72, KEY_SHUFFLE }, /* SNAPSHOT */ - { 0x0c, 0x4e, KEY_PLAYPAUSE }, /* TIMESHIFT */ - { 0x0b, 0x70, KEY_RECORD }, - { 0x03, 0x7d, KEY_VOLUMEUP }, - { 0x01, 0x7d, KEY_VOLUMEDOWN }, - { 0x02, 0x42, KEY_CHANNELUP }, - { 0x00, 0x7d, KEY_CHANNELDOWN }, - - /* Key codes for Nova-TD "credit card" remote control. */ - { 0x1d, 0x00, KEY_0 }, - { 0x1d, 0x01, KEY_1 }, - { 0x1d, 0x02, KEY_2 }, - { 0x1d, 0x03, KEY_3 }, - { 0x1d, 0x04, KEY_4 }, - { 0x1d, 0x05, KEY_5 }, - { 0x1d, 0x06, KEY_6 }, - { 0x1d, 0x07, KEY_7 }, - { 0x1d, 0x08, KEY_8 }, - { 0x1d, 0x09, KEY_9 }, - { 0x1d, 0x0a, KEY_TEXT }, - { 0x1d, 0x0d, KEY_MENU }, - { 0x1d, 0x0f, KEY_MUTE }, - { 0x1d, 0x10, KEY_VOLUMEUP }, - { 0x1d, 0x11, KEY_VOLUMEDOWN }, - { 0x1d, 0x12, KEY_CHANNEL }, - { 0x1d, 0x14, KEY_UP }, - { 0x1d, 0x15, KEY_DOWN }, - { 0x1d, 0x16, KEY_LEFT }, - { 0x1d, 0x17, KEY_RIGHT }, - { 0x1d, 0x1c, KEY_TV }, - { 0x1d, 0x1e, KEY_NEXT }, - { 0x1d, 0x1f, KEY_BACK }, - { 0x1d, 0x20, KEY_CHANNELUP }, - { 0x1d, 0x21, KEY_CHANNELDOWN }, - { 0x1d, 0x24, KEY_LAST }, - { 0x1d, 0x25, KEY_OK }, - { 0x1d, 0x30, KEY_PAUSE }, - { 0x1d, 0x32, KEY_REWIND }, - { 0x1d, 0x34, KEY_FASTFORWARD }, - { 0x1d, 0x35, KEY_PLAY }, - { 0x1d, 0x36, KEY_STOP }, - { 0x1d, 0x37, KEY_RECORD }, - { 0x1d, 0x3b, KEY_GOTO }, - { 0x1d, 0x3d, KEY_POWER }, -}; - -/* STK7700P: Hauppauge Nova-T Stick, AVerMedia Volar */ -static struct dibx000_agc_config stk7700p_7000m_mt2060_agc_config = { - BAND_UHF | BAND_VHF, // band_caps - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup - - 712, // inv_gain - 41, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 4095, // wbd_ref - 0, // wbd_sel - 0, // wbd_alpha - - 42598, // agc1_max - 17694, // agc1_min - 45875, // agc2_max - 2621, // agc2_min - 0, // agc1_pt1 - 76, // agc1_pt2 - 139, // agc1_pt3 - 52, // agc1_slope1 - 59, // agc1_slope2 - 107, // agc2_pt1 - 172, // agc2_pt2 - 57, // agc2_slope1 - 70, // agc2_slope2 - - 21, // alpha_mant - 25, // alpha_exp - 28, // beta_mant - 48, // beta_exp - - 1, // perform_agc_softsplit - { 0, // split_min - 107, // split_max - 51800, // global_split_min - 24700 // global_split_max - }, -}; - -static struct dibx000_agc_config stk7700p_7000p_mt2060_agc_config = { - BAND_UHF | BAND_VHF, - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), // setup - - 712, // inv_gain - 41, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 4095, // wbd_ref - 0, // wbd_sel - 0, // wbd_alpha - - 42598, // agc1_max - 16384, // agc1_min - 42598, // agc2_max - 0, // agc2_min - - 0, // agc1_pt1 - 137, // agc1_pt2 - 255, // agc1_pt3 - - 0, // agc1_slope1 - 255, // agc1_slope2 - - 0, // agc2_pt1 - 0, // agc2_pt2 - - 0, // agc2_slope1 - 41, // agc2_slope2 - - 15, // alpha_mant - 25, // alpha_exp - - 28, // beta_mant - 48, // beta_exp - - 0, // perform_agc_softsplit -}; - -static struct dibx000_bandwidth_config stk7700p_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 << 0), // sad_cfg: refsel, sel, freq_15k - 60258167, // ifreq - 20452225, // timf - 30000000, // xtal -}; - -static struct dib7000m_config stk7700p_dib7000m_config = { - .dvbt_mode = 1, - .output_mpeg2_in_188_bytes = 1, - .quartz_direct = 1, - - .agc_config_count = 1, - .agc = &stk7700p_7000m_mt2060_agc_config, - .bw = &stk7700p_pll_config, - - .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, -}; - -static struct dib7000p_config stk7700p_dib7000p_config = { - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 1, - .agc = &stk7700p_7000p_mt2060_agc_config, - .bw = &stk7700p_pll_config, - - .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, -}; - -static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dib0700_state *st = adap->dev->priv; - /* unless there is no real power management in DVB - we leave the device on GPIO6 */ - - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); msleep(50); - - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); msleep(10); - dib0700_ctrl_clock(adap->dev, 72, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(100); - - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - - 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); - st->is_dib7000pc = 1; - } else - adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); - - return adap->fe == NULL ? -ENODEV : 0; -} - -static struct mt2060_config stk7700p_mt2060_config = { - 0x60 -}; - -static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap; - struct dib0700_state *st = adap->dev->priv; - struct i2c_adapter *tun_i2c; - 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_STICK)) { - 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); - else - tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); - - return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config, - if1) == NULL ? -ENODEV : 0; -} - -/* DIB7070 generic */ -static struct dibx000_agc_config dib7070_agc_config = { - BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=5, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ - (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), // setup - - 600, // inv_gain - 10, // time_stabiliz - - 0, // alpha_level - 118, // thlock - - 0, // wbd_inv - 3530, // wbd_ref - 1, // wbd_sel - 5, // wbd_alpha - - 65535, // agc1_max - 0, // agc1_min - - 65535, // agc2_max - 0, // agc2_min - - 0, // agc1_pt1 - 40, // agc1_pt2 - 183, // agc1_pt3 - 206, // agc1_slope1 - 255, // agc1_slope2 - 72, // agc2_pt1 - 152, // agc2_pt2 - 88, // agc2_slope1 - 90, // agc2_slope2 - - 17, // alpha_mant - 27, // alpha_exp - 23, // beta_mant - 51, // beta_exp - - 0, // perform_agc_softsplit -}; - -static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) -{ - return dib7000p_set_gpio(fe, 8, 0, !onoff); -} - -static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) -{ - return dib7000p_set_gpio(fe, 9, 0, onoff); -} - -static struct dib0070_config dib7070p_dib0070_config[2] = { - { - .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, - .reset = dib7070_tuner_reset, - .sleep = dib7070_tuner_sleep, - .clock_khz = 12000, - .clock_pad_drive = 4 - }, { - .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, - .reset = dib7070_tuner_reset, - .sleep = dib7070_tuner_sleep, - .clock_khz = 12000, - - } -}; - -static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) -{ - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dib0700_adapter_state *state = adap->priv; - - u16 offset; - u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); - switch (band) { - case BAND_VHF: offset = 950; break; - case BAND_UHF: - default: offset = 550; break; - } - deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe)); - dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe)); - return state->set_param_save(fe, fep); -} - -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); - - if (adap->id == 0) { - if (dvb_attach(dib0070_attach, adap->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) - return -ENODEV; - } - - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override; - return 0; -} - -static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { - 60000, 15000, // internal, sampling - 1, 20, 3, 1, 0, // pll_cfg: prediv, ratio, range, reset, bypass - 0, 0, 1, 1, 2, // misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc, modulo - (3 << 14) | (1 << 12) | (524 << 0), // sad_cfg: refsel, sel, freq_15k - (0 << 25) | 0, // ifreq = 0.000000 MHz - 20452225, // timf - 12000000, // xtal_hz -}; - -static struct dib7000p_config dib7070p_dib7000p_config = { - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 1, - .agc = &dib7070_agc_config, - .bw = &dib7070_bw_config_12_mhz, - .tuner_is_baseband = 1, - .spur_protect = 1, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .hostbus_diversity = 1, -}; - -/* STK7070P */ -static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct usb_device_descriptor *p = &adap->dev->udev->descriptor; - if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && - p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); - else - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - - dib0700_ctrl_clock(adap->dev, 72, 1); - - msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, - &dib7070p_dib7000p_config); - - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, - &dib7070p_dib7000p_config); - return adap->fe == NULL ? -ENODEV : 0; -} - -/* STK7070PD */ -static struct dib7000p_config stk7070pd_dib7000p_config[2] = { - { - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 1, - .agc = &dib7070_agc_config, - .bw = &dib7070_bw_config_12_mhz, - .tuner_is_baseband = 1, - .spur_protect = 1, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .hostbus_diversity = 1, - }, { - .output_mpeg2_in_188_bytes = 1, - - .agc_config_count = 1, - .agc = &dib7070_agc_config, - .bw = &dib7070_bw_config_12_mhz, - .tuner_is_baseband = 1, - .spur_protect = 1, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .hostbus_diversity = 1, - } -}; - -static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) -{ - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - - dib0700_ctrl_clock(adap->dev, 72, 1); - - msleep(10); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(10); - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - - dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config); - - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); - return adap->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; -} - -/* S5H1411 */ -static struct s5h1411_config pinnacle_801e_config = { - .output_mode = S5H1411_PARALLEL_OUTPUT, - .gpio = S5H1411_GPIO_OFF, - .mpeg_timing = S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, - .qam_if = S5H1411_IF_44000, - .vsb_if = S5H1411_IF_44000, - .inversion = S5H1411_INVERSION_OFF, - .status_mode = S5H1411_DEMODLOCKING -}; - -/* Pinnacle PCTV HD Pro 801e GPIOs map: - GPIO0 - currently unknown - GPIO1 - xc5000 tuner reset - GPIO2 - CX25843 sleep - GPIO3 - currently unknown - GPIO4 - currently unknown - GPIO6 - currently unknown - GPIO7 - currently unknown - GPIO9 - currently unknown - GPIO10 - CX25843 reset - */ -static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dib0700_state *st = adap->dev->priv; - - /* Make use of the new i2c functions from FW 1.20 */ - st->fw_use_new_i2c_api = 1; - - /* The s5h1411 requires the dib0700 to not be in master mode */ - st->disable_streaming_master_mode = 1; - - /* All msleep values taken from Windows USB trace */ - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 0); - dib0700_set_gpio(adap->dev, GPIO3, GPIO_OUT, 0); - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); - msleep(400); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); - msleep(60); - dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); - msleep(30); - dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1); - dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 0); - msleep(30); - - /* Put the CX25843 to sleep for now since we're in digital mode */ - 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->dev->i2c_adap); - return adap->fe == NULL ? -ENODEV : 0; -} - -static int dib0700_xc5000_tuner_callback(void *priv, int component, - int command, int arg) -{ - struct dvb_usb_adapter *adap = priv; - - if (command == XC5000_TUNER_RESET) { - /* Reset the tuner */ - dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 0); - msleep(330); /* from Windows USB trace */ - dib0700_set_gpio(adap->dev, GPIO1, GPIO_OUT, 1); - msleep(330); /* from Windows USB trace */ - } else { - err("xc5000: unknown tuner callback command: %d\n", command); - return -EINVAL; - } - - return 0; -} - -static struct xc5000_config s5h1411_xc5000_tunerconfig = { - .i2c_address = 0x64, - .if_khz = 5380, -}; - -static int xc5000_tuner_attach(struct dvb_usb_adapter *adap) -{ - /* FIXME: generalize & move to common area */ - adap->fe->callback = dib0700_xc5000_tuner_callback; - - return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap, - &s5h1411_xc5000_tunerconfig) - == NULL ? -ENODEV : 0; -} - -/* DVB-USB and USB stuff follows */ -struct usb_device_id dib0700_usb_id_table[] = { -/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P_PC) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) }, -/* 5 */ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) }, - { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500) }, - { USB_DEVICE(USB_VID_UNIWILL, USB_PID_UNIWILL_STK7700P) }, - { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) }, -/* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV2000E) }, - { USB_DEVICE(USB_VID_TERRATEC, - USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700D) }, -/* 15 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070P) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV_DVB_T_FLASH) }, - { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7070PD) }, - { USB_DEVICE(USB_VID_PINNACLE, - USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) }, - { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_VIDEOMATE_U500_PC) }, -/* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) }, - { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U7000) }, - { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) }, - { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000) }, - { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3100) }, -/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) }, - { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_USB_XE) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_EXPRESSCARD_320CX) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV72E) }, -/* 30 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73E) }, - { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_EC372S) }, - { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_HT_EXPRESS) }, - { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS) }, - { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_STK7700P_2) }, -/* 35 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009) }, - { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_3) }, - { USB_DEVICE(USB_VID_GIGABYTE, USB_PID_GIGABYTE_U8000) }, - { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700PH) }, - { USB_DEVICE(USB_VID_ASUS, USB_PID_ASUS_U3000H) }, -/* 40 */{ USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV801E_SE) }, - { 0 } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); - -#define DIB0700_DEFAULT_DEVICE_PROPERTIES \ - .caps = DVB_USB_IS_AN_I2C_ADAPTER, \ - .usb_ctrl = DEVICE_SPECIFIC, \ - .firmware = "dvb-usb-dib0700-1.20.fw", \ - .download_firmware = dib0700_download_firmware, \ - .no_reconnect = 1, \ - .size_of_priv = sizeof(struct dib0700_state), \ - .i2c_algo = &dib0700_i2c_algo, \ - .identify_state = dib0700_identify_state - -#define DIB0700_DEFAULT_STREAMING_CONFIG(ep) \ - .streaming_ctrl = dib0700_streaming_ctrl, \ - .stream = { \ - .type = USB_BULK, \ - .count = 4, \ - .endpoint = ep, \ - .u = { \ - .bulk = { \ - .buffersize = 39480, \ - } \ - } \ - } - -struct dvb_usb_device_properties dib0700_devices[] = { - { - DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = stk7700p_frontend_attach, - .tuner_attach = stk7700p_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - }, - }, - - .num_device_descs = 8, - .devices = { - { "DiBcom STK7700P reference design", - { &dib0700_usb_id_table[0], &dib0700_usb_id_table[1] }, - { NULL }, - }, - { "Hauppauge Nova-T Stick", - { &dib0700_usb_id_table[4], &dib0700_usb_id_table[9], NULL }, - { NULL }, - }, - { "AVerMedia AVerTV DVB-T Volar", - { &dib0700_usb_id_table[5], &dib0700_usb_id_table[10] }, - { NULL }, - }, - { "Compro Videomate U500", - { &dib0700_usb_id_table[6], &dib0700_usb_id_table[19] }, - { NULL }, - }, - { "Uniwill STK7700P based (Hama and others)", - { &dib0700_usb_id_table[7], NULL }, - { NULL }, - }, - { "Leadtek Winfast DTV Dongle (STK7700P based)", - { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] }, - { NULL }, - }, - { "AVerMedia AVerTV DVB-T Express", - { &dib0700_usb_id_table[20] }, - { NULL }, - }, - { "Gigabyte U7000", - { &dib0700_usb_id_table[21], NULL }, - { NULL }, - } - }, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 2, - .adapter = { - { - .frontend_attach = bristol_frontend_attach, - .tuner_attach = bristol_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - }, { - .frontend_attach = bristol_frontend_attach, - .tuner_attach = bristol_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - } - }, - - .num_device_descs = 1, - .devices = { - { "Hauppauge Nova-T 500 Dual DVB-T", - { &dib0700_usb_id_table[2], &dib0700_usb_id_table[3], NULL }, - { NULL }, - }, - }, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 2, - .adapter = { - { - .frontend_attach = stk7700d_frontend_attach, - .tuner_attach = stk7700d_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - }, { - .frontend_attach = stk7700d_frontend_attach, - .tuner_attach = stk7700d_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - } - }, - - .num_device_descs = 4, - .devices = { - { "Pinnacle PCTV 2000e", - { &dib0700_usb_id_table[11], NULL }, - { NULL }, - }, - { "Terratec Cinergy DT XS Diversity", - { &dib0700_usb_id_table[12], NULL }, - { NULL }, - }, - { "Hauppauge Nova-TD Stick/Elgato Eye-TV Diversity", - { &dib0700_usb_id_table[13], NULL }, - { NULL }, - }, - { "DiBcom STK7700D reference design", - { &dib0700_usb_id_table[14], NULL }, - { NULL }, - } - }, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = stk7700P2_frontend_attach, - .tuner_attach = stk7700d_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - }, - }, - - .num_device_descs = 2, - .devices = { - { "ASUS My Cinema U3000 Mini DVBT Tuner", - { &dib0700_usb_id_table[23], NULL }, - { NULL }, - }, - { "Yuan EC372S", - { &dib0700_usb_id_table[31], NULL }, - { NULL }, - } - }, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = stk7070p_frontend_attach, - .tuner_attach = dib7070p_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - - .size_of_priv = sizeof(struct dib0700_adapter_state), - }, - }, - - .num_device_descs = 9, - .devices = { - { "DiBcom STK7070P reference design", - { &dib0700_usb_id_table[15], NULL }, - { NULL }, - }, - { "Pinnacle PCTV DVB-T Flash Stick", - { &dib0700_usb_id_table[16], NULL }, - { NULL }, - }, - { "Artec T14BR DVB-T", - { &dib0700_usb_id_table[22], NULL }, - { NULL }, - }, - { "ASUS My Cinema U3100 Mini DVBT Tuner", - { &dib0700_usb_id_table[24], NULL }, - { NULL }, - }, - { "Hauppauge Nova-T Stick", - { &dib0700_usb_id_table[25], NULL }, - { NULL }, - }, - { "Hauppauge Nova-T MyTV.t", - { &dib0700_usb_id_table[26], NULL }, - { NULL }, - }, - { "Pinnacle PCTV 72e", - { &dib0700_usb_id_table[29], NULL }, - { NULL }, - }, - { "Pinnacle PCTV 73e", - { &dib0700_usb_id_table[30], NULL }, - { NULL }, - }, - { "Terratec Cinergy T USB XXS", - { &dib0700_usb_id_table[33], NULL }, - { NULL }, - }, - }, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 2, - .adapter = { - { - .frontend_attach = stk7070pd_frontend_attach0, - .tuner_attach = dib7070p_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - - .size_of_priv = sizeof(struct dib0700_adapter_state), - }, { - .frontend_attach = stk7070pd_frontend_attach1, - .tuner_attach = dib7070p_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - - .size_of_priv = sizeof(struct dib0700_adapter_state), - } - }, - - .num_device_descs = 4, - .devices = { - { "DiBcom STK7070PD reference design", - { &dib0700_usb_id_table[17], NULL }, - { NULL }, - }, - { "Pinnacle PCTV Dual DVB-T Diversity Stick", - { &dib0700_usb_id_table[18], NULL }, - { NULL }, - }, - { "Hauppauge Nova-TD Stick (52009)", - { &dib0700_usb_id_table[35], NULL }, - { NULL }, - }, - { "Hauppauge Nova-TD-500 (84xxx)", - { &dib0700_usb_id_table[36], NULL }, - { NULL }, - } - } - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = stk7700ph_frontend_attach, - .tuner_attach = stk7700ph_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - - .size_of_priv = sizeof(struct - dib0700_adapter_state), - }, - }, - - .num_device_descs = 5, - .devices = { - { "Terratec Cinergy HT USB XE", - { &dib0700_usb_id_table[27], NULL }, - { NULL }, - }, - { "Pinnacle Expresscard 320cx", - { &dib0700_usb_id_table[28], NULL }, - { NULL }, - }, - { "Terratec Cinergy HT Express", - { &dib0700_usb_id_table[32], NULL }, - { NULL }, - }, - { "Gigabyte U8000-RH", - { &dib0700_usb_id_table[37], NULL }, - { NULL }, - }, - { "YUAN High-Tech STK7700PH", - { &dib0700_usb_id_table[38], NULL }, - { NULL }, - }, - { "Asus My Cinema-U3000Hybrid", - { &dib0700_usb_id_table[39], NULL }, - { NULL }, - }, - }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, - .num_adapters = 1, - .adapter = { - { - .frontend_attach = s5h1411_frontend_attach, - .tuner_attach = xc5000_tuner_attach, - - DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - - .size_of_priv = sizeof(struct - dib0700_adapter_state), - }, - }, - - .num_device_descs = 2, - .devices = { - { "Pinnacle PCTV HD Pro USB Stick", - { &dib0700_usb_id_table[40], NULL }, - { NULL }, - }, - { "Pinnacle PCTV HD USB Stick", - { &dib0700_usb_id_table[41], NULL }, - { NULL }, - }, - }, - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dib0700_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys), - .rc_query = dib0700_rc_query - }, -}; - -int dib0700_device_count = ARRAY_SIZE(dib0700_devices); diff --git a/drivers/media/dvb/dvb-usb/dib07x0.h b/drivers/media/dvb/dvb-usb/dib07x0.h deleted file mode 100644 index 7e62c101852..00000000000 --- a/drivers/media/dvb/dvb-usb/dib07x0.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _DIB07X0_H_ -#define _DIB07X0_H_ - -enum dib07x0_gpios { - GPIO0 = 0, - GPIO1 = 2, - GPIO2 = 3, - GPIO3 = 4, - GPIO4 = 5, - GPIO5 = 6, - GPIO6 = 8, - GPIO7 = 10, - GPIO8 = 11, - GPIO9 = 14, - GPIO10 = 15, -}; - -#define GPIO_IN 0 -#define GPIO_OUT 1 - -#endif diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c deleted file mode 100644 index 8ee6cd4da9e..00000000000 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ /dev/null @@ -1,456 +0,0 @@ -/* Common methods for dibusb-based-receivers. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dibusb.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info (|-able))." DVB_USB_DEBUG_STATUS); -MODULE_LICENSE("GPL"); - -#define deb_info(args...) dprintk(debug,0x01,args) - -/* common stuff used by the different dibusb modules */ -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)) { - err("error while controlling the fifo of the demod."); - return -ENODEV; - } - } - return 0; -} -EXPORT_SYMBOL(dibusb_streaming_ctrl); - -int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) -{ - 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); - } - return 0; -} -EXPORT_SYMBOL(dibusb_pid_filter); - -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) - err("could not handle pid_parser"); - } - return 0; -} -EXPORT_SYMBOL(dibusb_pid_filter_ctrl); - -int dibusb_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 b[3]; - int ret; - b[0] = DIBUSB_REQ_SET_IOCTL; - b[1] = DIBUSB_IOCTL_CMD_POWER_MODE; - b[2] = onoff ? DIBUSB_IOCTL_POWER_WAKEUP : DIBUSB_IOCTL_POWER_SLEEP; - ret = dvb_usb_generic_write(d,b,3); - msleep(10); - return ret; -} -EXPORT_SYMBOL(dibusb_power_ctrl); - -int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - u8 b[3] = { 0 }; - int ret; - - if ((ret = dibusb_streaming_ctrl(adap,onoff)) < 0) - return ret; - - if (onoff) { - b[0] = DIBUSB_REQ_SET_STREAMING_MODE; - b[1] = 0x00; - if ((ret = dvb_usb_generic_write(adap->dev,b,2)) < 0) - return ret; - } - - b[0] = DIBUSB_REQ_SET_IOCTL; - b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; - return dvb_usb_generic_write(adap->dev,b,3); -} -EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); - -int dibusb2_0_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - if (onoff) { - u8 b[3] = { DIBUSB_REQ_SET_IOCTL, DIBUSB_IOCTL_CMD_POWER_MODE, DIBUSB_IOCTL_POWER_WAKEUP }; - return dvb_usb_generic_write(d,b,3); - } else - return 0; -} -EXPORT_SYMBOL(dibusb2_0_power_ctrl); - -static int dibusb_i2c_msg(struct dvb_usb_device *d, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u8 sndbuf[wlen+4]; /* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */ - /* write only ? */ - int wo = (rbuf == NULL || rlen == 0), - len = 2 + wlen + (wo ? 0 : 2); - - sndbuf[0] = wo ? DIBUSB_REQ_I2C_WRITE : DIBUSB_REQ_I2C_READ; - sndbuf[1] = (addr << 1) | (wo ? 0 : 1); - - memcpy(&sndbuf[2],wbuf,wlen); - - if (!wo) { - sndbuf[wlen+2] = (rlen >> 8) & 0xff; - sndbuf[wlen+3] = rlen & 0xff; - } - - return dvb_usb_generic_rw(d,sndbuf,len,rbuf,rlen,0); -} - -/* - * I2C master xfer function - */ -static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len, - msg[i+1].buf,msg[i+1].len) < 0) - break; - i++; - } else - if (dibusb_i2c_msg(d, msg[i].addr, msg[i].buf,msg[i].len,NULL,0) < 0) - break; - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static u32 dibusb_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -struct i2c_algorithm dibusb_i2c_algo = { - .master_xfer = dibusb_i2c_xfer, - .functionality = dibusb_i2c_func, -}; -EXPORT_SYMBOL(dibusb_i2c_algo); - -int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val) -{ - u8 wbuf[1] = { offs }; - return dibusb_i2c_msg(d, 0x50, wbuf, 1, val, 1); -} -EXPORT_SYMBOL(dibusb_read_eeprom_byte); - -/* 3000MC/P stuff */ -// Config Adjacent channels Perf -cal22 -static struct dibx000_agc_config dib3000p_mt2060_agc_config = { - .band_caps = BAND_VHF | BAND_UHF, - .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0), - - .agc1_max = 48497, - .agc1_min = 23593, - .agc2_max = 46531, - .agc2_min = 24904, - - .agc1_pt1 = 0x65, - .agc1_pt2 = 0x69, - - .agc1_slope1 = 0x51, - .agc1_slope2 = 0x27, - - .agc2_pt1 = 0, - .agc2_pt2 = 0x33, - - .agc2_slope1 = 0x35, - .agc2_slope2 = 0x37, -}; - -static struct dib3000mc_config stk3000p_dib3000p_config = { - &dib3000p_mt2060_agc_config, - - .max_time = 0x196, - .ln_adc_level = 0x1cc7, - - .output_mpeg2_in_188_bytes = 1, - - .agc_command1 = 1, - .agc_command2 = 1, -}; - -static struct dibx000_agc_config dib3000p_panasonic_agc_config = { - .band_caps = BAND_VHF | BAND_UHF, - .setup = (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0), - - .agc1_max = 56361, - .agc1_min = 22282, - .agc2_max = 47841, - .agc2_min = 36045, - - .agc1_pt1 = 0x3b, - .agc1_pt2 = 0x6b, - - .agc1_slope1 = 0x55, - .agc1_slope2 = 0x1d, - - .agc2_pt1 = 0, - .agc2_pt2 = 0x0a, - - .agc2_slope1 = 0x95, - .agc2_slope2 = 0x1e, -}; - -#if defined(CONFIG_DVB_DIB3000MC) || \ - (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) - -static struct dib3000mc_config mod3000p_dib3000p_config = { - &dib3000p_panasonic_agc_config, - - .max_time = 0x51, - .ln_adc_level = 0x1cc7, - - .output_mpeg2_in_188_bytes = 1, - - .agc_command1 = 1, - .agc_command2 = 1, -}; - -int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) -{ - 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) { - if (adap->priv != NULL) { - struct dibusb_state *st = adap->priv; - st->ops.pid_parse = dib3000mc_pid_parse; - st->ops.pid_ctrl = dib3000mc_pid_control; - } - return 0; - } - return -ENODEV; -} -EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach); - -static struct mt2060_config stk3000p_mt2060_config = { - 0x60 -}; - -int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dibusb_state *st = adap->priv; - u8 a,b; - u16 if1 = 1220; - struct i2c_adapter *tun_i2c; - - // First IF calibration for Liteon Sticks - if (adap->dev->udev->descriptor.idVendor == USB_VID_LITEON && - adap->dev->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) { - - dibusb_read_eeprom_byte(adap->dev,0x7E,&a); - dibusb_read_eeprom_byte(adap->dev,0x7F,&b); - - if (a == 0x00) - if1 += b; - else if (a == 0x80) - if1 -= b; - else - warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b); - - } else if (adap->dev->udev->descriptor.idVendor == USB_VID_DIBCOM && - adap->dev->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) { - u8 desc; - dibusb_read_eeprom_byte(adap->dev, 7, &desc); - if (desc == 2) { - a = 127; - do { - dibusb_read_eeprom_byte(adap->dev, a, &desc); - a--; - } while (a > 7 && (desc == 0xff || desc == 0x00)); - if (desc & 0x80) - if1 -= (0xff - desc); - else - if1 += desc; - } - } - - tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); - if (dvb_attach(mt2060_attach, adap->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) - return -ENOMEM; - } else { - st->mt2060_present = 1; - /* set the correct parameters for the dib3000p */ - dib3000mc_set_config(adap->fe, &stk3000p_dib3000p_config); - } - return 0; -} -EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach); -#endif - -/* - * common remote control stuff - */ -struct dvb_usb_rc_key dibusb_rc_keys[] = { - /* Key codes for the little Artec T1/Twinhan/HAMA/ remote. */ - { 0x00, 0x16, KEY_POWER }, - { 0x00, 0x10, KEY_MUTE }, - { 0x00, 0x03, KEY_1 }, - { 0x00, 0x01, KEY_2 }, - { 0x00, 0x06, KEY_3 }, - { 0x00, 0x09, KEY_4 }, - { 0x00, 0x1d, KEY_5 }, - { 0x00, 0x1f, KEY_6 }, - { 0x00, 0x0d, KEY_7 }, - { 0x00, 0x19, KEY_8 }, - { 0x00, 0x1b, KEY_9 }, - { 0x00, 0x15, KEY_0 }, - { 0x00, 0x05, KEY_CHANNELUP }, - { 0x00, 0x02, KEY_CHANNELDOWN }, - { 0x00, 0x1e, KEY_VOLUMEUP }, - { 0x00, 0x0a, KEY_VOLUMEDOWN }, - { 0x00, 0x11, KEY_RECORD }, - { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ - { 0x00, 0x14, KEY_PLAY }, - { 0x00, 0x1a, KEY_STOP }, - { 0x00, 0x40, KEY_REWIND }, - { 0x00, 0x12, KEY_FASTFORWARD }, - { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ - { 0x00, 0x4c, KEY_PAUSE }, - { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ - { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ - /* additional keys TwinHan VisionPlus, the Artec seemingly not have */ - { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */ - { 0x00, 0x1c, KEY_EPG }, /* EPG */ - { 0x00, 0x00, KEY_TAB }, /* Tab */ - { 0x00, 0x48, KEY_INFO }, /* Preview */ - { 0x00, 0x04, KEY_LIST }, /* RecordList */ - { 0x00, 0x0f, KEY_TEXT }, /* Teletext */ - /* Key codes for the KWorld/ADSTech/JetWay remote. */ - { 0x86, 0x12, KEY_POWER }, - { 0x86, 0x0f, KEY_SELECT }, /* source */ - { 0x86, 0x0c, KEY_UNKNOWN }, /* scan */ - { 0x86, 0x0b, KEY_EPG }, - { 0x86, 0x10, KEY_MUTE }, - { 0x86, 0x01, KEY_1 }, - { 0x86, 0x02, KEY_2 }, - { 0x86, 0x03, KEY_3 }, - { 0x86, 0x04, KEY_4 }, - { 0x86, 0x05, KEY_5 }, - { 0x86, 0x06, KEY_6 }, - { 0x86, 0x07, KEY_7 }, - { 0x86, 0x08, KEY_8 }, - { 0x86, 0x09, KEY_9 }, - { 0x86, 0x0a, KEY_0 }, - { 0x86, 0x18, KEY_ZOOM }, - { 0x86, 0x1c, KEY_UNKNOWN }, /* preview */ - { 0x86, 0x13, KEY_UNKNOWN }, /* snap */ - { 0x86, 0x00, KEY_UNDO }, - { 0x86, 0x1d, KEY_RECORD }, - { 0x86, 0x0d, KEY_STOP }, - { 0x86, 0x0e, KEY_PAUSE }, - { 0x86, 0x16, KEY_PLAY }, - { 0x86, 0x11, KEY_BACK }, - { 0x86, 0x19, KEY_FORWARD }, - { 0x86, 0x14, KEY_UNKNOWN }, /* pip */ - { 0x86, 0x15, KEY_ESC }, - { 0x86, 0x1a, KEY_UP }, - { 0x86, 0x1e, KEY_DOWN }, - { 0x86, 0x1f, KEY_LEFT }, - { 0x86, 0x1b, KEY_RIGHT }, - - /* Key codes for the DiBcom MOD3000 remote. */ - { 0x80, 0x00, KEY_MUTE }, - { 0x80, 0x01, KEY_TEXT }, - { 0x80, 0x02, KEY_HOME }, - { 0x80, 0x03, KEY_POWER }, - - { 0x80, 0x04, KEY_RED }, - { 0x80, 0x05, KEY_GREEN }, - { 0x80, 0x06, KEY_YELLOW }, - { 0x80, 0x07, KEY_BLUE }, - - { 0x80, 0x08, KEY_DVD }, - { 0x80, 0x09, KEY_AUDIO }, - { 0x80, 0x0a, KEY_MEDIA }, /* Pictures */ - { 0x80, 0x0b, KEY_VIDEO }, - - { 0x80, 0x0c, KEY_BACK }, - { 0x80, 0x0d, KEY_UP }, - { 0x80, 0x0e, KEY_RADIO }, - { 0x80, 0x0f, KEY_EPG }, - - { 0x80, 0x10, KEY_LEFT }, - { 0x80, 0x11, KEY_OK }, - { 0x80, 0x12, KEY_RIGHT }, - { 0x80, 0x13, KEY_UNKNOWN }, /* SAP */ - - { 0x80, 0x14, KEY_TV }, - { 0x80, 0x15, KEY_DOWN }, - { 0x80, 0x16, KEY_MENU }, /* DVD Menu */ - { 0x80, 0x17, KEY_LAST }, - - { 0x80, 0x18, KEY_RECORD }, - { 0x80, 0x19, KEY_STOP }, - { 0x80, 0x1a, KEY_PAUSE }, - { 0x80, 0x1b, KEY_PLAY }, - - { 0x80, 0x1c, KEY_PREVIOUS }, - { 0x80, 0x1d, KEY_REWIND }, - { 0x80, 0x1e, KEY_FASTFORWARD }, - { 0x80, 0x1f, KEY_NEXT}, - - { 0x80, 0x40, KEY_1 }, - { 0x80, 0x41, KEY_2 }, - { 0x80, 0x42, KEY_3 }, - { 0x80, 0x43, KEY_CHANNELUP }, - - { 0x80, 0x44, KEY_4 }, - { 0x80, 0x45, KEY_5 }, - { 0x80, 0x46, KEY_6 }, - { 0x80, 0x47, KEY_CHANNELDOWN }, - - { 0x80, 0x48, KEY_7 }, - { 0x80, 0x49, KEY_8 }, - { 0x80, 0x4a, KEY_9 }, - { 0x80, 0x4b, KEY_VOLUMEUP }, - - { 0x80, 0x4c, KEY_CLEAR }, - { 0x80, 0x4d, KEY_0 }, - { 0x80, 0x4e, KEY_ENTER }, - { 0x80, 0x4f, KEY_VOLUMEDOWN }, -}; -EXPORT_SYMBOL(dibusb_rc_keys); - -int dibusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key[5],cmd = DIBUSB_REQ_POLL_REMOTE; - dvb_usb_generic_rw(d,&cmd,1,key,5,0); - dvb_usb_nec_rc_key_to_event(d,key,event,state); - if (key[0] != 0) - deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); - return 0; -} -EXPORT_SYMBOL(dibusb_rc_query); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c deleted file mode 100644 index eeef50bff4f..00000000000 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ /dev/null @@ -1,469 +0,0 @@ -/* DVB USB compliant linux driver for mobile DVB-T USB devices based on - * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-B) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DiBcom, which has - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dibusb.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int dib3000mb_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct dvb_usb_adapter *adap = fe->dvb->priv; - struct dibusb_state *st = adap->priv; - - return st->ops.tuner_pass_ctrl(fe, enable, st->tuner_addr); -} - -static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct dib3000_config demod_cfg; - struct dibusb_state *st = adap->priv; - - demod_cfg.demod_address = 0x8; - - if ((adap->fe = dvb_attach(dib3000mb_attach, &demod_cfg, - &adap->dev->i2c_adap, &st->ops)) == NULL) - return -ENODEV; - - adap->fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl; - - return 0; -} - -static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dibusb_state *st = adap->priv; - - st->tuner_addr = 0x61; - - dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, - DVB_PLL_TUA6010XS); - return 0; -} - -static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap) -{ - struct dibusb_state *st = adap->priv; - - st->tuner_addr = 0x60; - - dvb_attach(dvb_pll_attach, adap->fe, 0x60, &adap->dev->i2c_adap, - DVB_PLL_TDA665X); - return 0; -} - -/* Some of the Artec 1.1 device aren't equipped with the default tuner - * (Thomson Cable), but with a Panasonic ENV77H11D5. This function figures - * this out. */ -static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap) -{ - u8 b[2] = { 0,0 }, b2[1]; - int ret = 0; - struct i2c_msg msg[2] = { - { .flags = 0, .buf = b, .len = 2 }, - { .flags = I2C_M_RD, .buf = b2, .len = 1 }, - }; - struct dibusb_state *st = adap->priv; - - /* 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 (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 (b2[0] == 0xfe) { - info("This device has the Thomson Cable onboard. Which is default."); - ret = dibusb_thomson_tuner_attach(adap); - } else { - info("This device has the Panasonic ENV77H11D5 onboard."); - ret = dibusb_panasonic_tuner_attach(adap); - } - - return ret; -} - -/* USB Driver stuff */ -static struct dvb_usb_device_properties dibusb1_1_properties; -static struct dvb_usb_device_properties dibusb1_1_an2235_properties; -static struct dvb_usb_device_properties dibusb2_0b_properties; -static struct dvb_usb_device_properties artec_t1_usb2_properties; - -static int dibusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - if (0 == dvb_usb_device_init(intf, &dibusb1_1_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &dibusb1_1_an2235_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &dibusb2_0b_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &artec_t1_usb2_properties, - THIS_MODULE, NULL, adapter_nr)) - return 0; - - return -EINVAL; -} - -/* do not change the order of the ID table */ -static struct usb_device_id dibusb_dib3000mb_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) }, -/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) }, -/* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, -/* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, -/* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, -/* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, -/* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, -/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, -/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, -/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, -/* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, -/* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, -/* 12 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_WARM) }, -/* 13 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_COLD) }, -/* 14 */ { USB_DEVICE(USB_VID_HYPER_PALTEK, USB_PID_UNK_HYPER_PALTEK_WARM) }, -/* 15 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_COLD) }, -/* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, -/* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, -/* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, -/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, -/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, -/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, -/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, -/* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, - -/* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ -/* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, -/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, -/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, - -/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, - -/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, -/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, - -/* - * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices - * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that - * have been left on the device. If you don't have such a device but an Artec - * device that's supposed to work with this driver but is not detected by it, - * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config. - */ - -#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY -/* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, -#endif - - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); - -static struct dvb_usb_device_properties dibusb1_1_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_AN2135, - - .firmware = "dvb-usb-dibusb-5.0.0.11.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter_count = 16, - - .streaming_ctrl = dibusb_streaming_ctrl, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_tuner_probe_and_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - .size_of_priv = sizeof(struct dibusb_state), - } - }, - - .power_ctrl = dibusb_power_ctrl, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dibusb_rc_keys, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 9, - .devices = { - { "AVerMedia AverTV DVBT USB1.1", - { &dibusb_dib3000mb_table[0], NULL }, - { &dibusb_dib3000mb_table[1], NULL }, - }, - { "Compro Videomate DVB-U2000 - DVB-T USB1.1 (please confirm to linux-dvb)", - { &dibusb_dib3000mb_table[2], &dibusb_dib3000mb_table[4], NULL}, - { &dibusb_dib3000mb_table[3], NULL }, - }, - { "DiBcom USB1.1 DVB-T reference design (MOD3000)", - { &dibusb_dib3000mb_table[5], NULL }, - { &dibusb_dib3000mb_table[6], NULL }, - }, - { "KWorld V-Stream XPERT DTV - DVB-T USB1.1", - { &dibusb_dib3000mb_table[7], NULL }, - { &dibusb_dib3000mb_table[8], NULL }, - }, - { "Grandtec USB1.1 DVB-T", - { &dibusb_dib3000mb_table[9], &dibusb_dib3000mb_table[11], NULL }, - { &dibusb_dib3000mb_table[10], &dibusb_dib3000mb_table[12], NULL }, - }, - { "Unkown USB1.1 DVB-T device ???? please report the name to the author", - { &dibusb_dib3000mb_table[13], NULL }, - { &dibusb_dib3000mb_table[14], NULL }, - }, - { "TwinhanDTV USB-Ter USB1.1 / Magic Box I / HAMA USB1.1 DVB-T device", - { &dibusb_dib3000mb_table[15], &dibusb_dib3000mb_table[17], NULL}, - { &dibusb_dib3000mb_table[16], &dibusb_dib3000mb_table[18], NULL}, - }, - { "Artec T1 USB1.1 TVBOX with AN2135", - { &dibusb_dib3000mb_table[19], NULL }, - { &dibusb_dib3000mb_table[20], NULL }, - }, - { "VideoWalker DVB-T USB", - { &dibusb_dib3000mb_table[25], NULL }, - { &dibusb_dib3000mb_table[26], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties dibusb1_1_an2235_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = CYPRESS_AN2235, - - .firmware = "dvb-usb-dibusb-an2235-01.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER, - .pid_filter_count = 16, - - .streaming_ctrl = dibusb_streaming_ctrl, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_tuner_probe_and_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - .size_of_priv = sizeof(struct dibusb_state), - }, - }, - .power_ctrl = dibusb_power_ctrl, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dibusb_rc_keys, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - -#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY - .num_device_descs = 2, -#else - .num_device_descs = 1, -#endif - .devices = { - { "Artec T1 USB1.1 TVBOX with AN2235", - { &dibusb_dib3000mb_table[21], NULL }, - { &dibusb_dib3000mb_table[22], NULL }, - }, -#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY - { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", - { &dibusb_dib3000mb_table[30], NULL }, - { NULL }, - }, - { NULL }, -#endif - } -}; - -static struct dvb_usb_device_properties dibusb2_0b_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .firmware = "dvb-usb-adstech-usb2-02.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter_count = 16, - - .streaming_ctrl = dibusb2_0_streaming_ctrl, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_thomson_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - .size_of_priv = sizeof(struct dibusb_state), - } - }, - .power_ctrl = dibusb2_0_power_ctrl, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dibusb_rc_keys, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 2, - .devices = { - { "KWorld/ADSTech Instant DVB-T USB2.0", - { &dibusb_dib3000mb_table[23], NULL }, - { &dibusb_dib3000mb_table[24], NULL }, - }, - { "KWorld Xpert DVB-T USB2.0", - { &dibusb_dib3000mb_table[27], NULL }, - { NULL } - }, - { NULL }, - } -}; - -static struct dvb_usb_device_properties artec_t1_usb2_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - - .firmware = "dvb-usb-dibusb-6.0.0.8.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter_count = 16, - - .streaming_ctrl = dibusb2_0_streaming_ctrl, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - .frontend_attach = dibusb_dib3000mb_frontend_attach, - .tuner_attach = dibusb_tuner_probe_and_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - .size_of_priv = sizeof(struct dibusb_state), - } - }, - .power_ctrl = dibusb2_0_power_ctrl, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dibusb_rc_keys, - .rc_key_map_size = 111, /* wow, that is ugly ... I want to load it to the driver dynamically */ - .rc_query = dibusb_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "Artec T1 USB2.0", - { &dibusb_dib3000mb_table[28], NULL }, - { &dibusb_dib3000mb_table[29], NULL }, - }, - { NULL }, - } -}; - -static struct usb_driver dibusb_driver = { - .name = "dvb_usb_dibusb_mb", - .probe = dibusb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dibusb_dib3000mb_table, -}; - -/* module stuff */ -static int __init dibusb_module_init(void) -{ - int result; - if ((result = usb_register(&dibusb_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit dibusb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dibusb_driver); -} - -module_init (dibusb_module_init); -module_exit (dibusb_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for DiBcom USB DVB-T devices (DiB3000M-B based)"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c deleted file mode 100644 index 059cec95531..00000000000 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ /dev/null @@ -1,157 +0,0 @@ -/* DVB USB compliant linux driver for mobile DVB-T USB devices based on - * reference designs made by DiBcom (http://www.dibcom.fr/) (DiB3000M-C/P) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DiBcom, which has - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dibusb.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -/* USB Driver stuff */ -static struct dvb_usb_device_properties dibusb_mc_properties; - -static int dibusb_mc_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &dibusb_mc_properties, THIS_MODULE, - NULL, adapter_nr); -} - -/* do not change the order of the ID table */ -static struct usb_device_id dibusb_dib3000mc_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_COLD) }, -/* 01 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3001_WARM) }, -/* 02 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, -/* 03 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, // ( ? ) -/* 04 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_COLD) }, -/* 05 */ { USB_DEVICE(USB_VID_LITEON, USB_PID_LITEON_DVB_T_WARM) }, -/* 06 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_COLD) }, -/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_DIGIVOX_MINI_SL_WARM) }, -/* 08 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_COLD) }, -/* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB2_WARM) }, -/* 10 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_COLD) }, -/* 11 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14_WARM) }, -/* 12 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_COLD) }, -/* 13 */ { USB_DEVICE(USB_VID_LEADTEK, USB_PID_WINFAST_DTV_DONGLE_WARM) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, dibusb_dib3000mc_table); - -static struct dvb_usb_device_properties dibusb_mc_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-dibusb-6.0.0.8.fw", - - .num_adapters = 1, - .adapter = { - { - .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, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - .frontend_attach = dibusb_dib3000mc_frontend_attach, - .tuner_attach = dibusb_dib3000mc_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - .size_of_priv = sizeof(struct dibusb_state), - } - }, - .power_ctrl = dibusb2_0_power_ctrl, - - .rc_interval = DEFAULT_RC_INTERVAL, - .rc_key_map = dibusb_rc_keys, - .rc_key_map_size = 111, /* FIXME */ - .rc_query = dibusb_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 7, - .devices = { - { "DiBcom USB2.0 DVB-T reference design (MOD3000P)", - { &dibusb_dib3000mc_table[0], NULL }, - { &dibusb_dib3000mc_table[1], NULL }, - }, - { "Artec T1 USB2.0 TVBOX (please check the warm ID)", - { &dibusb_dib3000mc_table[2], NULL }, - { &dibusb_dib3000mc_table[3], NULL }, - }, - { "LITE-ON USB2.0 DVB-T Tuner", - /* Also rebranded as Intuix S800, Toshiba */ - { &dibusb_dib3000mc_table[4], NULL }, - { &dibusb_dib3000mc_table[5], NULL }, - }, - { "MSI Digivox Mini SL", - { &dibusb_dib3000mc_table[6], NULL }, - { &dibusb_dib3000mc_table[7], NULL }, - }, - { "GRAND - USB2.0 DVB-T adapter", - { &dibusb_dib3000mc_table[8], NULL }, - { &dibusb_dib3000mc_table[9], NULL }, - }, - { "Artec T14 - USB2.0 DVB-T", - { &dibusb_dib3000mc_table[10], NULL }, - { &dibusb_dib3000mc_table[11], NULL }, - }, - { "Leadtek - USB2.0 Winfast DTV dongle", - { &dibusb_dib3000mc_table[12], NULL }, - { &dibusb_dib3000mc_table[13], NULL }, - }, - { NULL }, - } -}; - -static struct usb_driver dibusb_mc_driver = { - .name = "dvb_usb_dibusb_mc", - .probe = dibusb_mc_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dibusb_dib3000mc_table, -}; - -/* module stuff */ -static int __init dibusb_mc_module_init(void) -{ - int result; - if ((result = usb_register(&dibusb_mc_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit dibusb_mc_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dibusb_mc_driver); -} - -module_init (dibusb_mc_module_init); -module_exit (dibusb_mc_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for DiBcom USB2.0 DVB-T (DiB3000M-C/P based) devices"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dibusb.h b/drivers/media/dvb/dvb-usb/dibusb.h deleted file mode 100644 index 8e847aa73ba..00000000000 --- a/drivers/media/dvb/dvb-usb/dibusb.h +++ /dev/null @@ -1,131 +0,0 @@ -/* Header file for all dibusb-based-receivers. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_DIBUSB_H_ -#define _DVB_USB_DIBUSB_H_ - -#ifndef DVB_USB_LOG_PREFIX - #define DVB_USB_LOG_PREFIX "dibusb" -#endif -#include "dvb-usb.h" - -#include "dib3000.h" -#include "dib3000mc.h" -#include "mt2060.h" - -/* - * protocol of all dibusb related devices - */ - -/* - * bulk msg to/from endpoint 0x01 - * - * general structure: - * request_byte parameter_bytes - */ - -#define DIBUSB_REQ_START_READ 0x00 -#define DIBUSB_REQ_START_DEMOD 0x01 - -/* - * i2c read - * bulk write: 0x02 ((7bit i2c_addr << 1) & 0x01) register_bytes length_word - * bulk read: byte_buffer (length_word bytes) - */ -#define DIBUSB_REQ_I2C_READ 0x02 - -/* - * i2c write - * bulk write: 0x03 (7bit i2c_addr << 1) register_bytes value_bytes - */ -#define DIBUSB_REQ_I2C_WRITE 0x03 - -/* - * polling the value of the remote control - * bulk write: 0x04 - * bulk read: byte_buffer (5 bytes) - */ -#define DIBUSB_REQ_POLL_REMOTE 0x04 - -/* additional status values for Hauppauge Remote Control Protocol */ -#define DIBUSB_RC_HAUPPAUGE_KEY_PRESSED 0x01 -#define DIBUSB_RC_HAUPPAUGE_KEY_EMPTY 0x03 - -/* streaming mode: - * bulk write: 0x05 mode_byte - * - * mode_byte is mostly 0x00 - */ -#define DIBUSB_REQ_SET_STREAMING_MODE 0x05 - -/* interrupt the internal read loop, when blocking */ -#define DIBUSB_REQ_INTR_READ 0x06 - -/* io control - * 0x07 cmd_byte param_bytes - * - * param_bytes can be up to 32 bytes - * - * cmd_byte function parameter name - * 0x00 power mode - * 0x00 sleep - * 0x01 wakeup - * - * 0x01 enable streaming - * 0x02 disable streaming - * - * - */ -#define DIBUSB_REQ_SET_IOCTL 0x07 - -/* IOCTL commands */ - -/* change the power mode in firmware */ -#define DIBUSB_IOCTL_CMD_POWER_MODE 0x00 -#define DIBUSB_IOCTL_POWER_SLEEP 0x00 -#define DIBUSB_IOCTL_POWER_WAKEUP 0x01 - -/* modify streaming of the FX2 */ -#define DIBUSB_IOCTL_CMD_ENABLE_STREAM 0x01 -#define DIBUSB_IOCTL_CMD_DISABLE_STREAM 0x02 - -struct dibusb_state { - struct dib_fe_xfer_ops ops; - int mt2060_present; - u8 tuner_addr; -}; - -struct dibusb_device_state { - /* for RC5 remote control */ - int old_toggle; - int last_repeat_count; -}; - -extern struct i2c_algorithm dibusb_i2c_algo; - -extern int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *); -extern int dibusb_dib3000mc_tuner_attach (struct dvb_usb_adapter *); - -extern int dibusb_streaming_ctrl(struct dvb_usb_adapter *, int); -extern int dibusb_pid_filter(struct dvb_usb_adapter *, int, u16, int); -extern int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *, int); -extern int dibusb2_0_streaming_ctrl(struct dvb_usb_adapter *, int); - -extern int dibusb_power_ctrl(struct dvb_usb_device *, int); -extern int dibusb2_0_power_ctrl(struct dvb_usb_device *, int); - -#define DEFAULT_RC_INTERVAL 150 -//#define DEFAULT_RC_INTERVAL 100000 - -extern struct dvb_usb_rc_key dibusb_rc_keys[]; -extern int dibusb_rc_query(struct dvb_usb_device *, u32 *, int *); -extern int dibusb_read_eeprom_byte(struct dvb_usb_device *, u8, u8 *); - -#endif diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c deleted file mode 100644 index b545cf3eab2..00000000000 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ /dev/null @@ -1,363 +0,0 @@ -/* DVB USB compliant linux driver for Nebula Electronics uDigiTV DVB-T USB2.0 - * receiver - * - * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) - * - * partly based on the SDK published by Nebula Electronics - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "digitv.h" - -#include "mt352.h" -#include "nxt6000.h" - -/* debug */ -static int dvb_usb_digitv_debug; -module_param_named(debug,dvb_usb_digitv_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define deb_rc(args...) dprintk(dvb_usb_digitv_debug,0x01,args) - -static int digitv_ctrl_msg(struct dvb_usb_device *d, - u8 cmd, u8 vv, u8 *wbuf, int wlen, u8 *rbuf, int rlen) -{ - int wo = (rbuf == NULL || rlen == 0); /* write-only */ - u8 sndbuf[7],rcvbuf[7]; - memset(sndbuf,0,7); memset(rcvbuf,0,7); - - sndbuf[0] = cmd; - sndbuf[1] = vv; - sndbuf[2] = wo ? wlen : rlen; - - if (wo) { - memcpy(&sndbuf[3],wbuf,wlen); - dvb_usb_generic_write(d,sndbuf,7); - } else { - dvb_usb_generic_rw(d,sndbuf,7,rcvbuf,7,10); - memcpy(rbuf,&rcvbuf[3],rlen); - } - return 0; -} - -/* I2C */ -static int digitv_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - if (num > 2) - warn("more than 2 i2c messages at a time is not handled yet. TODO."); - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (digitv_ctrl_msg(d, USB_READ_COFDM, msg[i].buf[0], NULL, 0, - msg[i+1].buf,msg[i+1].len) < 0) - break; - i++; - } else - if (digitv_ctrl_msg(d,USB_WRITE_COFDM, msg[i].buf[0], - &msg[i].buf[1],msg[i].len-1,NULL,0) < 0) - break; - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static u32 digitv_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm digitv_i2c_algo = { - .master_xfer = digitv_i2c_xfer, - .functionality = digitv_i2c_func, -}; - -/* Callbacks for DVB USB */ -static int digitv_identify_state (struct usb_device *udev, struct - dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, - int *cold) -{ - *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0; - return 0; -} - -static int digitv_mt352_demod_init(struct dvb_frontend *fe) -{ - static u8 reset_buf[] = { 0x89, 0x38, 0x8a, 0x2d, 0x50, 0x80 }; - static u8 init_buf[] = { 0x68, 0xa0, 0x8e, 0x40, 0x53, 0x50, - 0x67, 0x20, 0x7d, 0x01, 0x7c, 0x00, 0x7a, 0x00, - 0x79, 0x20, 0x57, 0x05, 0x56, 0x31, 0x88, 0x0f, - 0x75, 0x32 }; - int i; - - for (i = 0; i < ARRAY_SIZE(reset_buf); i += 2) - mt352_write(fe, &reset_buf[i], 2); - - msleep(1); - - for (i = 0; i < ARRAY_SIZE(init_buf); i += 2) - mt352_write(fe, &init_buf[i], 2); - - return 0; -} - -static struct mt352_config digitv_mt352_config = { - .demod_init = digitv_mt352_demod_init, -}; - -static int digitv_nxt6000_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) -{ - struct dvb_usb_adapter *adap = fe->dvb->priv; - u8 b[5]; - - fe->ops.tuner_ops.calc_regs(fe, fep, b, sizeof(b)); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - return digitv_ctrl_msg(adap->dev, USB_WRITE_TUNER, 0, &b[1], 4, NULL, 0); -} - -static struct nxt6000_config digitv_nxt6000_config = { - .clock_inversion = 1, -}; - -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) { - st->is_nxt6000 = 0; - return 0; - } - if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) { - st->is_nxt6000 = 1; - return 0; - } - return -EIO; -} - -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)) - return -ENODEV; - - if (st->is_nxt6000) - adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; - - return 0; -} - -static struct dvb_usb_rc_key digitv_rc_keys[] = { - { 0x5f, 0x55, KEY_0 }, - { 0x6f, 0x55, KEY_1 }, - { 0x9f, 0x55, KEY_2 }, - { 0xaf, 0x55, KEY_3 }, - { 0x5f, 0x56, KEY_4 }, - { 0x6f, 0x56, KEY_5 }, - { 0x9f, 0x56, KEY_6 }, - { 0xaf, 0x56, KEY_7 }, - { 0x5f, 0x59, KEY_8 }, - { 0x6f, 0x59, KEY_9 }, - { 0x9f, 0x59, KEY_TV }, - { 0xaf, 0x59, KEY_AUX }, - { 0x5f, 0x5a, KEY_DVD }, - { 0x6f, 0x5a, KEY_POWER }, - { 0x9f, 0x5a, KEY_MHP }, /* labelled 'Picture' */ - { 0xaf, 0x5a, KEY_AUDIO }, - { 0x5f, 0x65, KEY_INFO }, - { 0x6f, 0x65, KEY_F13 }, /* 16:9 */ - { 0x9f, 0x65, KEY_F14 }, /* 14:9 */ - { 0xaf, 0x65, KEY_EPG }, - { 0x5f, 0x66, KEY_EXIT }, - { 0x6f, 0x66, KEY_MENU }, - { 0x9f, 0x66, KEY_UP }, - { 0xaf, 0x66, KEY_DOWN }, - { 0x5f, 0x69, KEY_LEFT }, - { 0x6f, 0x69, KEY_RIGHT }, - { 0x9f, 0x69, KEY_ENTER }, - { 0xaf, 0x69, KEY_CHANNELUP }, - { 0x5f, 0x6a, KEY_CHANNELDOWN }, - { 0x6f, 0x6a, KEY_VOLUMEUP }, - { 0x9f, 0x6a, KEY_VOLUMEDOWN }, - { 0xaf, 0x6a, KEY_RED }, - { 0x5f, 0x95, KEY_GREEN }, - { 0x6f, 0x95, KEY_YELLOW }, - { 0x9f, 0x95, KEY_BLUE }, - { 0xaf, 0x95, KEY_SUBTITLE }, - { 0x5f, 0x96, KEY_F15 }, /* AD */ - { 0x6f, 0x96, KEY_TEXT }, - { 0x9f, 0x96, KEY_MUTE }, - { 0xaf, 0x96, KEY_REWIND }, - { 0x5f, 0x99, KEY_STOP }, - { 0x6f, 0x99, KEY_PLAY }, - { 0x9f, 0x99, KEY_FASTFORWARD }, - { 0xaf, 0x99, KEY_F16 }, /* chapter */ - { 0x5f, 0x9a, KEY_PAUSE }, - { 0x6f, 0x9a, KEY_PLAY }, - { 0x9f, 0x9a, KEY_RECORD }, - { 0xaf, 0x9a, KEY_F17 }, /* picture in picture */ - { 0x5f, 0xa5, KEY_KPPLUS }, /* zoom in */ - { 0x6f, 0xa5, KEY_KPMINUS }, /* zoom out */ - { 0x9f, 0xa5, KEY_F18 }, /* capture */ - { 0xaf, 0xa5, KEY_F19 }, /* web */ - { 0x5f, 0xa6, KEY_EMAIL }, - { 0x6f, 0xa6, KEY_PHONE }, - { 0x9f, 0xa6, KEY_PC }, -}; - -static int digitv_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - int i; - u8 key[5]; - u8 b[4] = { 0 }; - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - digitv_ctrl_msg(d,USB_READ_REMOTE,0,NULL,0,&key[1],4); - - /* Tell the device we've read the remote. Not sure how necessary - this is, but the Nebula SDK does it. */ - digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); - - /* if something is inside the buffer, simulate key press */ - if (key[1] != 0) - { - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (d->props.rc_key_map[i].custom == key[1] && - d->props.rc_key_map[i].data == key[2]) { - *event = d->props.rc_key_map[i].event; - *state = REMOTE_KEY_PRESSED; - return 0; - } - } - } - - if (key[0] != 0) - deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); - return 0; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties digitv_properties; - -static int digitv_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct dvb_usb_device *d; - int ret = dvb_usb_device_init(intf, &digitv_properties, THIS_MODULE, &d, - adapter_nr); - if (ret == 0) { - u8 b[4] = { 0 }; - - if (d != NULL) { /* do that only when the firmware is loaded */ - b[0] = 1; - digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0); - - b[0] = 0; - digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); - } - } - return ret; -} - -static struct usb_device_id digitv_table [] = { - { USB_DEVICE(USB_VID_ANCHOR, USB_PID_NEBULA_DIGITV) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, digitv_table); - -static struct dvb_usb_device_properties digitv_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-digitv-02.fw", - - .size_of_priv = sizeof(struct digitv_state), - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = digitv_frontend_attach, - .tuner_attach = digitv_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .identify_state = digitv_identify_state, - - .rc_interval = 1000, - .rc_key_map = digitv_rc_keys, - .rc_key_map_size = ARRAY_SIZE(digitv_rc_keys), - .rc_query = digitv_rc_query, - - .i2c_algo = &digitv_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "Nebula Electronics uDigiTV DVB-T USB2.0)", - { &digitv_table[0], NULL }, - { NULL }, - }, - { NULL }, - } -}; - -static struct usb_driver digitv_driver = { - .name = "dvb_usb_digitv", - .probe = digitv_probe, - .disconnect = dvb_usb_device_exit, - .id_table = digitv_table, -}; - -/* module stuff */ -static int __init digitv_module_init(void) -{ - int result; - if ((result = usb_register(&digitv_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit digitv_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&digitv_driver); -} - -module_init (digitv_module_init); -module_exit (digitv_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for Nebula Electronics uDigiTV DVB-T USB2.0"); -MODULE_VERSION("1.0-alpha"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/digitv.h b/drivers/media/dvb/dvb-usb/digitv.h deleted file mode 100644 index 908c09f4966..00000000000 --- a/drivers/media/dvb/dvb-usb/digitv.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _DVB_USB_DIGITV_H_ -#define _DVB_USB_DIGITV_H_ - -#define DVB_USB_LOG_PREFIX "digitv" -#include "dvb-usb.h" - -struct digitv_state { - int is_nxt6000; -}; - -/* protocol (from usblogging and the SDK: - * - * Always 7 bytes bulk message(s) for controlling - * - * First byte describes the command. Reads are 2 consecutive transfer (as always). - * - * General structure: - * - * write or first message of a read: - * <cmdbyte> VV <len> B0 B1 B2 B3 - * - * second message of a read - * <cmdbyte> VV <len> R0 R1 R2 R3 - * - * whereas 0 < len <= 4 - * - * I2C address is stored somewhere inside the device. - * - * 0x01 read from EEPROM - * VV = offset; B* = 0; R* = value(s) - * - * 0x02 read register of the COFDM - * VV = register; B* = 0; R* = value(s) - * - * 0x05 write register of the COFDM - * VV = register; B* = value(s); - * - * 0x06 write to the tuner (only for NXT6000) - * VV = 0; B* = PLL data; len = 4; - * - * 0x03 read remote control - * VV = 0; B* = 0; len = 4; R* = key - * - * 0x07 write to the remote (don't know why one should this, resetting ?) - * VV = 0; B* = key; len = 4; - * - * 0x08 write remote type - * VV = 0; B[0] = 0x01, len = 4 - * - * 0x09 write device init - * TODO - */ -#define USB_READ_EEPROM 1 - -#define USB_READ_COFDM 2 -#define USB_WRITE_COFDM 5 - -#define USB_WRITE_TUNER 6 - -#define USB_READ_REMOTE 3 -#define USB_WRITE_REMOTE 7 -#define USB_WRITE_REMOTE_TYPE 8 - -#define USB_DEV_INIT 9 - -#endif diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c deleted file mode 100644 index 17413adec7a..00000000000 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Frontend part of the Linux driver for the WideView/ Yakumo/ Hama/ - * Typhoon/ Yuan DVB-T USB2.0 receiver. - * - * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dtt200u.h" - -struct dtt200u_fe_state { - struct dvb_usb_device *d; - - fe_status_t stat; - - struct dvb_frontend_parameters fep; - struct dvb_frontend frontend; -}; - -static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 st = GET_TUNE_STATUS, b[3]; - - dvb_usb_generic_rw(state->d,&st,1,b,3,0); - - switch (b[0]) { - case 0x01: - *stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | - FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - break; - case 0x00: /* pending */ - *stat = FE_TIMEDOUT; /* during set_frontend */ - break; - default: - case 0x02: /* failed */ - *stat = 0; - break; - } - return 0; -} - -static int dtt200u_fe_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_VIT_ERR_CNT,b[3]; - dvb_usb_generic_rw(state->d,&bw,1,b,3,0); - *ber = (b[0] << 16) | (b[1] << 8) | b[2]; - return 0; -} - -static int dtt200u_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_RS_UNCOR_BLK_CNT,b[2]; - - dvb_usb_generic_rw(state->d,&bw,1,b,2,0); - *unc = (b[0] << 8) | b[1]; - return 0; -} - -static int dtt200u_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_AGC, b; - dvb_usb_generic_rw(state->d,&bw,1,&b,1,0); - *strength = (b << 8) | b; - return 0; -} - -static int dtt200u_fe_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 bw = GET_SNR,br; - dvb_usb_generic_rw(state->d,&bw,1,&br,1,0); - *snr = ~((br << 8) | br); - return 0; -} - -static int dtt200u_fe_init(struct dvb_frontend* fe) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - u8 b = SET_INIT; - return dvb_usb_generic_write(state->d,&b,1); -} - -static int dtt200u_fe_sleep(struct dvb_frontend* fe) -{ - return dtt200u_fe_init(fe); -} - -static int dtt200u_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1500; - tune->step_size = 0; - tune->max_drift = 0; - return 0; -} - -static int dtt200u_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - int i; - fe_status_t st; - u16 freq = fep->frequency / 250000; - u8 bwbuf[2] = { SET_BANDWIDTH, 0 },freqbuf[3] = { SET_RF_FREQ, 0, 0 }; - - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: bwbuf[1] = 8; break; - case BANDWIDTH_7_MHZ: bwbuf[1] = 7; break; - case BANDWIDTH_6_MHZ: bwbuf[1] = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; - } - - dvb_usb_generic_write(state->d,bwbuf,2); - - freqbuf[1] = freq & 0xff; - freqbuf[2] = (freq >> 8) & 0xff; - dvb_usb_generic_write(state->d,freqbuf,3); - - for (i = 0; i < 30; i++) { - msleep(20); - dtt200u_fe_read_status(fe, &st); - if (st & FE_TIMEDOUT) - continue; - } - - return 0; -} - -static int dtt200u_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dtt200u_fe_state *state = fe->demodulator_priv; - memcpy(fep,&state->fep,sizeof(struct dvb_frontend_parameters)); - return 0; -} - -static void dtt200u_fe_release(struct dvb_frontend* fe) -{ - struct dtt200u_fe_state *state = (struct dtt200u_fe_state*) fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops dtt200u_fe_ops; - -struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) -{ - struct dtt200u_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL); - if (state == NULL) - goto error; - - deb_info("attaching frontend dtt200u\n"); - - state->d = d; - - memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - return NULL; -} - -static struct dvb_frontend_ops dtt200u_fe_ops = { - .info = { - .name = "WideView USB DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dtt200u_fe_release, - - .init = dtt200u_fe_init, - .sleep = dtt200u_fe_sleep, - - .set_frontend = dtt200u_fe_set_frontend, - .get_frontend = dtt200u_fe_get_frontend, - .get_tune_settings = dtt200u_fe_get_tune_settings, - - .read_status = dtt200u_fe_read_status, - .read_ber = dtt200u_fe_read_ber, - .read_signal_strength = dtt200u_fe_read_signal_strength, - .read_snr = dtt200u_fe_read_snr, - .read_ucblocks = dtt200u_fe_read_unc_blocks, -}; diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c deleted file mode 100644 index 81a6cbf6016..00000000000 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ /dev/null @@ -1,367 +0,0 @@ -/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/ - * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * Thanks to Steve Chang from WideView for providing support for the WT-220U. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dtt200u.h" - -/* debug */ -int dvb_usb_dtt200u_debug; -module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 b = SET_INIT; - - if (onoff) - dvb_usb_generic_write(d,&b,2); - - return 0; -} - -static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - u8 b_streaming[2] = { SET_STREAMING, onoff }; - u8 b_rst_pid = RESET_PID_FILTER; - - dvb_usb_generic_write(adap->dev, b_streaming, 2); - - if (onoff == 0) - dvb_usb_generic_write(adap->dev, &b_rst_pid, 1); - return 0; -} - -static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) -{ - u8 b_pid[4]; - pid = onoff ? pid : 0; - - b_pid[0] = SET_PID_FILTER; - b_pid[1] = index; - b_pid[2] = pid & 0xff; - b_pid[3] = (pid >> 8) & 0x1f; - - return dvb_usb_generic_write(adap->dev, b_pid, 4); -} - -/* remote control */ -/* key list for the tiny remote control (Yakumo, don't know about the others) */ -static struct dvb_usb_rc_key dtt200u_rc_keys[] = { - { 0x80, 0x01, KEY_MUTE }, - { 0x80, 0x02, KEY_CHANNELDOWN }, - { 0x80, 0x03, KEY_VOLUMEDOWN }, - { 0x80, 0x04, KEY_1 }, - { 0x80, 0x05, KEY_2 }, - { 0x80, 0x06, KEY_3 }, - { 0x80, 0x07, KEY_4 }, - { 0x80, 0x08, KEY_5 }, - { 0x80, 0x09, KEY_6 }, - { 0x80, 0x0a, KEY_7 }, - { 0x80, 0x0c, KEY_ZOOM }, - { 0x80, 0x0d, KEY_0 }, - { 0x80, 0x0e, KEY_SELECT }, - { 0x80, 0x12, KEY_POWER }, - { 0x80, 0x1a, KEY_CHANNELUP }, - { 0x80, 0x1b, KEY_8 }, - { 0x80, 0x1e, KEY_VOLUMEUP }, - { 0x80, 0x1f, KEY_9 }, -}; - -static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key[5],cmd = GET_RC_CODE; - dvb_usb_generic_rw(d,&cmd,1,key,5,0); - dvb_usb_nec_rc_key_to_event(d,key,event,state); - if (key[0] != 0) - deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); - return 0; -} - -static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap) -{ - adap->fe = dtt200u_fe_attach(adap->dev); - return 0; -} - -static struct dvb_usb_device_properties dtt200u_properties; -static struct dvb_usb_device_properties wt220u_fc_properties; -static struct dvb_usb_device_properties wt220u_properties; -static struct dvb_usb_device_properties wt220u_zl0353_properties; -static struct dvb_usb_device_properties wt220u_miglia_properties; - -static int dtt200u_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - if (0 == dvb_usb_device_init(intf, &dtt200u_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &wt220u_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &wt220u_fc_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties, - THIS_MODULE, NULL, adapter_nr)) - return 0; - - return -ENODEV; -} - -static struct usb_device_id dtt200u_usb_table [] = { - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) }, - { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD) }, - { 0 }, -}; -MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); - -static struct dvb_usb_device_properties dtt200u_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-dtt200u-01.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, - .pid_filter_count = 15, - - .streaming_ctrl = dtt200u_streaming_ctrl, - .pid_filter = dtt200u_pid_filter, - .frontend_attach = dtt200u_frontend_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .power_ctrl = dtt200u_power_ctrl, - - .rc_interval = 300, - .rc_key_map = dtt200u_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), - .rc_query = dtt200u_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)", - .cold_ids = { &dtt200u_usb_table[0], NULL }, - .warm_ids = { &dtt200u_usb_table[1], NULL }, - }, - { NULL }, - } -}; - -static struct dvb_usb_device_properties wt220u_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-wt220u-02.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, - .pid_filter_count = 15, - - .streaming_ctrl = dtt200u_streaming_ctrl, - .pid_filter = dtt200u_pid_filter, - .frontend_attach = dtt200u_frontend_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .power_ctrl = dtt200u_power_ctrl, - - .rc_interval = 300, - .rc_key_map = dtt200u_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), - .rc_query = dtt200u_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", - .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL }, - .warm_ids = { &dtt200u_usb_table[3], NULL }, - }, - { NULL }, - } -}; - -static struct dvb_usb_device_properties wt220u_fc_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-wt220u-fc03.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, - .pid_filter_count = 15, - - .streaming_ctrl = dtt200u_streaming_ctrl, - .pid_filter = dtt200u_pid_filter, - .frontend_attach = dtt200u_frontend_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .power_ctrl = dtt200u_power_ctrl, - - .rc_interval = 300, - .rc_key_map = dtt200u_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), - .rc_query = dtt200u_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", - .cold_ids = { &dtt200u_usb_table[6], NULL }, - .warm_ids = { &dtt200u_usb_table[7], NULL }, - }, - { NULL }, - } -}; - -static struct dvb_usb_device_properties wt220u_zl0353_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-wt220u-zl0353-01.fw", - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, - .pid_filter_count = 15, - - .streaming_ctrl = dtt200u_streaming_ctrl, - .pid_filter = dtt200u_pid_filter, - .frontend_attach = dtt200u_frontend_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .power_ctrl = dtt200u_power_ctrl, - - .rc_interval = 300, - .rc_key_map = dtt200u_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), - .rc_query = dtt200u_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { .name = "WideView WT-220U PenType Receiver (based on ZL353)", - .cold_ids = { &dtt200u_usb_table[4], NULL }, - .warm_ids = { &dtt200u_usb_table[5], NULL }, - }, - { NULL }, - } -}; - -static struct dvb_usb_device_properties wt220u_miglia_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-wt220u-miglia-01.fw", - - .num_adapters = 1, - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { .name = "WideView WT-220U PenType Receiver (Miglia)", - .cold_ids = { &dtt200u_usb_table[9], NULL }, - /* This device turns into WT220U_ZL0353_WARM when fw - has been uploaded */ - .warm_ids = { NULL }, - }, - { NULL }, - } -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver dtt200u_usb_driver = { - .name = "dvb_usb_dtt200u", - .probe = dtt200u_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dtt200u_usb_table, -}; - -/* module stuff */ -static int __init dtt200u_usb_module_init(void) -{ - int result; - if ((result = usb_register(&dtt200u_usb_driver))) { - err("usb_register failed. (%d)",result); - return result; - } - - return 0; -} - -static void __exit dtt200u_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dtt200u_usb_driver); -} - -module_init(dtt200u_usb_module_init); -module_exit(dtt200u_usb_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dtt200u.h b/drivers/media/dvb/dvb-usb/dtt200u.h deleted file mode 100644 index 005b0a7df35..00000000000 --- a/drivers/media/dvb/dvb-usb/dtt200u.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Common header file of Linux driver for the WideView/ Yakumo/ Hama/ - * Typhoon/ Yuan DVB-T USB2.0 receiver. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_DTT200U_H_ -#define _DVB_USB_DTT200U_H_ - -#define DVB_USB_LOG_PREFIX "dtt200u" - -#include "dvb-usb.h" - -extern int dvb_usb_dtt200u_debug; -#define deb_info(args...) dprintk(dvb_usb_dtt200u_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_dtt200u_debug,0x02,args) - -/* guessed protocol description (reverse engineered): - * read - * 00 - USB type 0x02 for usb2.0, 0x01 for usb1.1 - * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) - */ - -#define GET_SPEED 0x00 -#define GET_TUNE_STATUS 0x81 -#define GET_RC_CODE 0x84 -#define GET_CONFIGURATION 0x88 -#define GET_AGC 0x89 -#define GET_SNR 0x8a -#define GET_VIT_ERR_CNT 0x8c -#define GET_RS_ERR_CNT 0x8d -#define GET_RS_UNCOR_BLK_CNT 0x8e - -/* write - * 01 - init - * 02 - frequency (divided by 250000) - * 03 - bandwidth - * 04 - pid table (index pid(7:0) pid(12:8)) - * 05 - reset the pid table - * 08 - transfer switch - */ - -#define SET_INIT 0x01 -#define SET_RF_FREQ 0x02 -#define SET_BANDWIDTH 0x03 -#define SET_PID_FILTER 0x04 -#define RESET_PID_FILTER 0x05 -#define SET_STREAMING 0x08 - -extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); - -#endif diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c deleted file mode 100644 index 078ce92ca43..00000000000 --- a/drivers/media/dvb/dvb-usb/dtv5100.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T - * - * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com> - * http://royale.zerezo.com/dtv5100/ - * - * Inspired by gl861.c and au6610.c drivers - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "dtv5100.h" -#include "zl10353.h" -#include "qt1010.h" - -/* debug */ -static int dvb_usb_dtv5100_debug; -module_param_named(debug, dvb_usb_dtv5100_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int dtv5100_i2c_msg(struct dvb_usb_device *d, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u8 request; - u8 type; - u16 value; - u16 index; - - switch (wlen) { - case 1: - /* write { reg }, read { value } */ - request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_READ : - DTV5100_TUNER_READ); - type = USB_TYPE_VENDOR | USB_DIR_IN; - value = 0; - break; - case 2: - /* write { reg, value } */ - request = (addr == DTV5100_DEMOD_ADDR ? DTV5100_DEMOD_WRITE : - DTV5100_TUNER_WRITE); - type = USB_TYPE_VENDOR | USB_DIR_OUT; - value = wbuf[1]; - break; - default: - warn("wlen = %x, aborting.", wlen); - return -EINVAL; - } - index = (addr << 8) + wbuf[0]; - - msleep(1); /* avoid I2C errors */ - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), request, - type, value, index, rbuf, rlen, - DTV5100_USB_TIMEOUT); -} - -/* I2C */ -static int dtv5100_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, - msg[i+1].len) < 0) - break; - i++; - } else if (dtv5100_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, NULL, 0) < 0) - break; - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static u32 dtv5100_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm dtv5100_i2c_algo = { - .master_xfer = dtv5100_i2c_xfer, - .functionality = dtv5100_i2c_func, -}; - -/* Callbacks for DVB USB */ -static struct zl10353_config dtv5100_zl10353_config = { - .demod_address = DTV5100_DEMOD_ADDR, - .no_tuner = 1, - .parallel_ts = 1, -}; - -static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap) -{ - adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe == NULL) - return -EIO; - - /* disable i2c gate, or it won't work... is this safe? */ - adap->fe->ops.i2c_gate_ctrl = NULL; - - return 0; -} - -static struct qt1010_config dtv5100_qt1010_config = { - .i2c_address = DTV5100_TUNER_ADDR -}; - -static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap) -{ - return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, - &dtv5100_qt1010_config) == NULL ? -ENODEV : 0; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties dtv5100_properties; - -static int dtv5100_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int i, ret; - struct usb_device *udev = interface_to_usbdev(intf); - - /* initialize non qt1010/zl10353 part? */ - for (i = 0; dtv5100_init[i].request; i++) { - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - dtv5100_init[i].request, - USB_TYPE_VENDOR | USB_DIR_OUT, - dtv5100_init[i].value, - dtv5100_init[i].index, NULL, 0, - DTV5100_USB_TIMEOUT); - if (ret) - return ret; - } - - ret = dvb_usb_device_init(intf, &dtv5100_properties, - THIS_MODULE, NULL, adapter_nr); - if (ret) - return ret; - - return 0; -} - -static struct usb_device_id dtv5100_table[] = { - { USB_DEVICE(0x06be, 0xa232) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, dtv5100_table); - -static struct dvb_usb_device_properties dtv5100_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - - .size_of_priv = 0, - - .num_adapters = 1, - .adapter = {{ - .frontend_attach = dtv5100_frontend_attach, - .tuner_attach = dtv5100_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } }, - - .i2c_algo = &dtv5100_i2c_algo, - - .num_device_descs = 1, - .devices = { - { - .name = "AME DTV-5100 USB2.0 DVB-T", - .cold_ids = { NULL }, - .warm_ids = { &dtv5100_table[0], NULL }, - }, - } -}; - -static struct usb_driver dtv5100_driver = { - .name = "dvb_usb_dtv5100", - .probe = dtv5100_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dtv5100_table, -}; - -/* module stuff */ -static int __init dtv5100_module_init(void) -{ - int ret; - - ret = usb_register(&dtv5100_driver); - if (ret) - err("usb_register failed. Error number %d", ret); - - return ret; -} - -static void __exit dtv5100_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&dtv5100_driver); -} - -module_init(dtv5100_module_init); -module_exit(dtv5100_module_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dtv5100.h b/drivers/media/dvb/dvb-usb/dtv5100.h deleted file mode 100644 index 93e96e04a82..00000000000 --- a/drivers/media/dvb/dvb-usb/dtv5100.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * DVB USB Linux driver for AME DTV-5100 USB2.0 DVB-T - * - * Copyright (C) 2008 Antoine Jacquet <royale@zerezo.com> - * http://royale.zerezo.com/dtv5100/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _DVB_USB_DTV5100_H_ -#define _DVB_USB_DTV5100_H_ - -#define DVB_USB_LOG_PREFIX "dtv5100" -#include "dvb-usb.h" - -#define DTV5100_USB_TIMEOUT 500 - -#define DTV5100_DEMOD_ADDR 0x00 -#define DTV5100_DEMOD_WRITE 0xc0 -#define DTV5100_DEMOD_READ 0xc1 - -#define DTV5100_TUNER_ADDR 0xc4 -#define DTV5100_TUNER_WRITE 0xc7 -#define DTV5100_TUNER_READ 0xc8 - -#define DRIVER_AUTHOR "Antoine Jacquet, http://royale.zerezo.com/" -#define DRIVER_DESC "AME DTV-5100 USB2.0 DVB-T" - -static struct { - u8 request; - u8 value; - u16 index; -} dtv5100_init[] = { - { 0x000000c5, 0x00000000, 0x00000001 }, - { 0x000000c5, 0x00000001, 0x00000001 }, - { } /* Terminating entry */ -}; - -#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/drivers/media/dvb/dvb-usb/dvb-usb-common.h deleted file mode 100644 index 6b7b2a89242..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ /dev/null @@ -1,52 +0,0 @@ -/* dvb-usb-common.h is part of the DVB USB library. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * a header file containing prototypes and types for internal use of the dvb-usb-lib - */ -#ifndef _DVB_USB_COMMON_H_ -#define _DVB_USB_COMMON_H_ - -#define DVB_USB_LOG_PREFIX "dvb-usb" -#include "dvb-usb.h" - -extern int dvb_usb_debug; -extern int dvb_usb_disable_rc_polling; - -#define deb_info(args...) dprintk(dvb_usb_debug,0x001,args) -#define deb_xfer(args...) dprintk(dvb_usb_debug,0x002,args) -#define deb_pll(args...) dprintk(dvb_usb_debug,0x004,args) -#define deb_ts(args...) dprintk(dvb_usb_debug,0x008,args) -#define deb_err(args...) dprintk(dvb_usb_debug,0x010,args) -#define deb_rc(args...) dprintk(dvb_usb_debug,0x020,args) -#define deb_fw(args...) dprintk(dvb_usb_debug,0x040,args) -#define deb_mem(args...) dprintk(dvb_usb_debug,0x080,args) -#define deb_uxfer(args...) dprintk(dvb_usb_debug,0x100,args) - -/* commonly used methods */ -extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_device_properties *); - -extern int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff); - -extern int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props); -extern int usb_urb_exit(struct usb_data_stream *stream); -extern int usb_urb_submit(struct usb_data_stream *stream); -extern int usb_urb_kill(struct usb_data_stream *stream); - -extern int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap); -extern int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap); - -extern int dvb_usb_i2c_init(struct dvb_usb_device *); -extern int dvb_usb_i2c_exit(struct dvb_usb_device *); - -extern int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, - short *adapter_nums); -extern int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap); -extern int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap); -extern int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap); - -extern int dvb_usb_remote_init(struct dvb_usb_device *); -extern int dvb_usb_remote_exit(struct dvb_usb_device *); - -#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c deleted file mode 100644 index 8a7d87bcd1d..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ /dev/null @@ -1,204 +0,0 @@ -/* dvb-usb-dvb.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file contains functions for initializing and handling the - * linux-dvb API. - */ -#include "dvb-usb-common.h" - -/* does the complete input transfer handling */ -static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) -{ - struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv; - int newfeedcount,ret; - - if (adap == NULL) - return -ENODEV; - - 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); - - if (adap->props.streaming_ctrl != NULL) - if ((ret = adap->props.streaming_ctrl(adap,0))) - err("error while stopping stream."); - } - - 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); - - /* 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); - - deb_ts("controlling pid parser\n"); - if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER && - adap->props.caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF && - adap->props.pid_filter_ctrl != NULL) - if (adap->props.pid_filter_ctrl(adap,adap->pid_filtering) < 0) - err("could not handle pid_parser"); - - deb_ts("start feeding\n"); - if (adap->props.streaming_ctrl != NULL) - if (adap->props.streaming_ctrl(adap,1)) { - err("error while enabling fifo."); - return -ENODEV; - } - - } - return 0; -} - -static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - deb_ts("start pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid,dvbdmxfeed->type); - return dvb_usb_ctrl_feed(dvbdmxfeed,1); -} - -static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - deb_ts("stop pid: 0x%04x, feedtype: %d\n", dvbdmxfeed->pid, dvbdmxfeed->type); - return dvb_usb_ctrl_feed(dvbdmxfeed,0); -} - -int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) -{ - int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name, - adap->dev->owner, &adap->dev->udev->dev, - adapter_nums); - - if (ret < 0) { - deb_info("dvb_register_adapter failed: error %d", ret); - goto err; - } - adap->dvb_adap.priv = adap; - - if (adap->dev->props.read_mac_address) { - if (adap->dev->props.read_mac_address(adap->dev,adap->dvb_adap.proposed_mac) == 0) - info("MAC address: %pM",adap->dvb_adap.proposed_mac); - else - err("MAC address reading failed."); - } - - - 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.start_feed = dvb_usb_start_feed; - adap->demux.stop_feed = dvb_usb_stop_feed; - adap->demux.write_to_decoder = NULL; - if ((ret = dvb_dmx_init(&adap->demux)) < 0) { - err("dvb_dmx_init failed: error %d",ret); - goto err_dmx; - } - - adap->dmxdev.filternum = adap->demux.filternum; - adap->dmxdev.demux = &adap->demux.dmx; - adap->dmxdev.capabilities = 0; - if ((ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap)) < 0) { - err("dvb_dmxdev_init failed: error %d",ret); - goto err_dmx_dev; - } - - dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); - - adap->state |= DVB_USB_ADAP_STATE_DVB; - return 0; - -err_dmx_dev: - dvb_dmx_release(&adap->demux); -err_dmx: - dvb_unregister_adapter(&adap->dvb_adap); -err: - return ret; -} - -int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap) -{ - if (adap->state & DVB_USB_ADAP_STATE_DVB) { - deb_info("unregistering DVB part\n"); - dvb_net_release(&adap->dvb_net); - adap->demux.dmx.close(&adap->demux.dmx); - dvb_dmxdev_release(&adap->dmxdev); - dvb_dmx_release(&adap->demux); - dvb_unregister_adapter(&adap->dvb_adap); - adap->state &= ~DVB_USB_ADAP_STATE_DVB; - } - 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); - - return 0; -} - -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); - - 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; - } - - /* 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; - - if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) { - err("Frontend registration failed."); - dvb_frontend_detach(adap->fe); - adap->fe = NULL; - return -ENODEV; - } - - /* 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); - - 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); - } - return 0; -} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c deleted file mode 100644 index 733a7ff7b20..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ /dev/null @@ -1,146 +0,0 @@ -/* dvb-usb-firmware.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file contains functions for downloading the firmware to Cypress FX 1 and 2 based devices. - * - * FIXME: This part does actually not belong to dvb-usb, but to the usb-subsystem. - */ -#include "dvb-usb-common.h" - -#include <linux/usb.h> - -struct usb_cypress_controller { - int id; - const char *name; /* name of the usb controller */ - u16 cpu_cs_register; /* needs to be restarted, when the firmware has been downloaded. */ -}; - -static struct usb_cypress_controller cypress[] = { - { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 }, - { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, - { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, - { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, -}; - -/* - * load a firmware packet to the device - */ -static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) -{ - return usb_control_msg(udev, usb_sndctrlpipe(udev,0), - 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000); -} - -int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) -{ - struct hexline hx; - u8 reset; - int ret,pos=0; - - /* stop the CPU */ - reset = 1; - if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) - err("could not stop the USB controller CPU."); - - while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { - deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); - ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); - - if (ret != hx.len) { - err("error while transferring firmware " - "(transferred size: %d, block size: %d)", - ret,hx.len); - ret = -EINVAL; - break; - } - } - if (ret < 0) { - err("firmware download failed at %d with %d",pos,ret); - return ret; - } - - if (ret == 0) { - /* restart the CPU */ - reset = 0; - if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { - err("could not restart the USB controller CPU."); - ret = -EINVAL; - } - } else - ret = -EIO; - - return ret; -} -EXPORT_SYMBOL(usb_cypress_load_firmware); - -int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_device_properties *props) -{ - int ret; - const struct firmware *fw = NULL; - - if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", - props->firmware,ret); - return ret; - } - - info("downloading firmware from file '%s'",props->firmware); - - switch (props->usb_ctrl) { - case CYPRESS_AN2135: - case CYPRESS_AN2235: - case CYPRESS_FX2: - ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl); - break; - case DEVICE_SPECIFIC: - if (props->download_firmware) - ret = props->download_firmware(udev,fw); - else { - err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one."); - ret = -EINVAL; - } - break; - default: - ret = -EINVAL; - break; - } - - release_firmware(fw); - return ret; -} - -int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, - int *pos) -{ - u8 *b = (u8 *) &fw->data[*pos]; - int data_offs = 4; - if (*pos >= fw->size) - return 0; - - memset(hx,0,sizeof(struct hexline)); - - hx->len = b[0]; - - if ((*pos + hx->len + 4) >= fw->size) - return -EINVAL; - - hx->addr = b[1] | (b[2] << 8); - hx->type = b[3]; - - if (hx->type == 0x04) { - /* b[4] and b[5] are the Extended linear address record data field */ - hx->addr |= (b[4] << 24) | (b[5] << 16); -/* hx->len -= 2; - data_offs += 2; */ - } - memcpy(hx->data,&b[data_offs],hx->len); - hx->chk = b[hx->len + data_offs]; - - *pos += hx->len + 5; - - return *pos; -} -EXPORT_SYMBOL(dvb_usb_get_hexline); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c deleted file mode 100644 index 326f7608954..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ /dev/null @@ -1,44 +0,0 @@ -/* dvb-usb-i2c.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file contains functions for (de-)initializing an I2C adapter. - */ -#include "dvb-usb-common.h" - -int dvb_usb_i2c_init(struct dvb_usb_device *d) -{ - int ret = 0; - - if (!(d->props.caps & DVB_USB_IS_AN_I2C_ADAPTER)) - return 0; - - if (d->props.i2c_algo == NULL) { - err("no i2c algorithm specified"); - return -EINVAL; - } - - strncpy(d->i2c_adap.name, d->desc->name, sizeof(d->i2c_adap.name)); - d->i2c_adap.class = I2C_CLASS_TV_DIGITAL, - d->i2c_adap.algo = d->props.i2c_algo; - d->i2c_adap.algo_data = NULL; - d->i2c_adap.dev.parent = &d->udev->dev; - - i2c_set_adapdata(&d->i2c_adap, d); - - if ((ret = i2c_add_adapter(&d->i2c_adap)) < 0) - err("could not add i2c adapter"); - - d->state |= DVB_USB_STATE_I2C; - - return ret; -} - -int dvb_usb_i2c_exit(struct dvb_usb_device *d) -{ - if (d->state & DVB_USB_STATE_I2C) - i2c_del_adapter(&d->i2c_adap); - d->state &= ~DVB_USB_STATE_I2C; - return 0; -} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h deleted file mode 100644 index a4fca3fca5e..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ /dev/null @@ -1,238 +0,0 @@ -/* dvb-usb-ids.h is part of the DVB USB library. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) see - * dvb-usb-init.c for copyright information. - * - * a header file containing define's for the USB device supported by the - * various drivers. - */ -#ifndef _DVB_USB_IDS_H_ -#define _DVB_USB_IDS_H_ - -/* Vendor IDs */ -#define USB_VID_ADSTECH 0x06e1 -#define USB_VID_AFATECH 0x15a4 -#define USB_VID_ALCOR_MICRO 0x058f -#define USB_VID_ALINK 0x05e3 -#define USB_VID_AMT 0x1c73 -#define USB_VID_ANCHOR 0x0547 -#define USB_VID_ANSONIC 0x10b9 -#define USB_VID_ANUBIS_ELECTRONIC 0x10fd -#define USB_VID_ASUS 0x0b05 -#define USB_VID_AVERMEDIA 0x07ca -#define USB_VID_COMPRO 0x185b -#define USB_VID_COMPRO_UNK 0x145f -#define USB_VID_CONEXANT 0x0572 -#define USB_VID_CYPRESS 0x04b4 -#define USB_VID_DIBCOM 0x10b8 -#define USB_VID_DPOSH 0x1498 -#define USB_VID_DVICO 0x0fe9 -#define USB_VID_EMPIA 0xeb1a -#define USB_VID_GENPIX 0x09c0 -#define USB_VID_GRANDTEC 0x5032 -#define USB_VID_HANFTEK 0x15f4 -#define USB_VID_HAUPPAUGE 0x2040 -#define USB_VID_HYPER_PALTEK 0x1025 -#define USB_VID_KWORLD 0xeb2a -#define USB_VID_KWORLD_2 0x1b80 -#define USB_VID_KYE 0x0458 -#define USB_VID_LEADTEK 0x0413 -#define USB_VID_LITEON 0x04ca -#define USB_VID_MEDION 0x1660 -#define USB_VID_MIGLIA 0x18f3 -#define USB_VID_MSI 0x0db0 -#define USB_VID_MSI_2 0x1462 -#define USB_VID_OPERA1 0x695c -#define USB_VID_PINNACLE 0x2304 -#define USB_VID_TECHNOTREND 0x0b48 -#define USB_VID_TERRATEC 0x0ccd -#define USB_VID_TELESTAR 0x10b9 -#define USB_VID_VISIONPLUS 0x13d3 -#define USB_VID_TWINHAN 0x1822 -#define USB_VID_ULTIMA_ELECTRONIC 0x05d8 -#define USB_VID_UNIWILL 0x1584 -#define USB_VID_WIDEVIEW 0x14aa -#define USB_VID_GIGABYTE 0x1044 -#define USB_VID_YUAN 0x1164 -#define USB_VID_XTENSIONS 0x1ae7 - -/* Product IDs */ -#define USB_PID_ADSTECH_USB2_COLD 0xa333 -#define USB_PID_ADSTECH_USB2_WARM 0xa334 -#define USB_PID_AFATECH_AF9005 0x9020 -#define USB_PID_AFATECH_AF9015_9015 0x9015 -#define USB_PID_AFATECH_AF9015_9016 0x9016 -#define USB_VID_ALINK_DTU 0xf170 -#define USB_PID_ANSONIC_DVBT_USB 0x6000 -#define USB_PID_ANYSEE 0x861f -#define USB_PID_AZUREWAVE_AD_TU700 0x3237 -#define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 -#define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 -#define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 -#define USB_PID_AVERMEDIA_DVBT_USB2_WARM 0xa801 -#define USB_PID_COMPRO_DVBU2000_COLD 0xd000 -#define USB_PID_COMPRO_DVBU2000_WARM 0xd001 -#define USB_PID_COMPRO_DVBU2000_UNK_COLD 0x010c -#define USB_PID_COMPRO_DVBU2000_UNK_WARM 0x010d -#define USB_PID_COMPRO_VIDEOMATE_U500 0x1e78 -#define USB_PID_COMPRO_VIDEOMATE_U500_PC 0x1e80 -#define USB_PID_CONEXANT_D680_DMB 0x86d6 -#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064 -#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065 -#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8 -#define USB_PID_DIBCOM_MOD3000_WARM 0x0bb9 -#define USB_PID_DIBCOM_MOD3001_COLD 0x0bc6 -#define USB_PID_DIBCOM_MOD3001_WARM 0x0bc7 -#define USB_PID_DIBCOM_STK7700P 0x1e14 -#define USB_PID_DIBCOM_STK7700P_PC 0x1e78 -#define USB_PID_DIBCOM_STK7700D 0x1ef0 -#define USB_PID_DIBCOM_STK7700_U7000 0x7001 -#define USB_PID_DIBCOM_STK7070P 0x1ebc -#define USB_PID_DIBCOM_STK7070PD 0x1ebe -#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 -#define USB_PID_DPOSH_M9206_COLD 0x9206 -#define USB_PID_DPOSH_M9206_WARM 0xa090 -#define USB_PID_UNIWILL_STK7700P 0x6003 -#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 -#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 -#define USB_PID_KWORLD_399U 0xe399 -#define USB_PID_KWORLD_395U 0xe396 -#define USB_PID_KWORLD_PC160_2T 0xc160 -#define USB_PID_KWORLD_VSTREAM_COLD 0x17de -#define USB_PID_KWORLD_VSTREAM_WARM 0x17df -#define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 -#define USB_PID_TERRATEC_CINERGY_T_USB_XE_REV2 0x0069 -#define USB_PID_TWINHAN_VP7041_COLD 0x3201 -#define USB_PID_TWINHAN_VP7041_WARM 0x3202 -#define USB_PID_TWINHAN_VP7020_COLD 0x3203 -#define USB_PID_TWINHAN_VP7020_WARM 0x3204 -#define USB_PID_TWINHAN_VP7045_COLD 0x3205 -#define USB_PID_TWINHAN_VP7045_WARM 0x3206 -#define USB_PID_TWINHAN_VP7021_COLD 0x3207 -#define USB_PID_TWINHAN_VP7021_WARM 0x3208 -#define USB_PID_TINYTWIN 0x3226 -#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 -#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 -#define USB_PID_ULTIMA_TVBOX_COLD 0x8105 -#define USB_PID_ULTIMA_TVBOX_WARM 0x8106 -#define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 -#define USB_PID_ULTIMA_TVBOX_AN2235_WARM 0x8108 -#define USB_PID_ULTIMA_TVBOX_ANCHOR_COLD 0x2235 -#define USB_PID_ULTIMA_TVBOX_USB2_COLD 0x8109 -#define USB_PID_ULTIMA_TVBOX_USB2_WARM 0x810a -#define USB_PID_ARTEC_T14_COLD 0x810b -#define USB_PID_ARTEC_T14_WARM 0x810c -#define USB_PID_ARTEC_T14BR 0x810f -#define USB_PID_ULTIMA_TVBOX_USB2_FX_COLD 0x8613 -#define USB_PID_ULTIMA_TVBOX_USB2_FX_WARM 0x1002 -#define USB_PID_UNK_HYPER_PALTEK_COLD 0x005e -#define USB_PID_UNK_HYPER_PALTEK_WARM 0x005f -#define USB_PID_HANFTEK_UMT_010_COLD 0x0001 -#define USB_PID_HANFTEK_UMT_010_WARM 0x0015 -#define USB_PID_DTT200U_COLD 0x0201 -#define USB_PID_DTT200U_WARM 0x0301 -#define USB_PID_WT220U_ZAP250_COLD 0x0220 -#define USB_PID_WT220U_COLD 0x0222 -#define USB_PID_WT220U_WARM 0x0221 -#define USB_PID_WT220U_FC_COLD 0x0225 -#define USB_PID_WT220U_FC_WARM 0x0226 -#define USB_PID_WT220U_ZL0353_COLD 0x022a -#define USB_PID_WT220U_ZL0353_WARM 0x022b -#define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 -#define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 -#define USB_PID_HAUPPAUGE_NOVA_T_500 0x9941 -#define USB_PID_HAUPPAUGE_NOVA_T_500_2 0x9950 -#define USB_PID_HAUPPAUGE_NOVA_T_500_3 0x8400 -#define USB_PID_HAUPPAUGE_NOVA_T_STICK 0x7050 -#define USB_PID_HAUPPAUGE_NOVA_T_STICK_2 0x7060 -#define USB_PID_HAUPPAUGE_NOVA_T_STICK_3 0x7070 -#define USB_PID_HAUPPAUGE_MYTV_T 0x7080 -#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580 -#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200 -#define USB_PID_AVERMEDIA_EXPRESS 0xb568 -#define USB_PID_AVERMEDIA_VOLAR 0xa807 -#define USB_PID_AVERMEDIA_VOLAR_2 0xb808 -#define USB_PID_AVERMEDIA_VOLAR_A868R 0xa868 -#define USB_PID_AVERMEDIA_MCE_USB_M038 0x1228 -#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R 0x0039 -#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_ATSC 0x1039 -#define USB_PID_AVERMEDIA_HYBRID_ULTRA_USB_M039R_DVBT 0x2039 -#define USB_PID_AVERMEDIA_VOLAR_X 0xa815 -#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150 -#define USB_PID_AVERMEDIA_A309 0xa309 -#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006 -#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a -#define USB_PID_TERRATEC_CINERGY_HT_USB_XE 0x0058 -#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 -#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 -#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e -#define USB_PID_PINNACLE_PCTV2000E 0x022c -#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228 -#define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T 0x0229 -#define USB_PID_PINNACLE_PCTV71E 0x022b -#define USB_PID_PINNACLE_PCTV72E 0x0236 -#define USB_PID_PINNACLE_PCTV73E 0x0237 -#define USB_PID_PINNACLE_PCTV801E 0x023a -#define USB_PID_PINNACLE_PCTV801E_SE 0x023b -#define USB_PID_PCTV_200E 0x020e -#define USB_PID_PCTV_400E 0x020f -#define USB_PID_PCTV_450E 0x0222 -#define USB_PID_NEBULA_DIGITV 0x0201 -#define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 -#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500 -#define USB_PID_DVICO_BLUEBIRD_LG064F_WARM 0xd501 -#define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD 0xdb00 -#define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM 0xdb01 -#define USB_PID_DVICO_BLUEBIRD_TH7579_COLD 0xdb10 -#define USB_PID_DVICO_BLUEBIRD_TH7579_WARM 0xdb11 -#define USB_PID_DVICO_BLUEBIRD_DUAL_1_COLD 0xdb50 -#define USB_PID_DVICO_BLUEBIRD_DUAL_1_WARM 0xdb51 -#define USB_PID_DVICO_BLUEBIRD_DUAL_2_COLD 0xdb58 -#define USB_PID_DVICO_BLUEBIRD_DUAL_2_WARM 0xdb59 -#define USB_PID_DVICO_BLUEBIRD_DUAL_4 0xdb78 -#define USB_PID_DVICO_BLUEBIRD_DUAL_4_REV_2 0xdb98 -#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2 0xdb70 -#define USB_PID_DVICO_BLUEBIRD_DVB_T_NANO_2_NFW_WARM 0xdb71 -#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 -#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55 -#define USB_PID_MEDION_MD95700 0x0932 -#define USB_PID_MSI_MEGASKY580 0x5580 -#define USB_PID_MSI_MEGASKY580_55801 0x5581 -#define USB_PID_KYE_DVB_T_COLD 0x701e -#define USB_PID_KYE_DVB_T_WARM 0x701f -#define USB_PID_LITEON_DVB_T_COLD 0xf000 -#define USB_PID_LITEON_DVB_T_WARM 0xf001 -#define USB_PID_DIGIVOX_MINI_SL_COLD 0xe360 -#define USB_PID_DIGIVOX_MINI_SL_WARM 0xe361 -#define USB_PID_GRANDTEC_DVBT_USB2_COLD 0x0bc6 -#define USB_PID_GRANDTEC_DVBT_USB2_WARM 0x0bc7 -#define USB_PID_WINFAST_DTV_DONGLE_COLD 0x6025 -#define USB_PID_WINFAST_DTV_DONGLE_WARM 0x6026 -#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 -#define USB_PID_WINFAST_DTV_DONGLE_STK7700P_2 0x6f01 -#define USB_PID_WINFAST_DTV_DONGLE_GOLD 0x6029 -#define USB_PID_GENPIX_8PSK_REV_1_COLD 0x0200 -#define USB_PID_GENPIX_8PSK_REV_1_WARM 0x0201 -#define USB_PID_GENPIX_8PSK_REV_2 0x0202 -#define USB_PID_GENPIX_SKYWALKER_1 0x0203 -#define USB_PID_GENPIX_SKYWALKER_CW3K 0x0204 -#define USB_PID_SIGMATEK_DVB_110 0x6610 -#define USB_PID_MSI_DIGI_VOX_MINI_II 0x1513 -#define USB_PID_MSI_DIGIVOX_DUO 0x8801 -#define USB_PID_OPERA1_COLD 0x2830 -#define USB_PID_OPERA1_WARM 0x3829 -#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD 0x0514 -#define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM 0x0513 -#define USB_PID_GIGABYTE_U7000 0x7001 -#define USB_PID_GIGABYTE_U8000 0x7002 -#define USB_PID_ASUS_U3000 0x171f -#define USB_PID_ASUS_U3000H 0x1736 -#define USB_PID_ASUS_U3100 0x173f -#define USB_PID_YUAN_EC372S 0x1edc -#define USB_PID_YUAN_STK7700PH 0x1f08 -#define USB_PID_DW2102 0x2102 -#define USB_PID_XTENSIONS_XD_380 0x0381 -#define USB_PID_TELESTAR_STARSTICK_2 0x8000 -#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807 - -#endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c deleted file mode 100644 index e331db8c77b..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * DVB USB library - provides a generic interface for a DVB USB device driver. - * - * dvb-usb-init.c - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dvb-usb-common.h" - -/* debug */ -int dvb_usb_debug; -module_param_named(debug,dvb_usb_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))." DVB_USB_DEBUG_STATUS); - -int dvb_usb_disable_rc_polling; -module_param_named(disable_rc_polling, dvb_usb_disable_rc_polling, int, 0644); -MODULE_PARM_DESC(disable_rc_polling, "disable remote control polling (default: 0)."); - -static int dvb_usb_force_pid_filter_usage; -module_param_named(force_pid_filter_usage, dvb_usb_force_pid_filter_usage, int, 0444); -MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID filter, if any (default: 0)."); - -static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) -{ - struct dvb_usb_adapter *adap; - int ret,n; - - for (n = 0; n < d->props.num_adapters; n++) { - adap = &d->adapter[n]; - adap->dev = d; - adap->id = n; - - memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties)); - -/* 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)) { - 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; - } else { - info("will pass the complete MPEG2 transport stream to the software demuxer."); - adap->pid_filtering = 0; - adap->max_feed_count = 255; - } - - if (!adap->pid_filtering && - dvb_usb_force_pid_filter_usage && - adap->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; - } - - if (adap->props.size_of_priv > 0) { - adap->priv = kzalloc(adap->props.size_of_priv,GFP_KERNEL); - if (adap->priv == NULL) { - err("no memory for priv for adapter %d.",n); - return -ENOMEM; - } - } - - if ((ret = dvb_usb_adapter_stream_init(adap)) || - (ret = dvb_usb_adapter_dvb_init(adap, adapter_nrs)) || - (ret = dvb_usb_adapter_frontend_init(adap))) { - return ret; - } - - d->num_adapters_initialized++; - d->state |= DVB_USB_STATE_DVB; - } - - /* - * when reloading the driver w/o replugging the device - * sometimes a timeout occures, this helps - */ - if (d->props.generic_bulk_ctrl_endpoint != 0) { - usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); - usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint)); - } - - return 0; -} - -static int dvb_usb_adapter_exit(struct dvb_usb_device *d) -{ - int n; - for (n = 0; n < d->num_adapters_initialized; n++) { - dvb_usb_adapter_frontend_exit(&d->adapter[n]); - dvb_usb_adapter_dvb_exit(&d->adapter[n]); - dvb_usb_adapter_stream_exit(&d->adapter[n]); - kfree(d->adapter[n].priv); - } - d->num_adapters_initialized = 0; - d->state &= ~DVB_USB_STATE_DVB; - return 0; -} - - -/* general initialization functions */ -static int dvb_usb_exit(struct dvb_usb_device *d) -{ - deb_info("state before exiting everything: %x\n",d->state); - dvb_usb_remote_exit(d); - dvb_usb_adapter_exit(d); - dvb_usb_i2c_exit(d); - deb_info("state should be zero now: %x\n",d->state); - d->state = DVB_USB_STATE_INIT; - kfree(d->priv); - kfree(d); - return 0; -} - -static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums) -{ - int ret = 0; - - mutex_init(&d->usb_mutex); - mutex_init(&d->i2c_mutex); - - d->state = DVB_USB_STATE_INIT; - - if (d->props.size_of_priv > 0) { - d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL); - if (d->priv == NULL) { - err("no memory for priv in 'struct dvb_usb_device'"); - return -ENOMEM; - } - } - -/* check the capabilities and set appropriate variables */ - dvb_usb_device_power_ctrl(d, 1); - - if ((ret = dvb_usb_i2c_init(d)) || - (ret = dvb_usb_adapter_init(d, adapter_nums))) { - dvb_usb_exit(d); - return ret; - } - - if ((ret = dvb_usb_remote_init(d))) - err("could not initialize remote control."); - - dvb_usb_device_power_ctrl(d, 0); - - return 0; -} - -/* determine the name and the state of the just found USB device */ -static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_device_properties *props, int *cold) -{ - int i,j; - struct dvb_usb_device_description *desc = NULL; - *cold = -1; - - for (i = 0; i < props->num_device_descs; i++) { - - for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) { - deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct); - if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && - props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { - *cold = 1; - desc = &props->devices[i]; - break; - } - } - - if (desc != NULL) - break; - - for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) { - deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct); - if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) && - props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) { - *cold = 0; - desc = &props->devices[i]; - break; - } - } - } - - if (desc != NULL && props->identify_state != NULL) - props->identify_state(udev,props,&desc,cold); - - return desc; -} - -int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - if (onoff) - d->powered++; - else - d->powered--; - - if (d->powered == 0 || (onoff && d->powered == 1)) { // when switching from 1 to 0 or from 0 to 1 - deb_info("power control: %d\n", onoff); - if (d->props.power_ctrl) - return d->props.power_ctrl(d, onoff); - } - return 0; -} - -/* - * USB - */ -int dvb_usb_device_init(struct usb_interface *intf, - struct dvb_usb_device_properties *props, - struct module *owner, struct dvb_usb_device **du, - short *adapter_nums) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct dvb_usb_device *d = NULL; - struct dvb_usb_device_description *desc = NULL; - - int ret = -ENOMEM,cold=0; - - if (du != NULL) - *du = NULL; - - if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { - deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); - return -ENODEV; - } - - if (cold) { - info("found a '%s' in cold state, will try to load a firmware",desc->name); - ret = dvb_usb_download_firmware(udev,props); - if (!props->no_reconnect || ret != 0) - return ret; - } - - info("found a '%s' in warm state.",desc->name); - d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); - if (d == NULL) { - err("no memory for 'struct dvb_usb_device'"); - return ret; - } - - d->udev = udev; - memcpy(&d->props,props,sizeof(struct dvb_usb_device_properties)); - d->desc = desc; - d->owner = owner; - - usb_set_intfdata(intf, d); - - if (du != NULL) - *du = d; - - ret = dvb_usb_init(d, adapter_nums); - - if (ret == 0) - info("%s successfully initialized and connected.",desc->name); - else - info("%s error while loading driver (%d)",desc->name,ret); - return ret; -} -EXPORT_SYMBOL(dvb_usb_device_init); - -void dvb_usb_device_exit(struct usb_interface *intf) -{ - struct dvb_usb_device *d = usb_get_intfdata(intf); - const char *name = "generic DVB-USB module"; - - usb_set_intfdata(intf,NULL); - if (d != NULL && d->desc != NULL) { - name = d->desc->name; - dvb_usb_exit(d); - } - info("%s successfully deinitialized and disconnected.",name); - -} -EXPORT_SYMBOL(dvb_usb_device_exit); - -MODULE_VERSION("1.0"); -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c deleted file mode 100644 index c0c2c22ddd8..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ /dev/null @@ -1,198 +0,0 @@ -/* dvb-usb-remote.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file contains functions for initializing the input-device and for handling remote-control-queries. - */ -#include "dvb-usb-common.h" -#include <linux/usb/input.h> - -/* Remote-control poll function - called every dib->rc_query_interval ms to see - * whether the remote control has received anything. - * - * TODO: Fix the repeat rate of the input device. - */ -static void dvb_usb_read_remote_control(struct work_struct *work) -{ - struct dvb_usb_device *d = - container_of(work, struct dvb_usb_device, rc_query_work.work); - u32 event; - int state; - - /* TODO: need a lock here. We can simply skip checking for the remote control - if we're busy. */ - - /* when the parameter has been set to 1 via sysfs while the driver was running */ - if (dvb_usb_disable_rc_polling) - return; - - if (d->props.rc_query(d,&event,&state)) { - err("error while querying for an remote control event."); - goto schedule; - } - - - switch (state) { - case REMOTE_NO_KEY_PRESSED: - break; - case REMOTE_KEY_PRESSED: - deb_rc("key pressed\n"); - d->last_event = event; - case REMOTE_KEY_REPEAT: - deb_rc("key repeated\n"); - input_event(d->rc_input_dev, EV_KEY, event, 1); - input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); - input_sync(d->rc_input_dev); - break; - default: - break; - } - -/* improved repeat handling ??? - switch (state) { - case REMOTE_NO_KEY_PRESSED: - deb_rc("NO KEY PRESSED\n"); - if (d->last_state != REMOTE_NO_KEY_PRESSED) { - deb_rc("releasing event %d\n",d->last_event); - input_event(d->rc_input_dev, EV_KEY, d->last_event, 0); - input_sync(d->rc_input_dev); - } - d->last_state = REMOTE_NO_KEY_PRESSED; - d->last_event = 0; - break; - case REMOTE_KEY_PRESSED: - deb_rc("KEY PRESSED\n"); - deb_rc("pressing event %d\n",event); - - input_event(d->rc_input_dev, EV_KEY, event, 1); - input_sync(d->rc_input_dev); - - d->last_event = event; - d->last_state = REMOTE_KEY_PRESSED; - break; - case REMOTE_KEY_REPEAT: - deb_rc("KEY_REPEAT\n"); - if (d->last_state != REMOTE_NO_KEY_PRESSED) { - deb_rc("repeating event %d\n",d->last_event); - input_event(d->rc_input_dev, EV_KEY, d->last_event, 2); - input_sync(d->rc_input_dev); - d->last_state = REMOTE_KEY_REPEAT; - } - default: - break; - } -*/ - -schedule: - schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); -} - -int dvb_usb_remote_init(struct dvb_usb_device *d) -{ - struct input_dev *input_dev; - int i; - int err; - - if (d->props.rc_key_map == NULL || - d->props.rc_query == NULL || - dvb_usb_disable_rc_polling) - return 0; - - usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys)); - strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys)); - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - input_dev->evbit[0] = BIT_MASK(EV_KEY); - input_dev->name = "IR-receiver inside an USB DVB receiver"; - input_dev->phys = d->rc_phys; - usb_to_input_id(d->udev, &input_dev->id); - input_dev->dev.parent = &d->udev->dev; - - /* set the bits for the keys */ - deb_rc("key map size: %d\n", d->props.rc_key_map_size); - for (i = 0; i < d->props.rc_key_map_size; i++) { - deb_rc("setting bit for event %d item %d\n", - d->props.rc_key_map[i].event, i); - set_bit(d->props.rc_key_map[i].event, input_dev->keybit); - } - - /* Start the remote-control polling. */ - if (d->props.rc_interval < 40) - d->props.rc_interval = 100; /* default */ - - /* setting these two values to non-zero, we have to manage key repeats */ - input_dev->rep[REP_PERIOD] = d->props.rc_interval; - input_dev->rep[REP_DELAY] = d->props.rc_interval + 150; - - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; - } - - d->rc_input_dev = input_dev; - - INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); - - info("schedule remote query interval to %d msecs.", d->props.rc_interval); - schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); - - d->state |= DVB_USB_STATE_REMOTE; - - return 0; -} - -int dvb_usb_remote_exit(struct dvb_usb_device *d) -{ - if (d->state & DVB_USB_STATE_REMOTE) { - cancel_rearming_delayed_work(&d->rc_query_work); - flush_scheduled_work(); - input_unregister_device(d->rc_input_dev); - } - d->state &= ~DVB_USB_STATE_REMOTE; - return 0; -} - -#define DVB_USB_RC_NEC_EMPTY 0x00 -#define DVB_USB_RC_NEC_KEY_PRESSED 0x01 -#define DVB_USB_RC_NEC_KEY_REPEATED 0x02 -int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *d, - u8 keybuf[5], u32 *event, int *state) -{ - int i; - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - switch (keybuf[0]) { - case DVB_USB_RC_NEC_EMPTY: - break; - case DVB_USB_RC_NEC_KEY_PRESSED: - if ((u8) ~keybuf[1] != keybuf[2] || - (u8) ~keybuf[3] != keybuf[4]) { - deb_err("remote control checksum failed.\n"); - break; - } - /* See if we can match the raw key code. */ - for (i = 0; i < d->props.rc_key_map_size; i++) - if (keymap[i].custom == keybuf[1] && - keymap[i].data == keybuf[3]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - return 0; - } - deb_err("key mapping failed - no appropriate key found in keymapping\n"); - break; - case DVB_USB_RC_NEC_KEY_REPEATED: - *state = REMOTE_KEY_REPEAT; - break; - default: - deb_err("unkown type of remote status: %d\n",keybuf[0]); - break; - } - return 0; -} -EXPORT_SYMBOL(dvb_usb_nec_rc_key_to_event); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c deleted file mode 100644 index 6fe71c6745e..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ /dev/null @@ -1,95 +0,0 @@ -/* dvb-usb-urb.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file keeps functions for initializing and handling the - * USB and URB stuff. - */ -#include "dvb-usb-common.h" - -int dvb_usb_generic_rw(struct dvb_usb_device *d, u8 *wbuf, u16 wlen, u8 *rbuf, - u16 rlen, int delay_ms) -{ - int actlen,ret = -ENOMEM; - - if (!d || wbuf == NULL || wlen == 0) - return -EINVAL; - - if (d->props.generic_bulk_ctrl_endpoint == 0) { - err("endpoint for generic control not specified."); - return -EINVAL; - } - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - deb_xfer(">>> "); - debug_dump(wbuf,wlen,deb_xfer); - - ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev, - d->props.generic_bulk_ctrl_endpoint), wbuf,wlen,&actlen, - 2000); - - if (ret) - err("bulk message failed: %d (%d/%d)",ret,wlen,actlen); - else - ret = actlen != wlen ? -1 : 0; - - /* an answer is expected, and no error before */ - if (!ret && rbuf && rlen) { - if (delay_ms) - msleep(delay_ms); - - ret = usb_bulk_msg(d->udev,usb_rcvbulkpipe(d->udev, - d->props.generic_bulk_ctrl_endpoint),rbuf,rlen,&actlen, - 2000); - - if (ret) - err("recv bulk message failed: %d",ret); - else { - deb_xfer("<<< "); - debug_dump(rbuf,actlen,deb_xfer); - } - } - - mutex_unlock(&d->usb_mutex); - return ret; -} -EXPORT_SYMBOL(dvb_usb_generic_rw); - -int dvb_usb_generic_write(struct dvb_usb_device *d, u8 *buf, u16 len) -{ - return dvb_usb_generic_rw(d,buf,len,NULL,0,0); -} -EXPORT_SYMBOL(dvb_usb_generic_write); - -static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length) -{ - struct dvb_usb_adapter *adap = stream->user_priv; - if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) - dvb_dmx_swfilter(&adap->demux, buffer, length); -} - -static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer, size_t length) -{ - struct dvb_usb_adapter *adap = stream->user_priv; - if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) - dvb_dmx_swfilter_204(&adap->demux, buffer, length); -} - -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 dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap) -{ - return usb_urb_exit(&adap->stream); -} diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h deleted file mode 100644 index b1de0f7e26e..00000000000 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ /dev/null @@ -1,400 +0,0 @@ -/* dvb-usb.h is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * the headerfile, all dvb-usb-drivers have to include. - * - * TODO: clean-up the structures for unused fields and update the comments - */ -#ifndef __DVB_USB_H__ -#define __DVB_USB_H__ - -#include <linux/input.h> -#include <linux/usb.h> -#include <linux/firmware.h> -#include <linux/mutex.h> - -#include "dvb_frontend.h" -#include "dvb_demux.h" -#include "dvb_net.h" -#include "dmxdev.h" - -#include "dvb-pll.h" - -#include "dvb-usb-ids.h" - -/* debug */ -#ifdef CONFIG_DVB_USB_DEBUG -#define dprintk(var,level,args...) \ - do { if ((var & level)) { printk(args); } } while (0) - -#define debug_dump(b,l,func) {\ - int loop_; \ - for (loop_ = 0; loop_ < l; loop_++) func("%02x ", b[loop_]); \ - func("\n");\ -} -#define DVB_USB_DEBUG_STATUS -#else -#define dprintk(args...) -#define debug_dump(b,l,func) - -#define DVB_USB_DEBUG_STATUS " (debugging is not enabled)" - -#endif - -/* generic log methods - taken from usb.h */ -#ifndef DVB_USB_LOG_PREFIX - #define DVB_USB_LOG_PREFIX "dvb-usb (please define a log prefix)" -#endif - -#undef err -#define err(format, arg...) printk(KERN_ERR DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) -#undef info -#define info(format, arg...) printk(KERN_INFO DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) -#undef warn -#define warn(format, arg...) printk(KERN_WARNING DVB_USB_LOG_PREFIX ": " format "\n" , ## arg) - -/** - * struct dvb_usb_device_description - name and its according USB IDs - * @name: real name of the box, regardless which DVB USB device class is in use - * @cold_ids: array of struct usb_device_id which describe the device in - * pre-firmware state - * @warm_ids: array of struct usb_device_id which describe the device in - * post-firmware state - * - * Each DVB USB device class can have one or more actual devices, this struct - * assigns a name to it. - */ -struct dvb_usb_device_description { - const char *name; - -#define DVB_USB_ID_MAX_NUM 15 - struct usb_device_id *cold_ids[DVB_USB_ID_MAX_NUM]; - struct usb_device_id *warm_ids[DVB_USB_ID_MAX_NUM]; -}; - -/** - * struct dvb_usb_rc_key - a remote control key and its input-event - * @custom: the vendor/custom part of the key - * @data: the actual key part - * @event: the input event assigned to key identified by custom and data - */ -struct dvb_usb_rc_key { - u8 custom,data; - u32 event; -}; - -struct dvb_usb_device; -struct dvb_usb_adapter; -struct usb_data_stream; - -/** - * Properties of USB streaming - TODO this structure should be somewhere else - * describes the kind of USB transfer used for data-streaming. - * (BULK or ISOC) - */ -struct usb_data_stream_properties { -#define USB_BULK 1 -#define USB_ISOC 2 - int type; - int count; - int endpoint; - - union { - struct { - int buffersize; /* per URB */ - } bulk; - struct { - int framesperurb; - int framesize; - int interval; - } isoc; - } u; -}; - -/** - * struct dvb_usb_adapter_properties - properties of a dvb-usb-adapter. - * A DVB-USB-Adapter is basically a dvb_adapter which is present on a USB-device. - * @caps: capabilities of the DVB USB device. - * @pid_filter_count: number of PID filter position in the optional hardware - * PID-filter. - * @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. - * @pid_filter: called to set/unset a PID for filtering. - * @frontend_attach: called to attach the possible frontends (fill fe-field - * of struct dvb_usb_device). - * @tuner_attach: called to attach the correct tuner and to fill pll_addr, - * pll_desc and pll_init_buf of struct dvb_usb_device). - * @stream: configuration of the USB streaming - */ -struct dvb_usb_adapter_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 -#define DVB_USB_ADAP_RECEIVES_204_BYTE_TS 0x08 - int caps; - int pid_filter_count; - - int (*streaming_ctrl) (struct dvb_usb_adapter *, int); - int (*pid_filter_ctrl) (struct dvb_usb_adapter *, int); - int (*pid_filter) (struct dvb_usb_adapter *, int, u16, int); - - int (*frontend_attach) (struct dvb_usb_adapter *); - int (*tuner_attach) (struct dvb_usb_adapter *); - - struct usb_data_stream_properties stream; - - int size_of_priv; -}; - -/** - * struct dvb_usb_device_properties - properties of a dvb-usb-device - * @usb_ctrl: which USB device-side controller is in use. Needed for firmware - * download. - * @firmware: name of the firmware file. - * @download_firmware: called to download the firmware when the usb_ctrl is - * DEVICE_SPECIFIC. - * @no_reconnect: device doesn't do a reconnect after downloading the firmware, - * so do the warm initialization right after it - * - * @size_of_priv: how many bytes shall be allocated for the private field - * of struct dvb_usb_device. - * - * @power_ctrl: called to enable/disable power of the device. - * @read_mac_address: called to read the MAC address of the device. - * @identify_state: called to determine the state (cold or warm), when it - * is not distinguishable by the USB IDs. - * - * @rc_key_map: a hard-wired array of struct dvb_usb_rc_key (NULL to disable - * remote control handling). - * @rc_key_map_size: number of items in @rc_key_map. - * @rc_query: called to query an event event. - * @rc_interval: time in ms between two queries. - * - * @i2c_algo: i2c_algorithm if the device has I2CoverUSB. - * - * @generic_bulk_ctrl_endpoint: most of the DVB USB devices have a generic - * endpoint which received control messages with bulk transfers. When this - * is non-zero, one can use dvb_usb_generic_rw and dvb_usb_generic_write- - * helper functions. - * - * @num_device_descs: number of struct dvb_usb_device_description in @devices - * @devices: array of struct dvb_usb_device_description compatibles with these - * properties. - */ -#define MAX_NO_OF_ADAPTER_PER_DEVICE 2 -struct dvb_usb_device_properties { - -#define DVB_USB_IS_AN_I2C_ADAPTER 0x01 - int caps; - -#define DEVICE_SPECIFIC 0 -#define CYPRESS_AN2135 1 -#define CYPRESS_AN2235 2 -#define CYPRESS_FX2 3 - int usb_ctrl; - int (*download_firmware) (struct usb_device *, const struct firmware *); - const char firmware[FIRMWARE_NAME_MAX]; - int no_reconnect; - - int size_of_priv; - - int num_adapters; - struct dvb_usb_adapter_properties adapter[MAX_NO_OF_ADAPTER_PER_DEVICE]; - - int (*power_ctrl) (struct dvb_usb_device *, int); - int (*read_mac_address) (struct dvb_usb_device *, u8 []); - int (*identify_state) (struct usb_device *, struct dvb_usb_device_properties *, - struct dvb_usb_device_description **, int *); - -/* remote control properties */ -#define REMOTE_NO_KEY_PRESSED 0x00 -#define REMOTE_KEY_PRESSED 0x01 -#define REMOTE_KEY_REPEAT 0x02 - struct dvb_usb_rc_key *rc_key_map; - int rc_key_map_size; - int (*rc_query) (struct dvb_usb_device *, u32 *, int *); - int rc_interval; - - struct i2c_algorithm *i2c_algo; - - int generic_bulk_ctrl_endpoint; - - int num_device_descs; - struct dvb_usb_device_description devices[9]; -}; - -/** - * struct usb_data_stream - generic object of an USB stream - * @buf_num: number of buffer allocated. - * @buf_size: size of each buffer in buf_list. - * @buf_list: array containing all allocate buffers for streaming. - * @dma_addr: list of dma_addr_t for each buffer in buf_list. - * - * @urbs_initialized: number of URBs initialized. - * @urbs_submitted: number of URBs submitted. - */ -#define MAX_NO_URBS_FOR_DATA_STREAM 10 -struct usb_data_stream { - struct usb_device *udev; - struct usb_data_stream_properties props; - -#define USB_STATE_INIT 0x00 -#define USB_STATE_URB_BUF 0x01 - int state; - - void (*complete) (struct usb_data_stream *, u8 *, size_t); - - struct urb *urb_list[MAX_NO_URBS_FOR_DATA_STREAM]; - int buf_num; - unsigned long buf_size; - u8 *buf_list[MAX_NO_URBS_FOR_DATA_STREAM]; - dma_addr_t dma_addr[MAX_NO_URBS_FOR_DATA_STREAM]; - - int urbs_initialized; - int urbs_submitted; - - void *user_priv; -}; - -/** - * struct dvb_usb_adapter - a DVB adapter on a USB device - * @id: index of this adapter (starting with 0). - * - * @feedcount: number of reqested feeds (used for streaming-activation) - * @pid_filtering: is hardware pid_filtering used or not. - * - * @pll_addr: I2C address of the tuner for programming - * @pll_init: array containing the initialization buffer - * @pll_desc: pointer to the appropriate struct dvb_pll_desc - * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board - * - * @dvb_adap: device's dvb_adapter. - * @dmxdev: device's dmxdev. - * @demux: device's software demuxer. - * @dvb_net: device's dvb_net interfaces. - * @dvb_frontend: device's frontend. - * @max_feed_count: how many feeds can be handled simultaneously by this - * device - * - * @fe_init: rerouted frontend-init (wakeup) function. - * @fe_sleep: rerouted frontend-sleep function. - * - * @stream: the usb data stream. - */ -struct dvb_usb_adapter { - struct dvb_usb_device *dev; - struct dvb_usb_adapter_properties props; - -#define DVB_USB_ADAP_STATE_INIT 0x000 -#define DVB_USB_ADAP_STATE_DVB 0x001 - int state; - - 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; - - void *priv; -}; - -/** - * struct dvb_usb_device - object of a DVB USB device - * @props: copy of the struct dvb_usb_properties this device belongs to. - * @desc: pointer to the device's struct dvb_usb_device_description. - * @state: initialization and runtime state of the device. - * - * @powered: indicated whether the device is power or not. - * Powered is in/decremented for each call to modify the state. - * @udev: pointer to the device's struct usb_device. - * - * @usb_mutex: semaphore of USB control messages (reading needs two messages) - * @i2c_mutex: semaphore for i2c-transfers - * - * @i2c_adap: device's i2c_adapter if it uses I2CoverUSB - * - * @rc_input_dev: input device for the remote control. - * @rc_query_work: struct work_struct frequent rc queries - * @last_event: last triggered event - * @last_state: last state (no, pressed, repeat) - * @owner: owner of the dvb_adapter - * @priv: private data of the actual driver (allocate by dvb-usb, size defined - * in size_of_priv of dvb_usb_properties). - */ -struct dvb_usb_device { - struct dvb_usb_device_properties props; - struct dvb_usb_device_description *desc; - - struct usb_device *udev; - -#define DVB_USB_STATE_INIT 0x000 -#define DVB_USB_STATE_I2C 0x001 -#define DVB_USB_STATE_DVB 0x002 -#define DVB_USB_STATE_REMOTE 0x004 - int state; - - int powered; - - /* locking */ - struct mutex usb_mutex; - - /* i2c */ - struct mutex i2c_mutex; - struct i2c_adapter i2c_adap; - - int num_adapters_initialized; - struct dvb_usb_adapter adapter[MAX_NO_OF_ADAPTER_PER_DEVICE]; - - /* remote control */ - struct input_dev *rc_input_dev; - char rc_phys[64]; - struct delayed_work rc_query_work; - u32 last_event; - int last_state; - - struct module *owner; - - void *priv; -}; - -extern int dvb_usb_device_init(struct usb_interface *, - struct dvb_usb_device_properties *, - struct module *, struct dvb_usb_device **, - short *adapter_nums); -extern void dvb_usb_device_exit(struct usb_interface *); - -/* the generic read/write method for device control */ -extern int dvb_usb_generic_rw(struct dvb_usb_device *, u8 *, u16, u8 *, u16,int); -extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16); - -/* commonly used remote control parsing */ -extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *); - -/* commonly used firmware download types and function */ -struct hexline { - u8 len; - u32 addr; - u8 type; - u8 data[255]; - u8 chk; -}; -extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); -extern int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos); - - -#endif diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c deleted file mode 100644 index c65f273ff31..00000000000 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ /dev/null @@ -1,838 +0,0 @@ -/* DVB USB framework compliant Linux driver for the -* DVBWorld DVB-S 2101, 2102, DVB-S2 2104 Card -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ -#include "dw2102.h" -#include "si21xx.h" -#include "stv0299.h" -#include "z0194a.h" -#include "stv0288.h" -#include "stb6000.h" -#include "eds1547.h" -#include "cx24116.h" - -#ifndef USB_PID_DW2102 -#define USB_PID_DW2102 0x2102 -#endif - -#ifndef USB_PID_DW2104 -#define USB_PID_DW2104 0x2104 -#endif - -#ifndef USB_PID_CINERGY_S -#define USB_PID_CINERGY_S 0x0064 -#endif - -#define DW210X_READ_MSG 0 -#define DW210X_WRITE_MSG 1 - -#define REG_1F_SYMBOLRATE_BYTE0 0x1f -#define REG_20_SYMBOLRATE_BYTE1 0x20 -#define REG_21_SYMBOLRATE_BYTE2 0x21 -/* on my own*/ -#define DW2102_VOLTAGE_CTRL (0x1800) -#define DW2102_RC_QUERY (0x1a00) - -struct dw210x_state { - u32 last_key_pressed; -}; -struct dw210x_rc_keys { - u32 keycode; - u32 event; -}; - -/* debug */ -static int dvb_usb_dw2102_debug; -module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int dw210x_op_rw(struct usb_device *dev, u8 request, u16 value, - u16 index, u8 * data, u16 len, int flags) -{ - int ret; - u8 u8buf[len]; - - unsigned int pipe = (flags == DW210X_READ_MSG) ? - usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0); - u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; - - if (flags == DW210X_WRITE_MSG) - memcpy(u8buf, data, len); - ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, - value, index , u8buf, len, 2000); - - if (flags == DW210X_READ_MSG) - memcpy(data, u8buf, len); - return ret; -} - -/* I2C */ -static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ -struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i = 0, ret = 0; - u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0}; - u16 value; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: - /* read stv0299 register */ - value = msg[0].buf[0];/* register */ - for (i = 0; i < msg[1].len; i++) { - value = value + i; - ret = dw210x_op_rw(d->udev, 0xb5, value, 0, - buf6, 2, DW210X_READ_MSG); - msg[1].buf[i] = buf6[0]; - } - break; - case 1: - switch (msg[0].addr) { - case 0x68: - /* write to stv0299 register */ - buf6[0] = 0x2a; - buf6[1] = msg[0].buf[0]; - buf6[2] = msg[0].buf[1]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 3, DW210X_WRITE_MSG); - break; - case 0x60: - if (msg[0].flags == 0) { - /* write to tuner pll */ - buf6[0] = 0x2c; - buf6[1] = 5; - buf6[2] = 0xc0; - buf6[3] = msg[0].buf[0]; - buf6[4] = msg[0].buf[1]; - buf6[5] = msg[0].buf[2]; - buf6[6] = msg[0].buf[3]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 7, DW210X_WRITE_MSG); - } else { - /* read from tuner */ - ret = dw210x_op_rw(d->udev, 0xb5, 0, 0, - buf6, 1, DW210X_READ_MSG); - msg[0].buf[0] = buf6[0]; - } - break; - case (DW2102_RC_QUERY): - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); - msg[0].buf[0] = buf6[0]; - msg[0].buf[1] = buf6[1]; - break; - case (DW2102_VOLTAGE_CTRL): - buf6[0] = 0x30; - buf6[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 2, DW210X_WRITE_MSG); - break; - } - - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} - -static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap, - struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0; - u8 buf6[] = {0, 0, 0, 0, 0, 0, 0}; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: - /* read si2109 register by number */ - buf6[0] = 0xd0; - buf6[1] = msg[0].len; - buf6[2] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - buf6, msg[0].len + 2, DW210X_WRITE_MSG); - /* read si2109 register */ - ret = dw210x_op_rw(d->udev, 0xc3, 0xd0, 0, - buf6, msg[1].len + 2, DW210X_READ_MSG); - memcpy(msg[1].buf, buf6 + 2, msg[1].len); - - break; - case 1: - switch (msg[0].addr) { - case 0x68: - /* write to si2109 register */ - buf6[0] = 0xd0; - buf6[1] = msg[0].len; - memcpy(buf6 + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, buf6, - msg[0].len + 2, DW210X_WRITE_MSG); - break; - case(DW2102_RC_QUERY): - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - buf6, 2, DW210X_READ_MSG); - msg[0].buf[0] = buf6[0]; - msg[0].buf[1] = buf6[1]; - break; - case(DW2102_VOLTAGE_CTRL): - buf6[0] = 0x30; - buf6[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - buf6, 2, DW210X_WRITE_MSG); - break; - } - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} -static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: { - /* read */ - /* first write first register number */ - u8 ibuf [msg[1].len + 2], obuf[3]; - obuf[0] = 0xd0; - obuf[1] = msg[0].len; - obuf[2] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - /* second read registers */ - ret = dw210x_op_rw(d->udev, 0xc3, 0xd1 , 0, - ibuf, msg[1].len + 2, DW210X_READ_MSG); - memcpy(msg[1].buf, ibuf + 2, msg[1].len); - - break; - } - case 1: - switch (msg[0].addr) { - case 0x68: { - /* write to register */ - u8 obuf[msg[0].len + 2]; - obuf[0] = 0xd0; - obuf[1] = msg[0].len; - memcpy(obuf + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - break; - } - case 0x61: { - /* write to tuner */ - u8 obuf[msg[0].len + 2]; - obuf[0] = 0xc2; - obuf[1] = msg[0].len; - memcpy(obuf + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - break; - } - case(DW2102_RC_QUERY): { - u8 ibuf[2]; - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[0].buf, ibuf , 2); - break; - } - case(DW2102_VOLTAGE_CTRL): { - u8 obuf[2]; - obuf[0] = 0x30; - obuf[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - obuf, 2, DW210X_WRITE_MSG); - break; - } - } - - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} - -static int dw2104_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int ret = 0; - int len, i; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - switch (num) { - case 2: { - /* read */ - /* first write first register number */ - u8 ibuf [msg[1].len + 2], obuf[3]; - obuf[0] = 0xaa; - obuf[1] = msg[0].len; - obuf[2] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - /* second read registers */ - ret = dw210x_op_rw(d->udev, 0xc3, 0xab , 0, - ibuf, msg[1].len + 2, DW210X_READ_MSG); - memcpy(msg[1].buf, ibuf + 2, msg[1].len); - - break; - } - case 1: - switch (msg[0].addr) { - case 0x55: { - if (msg[0].buf[0] == 0xf7) { - /* firmware */ - /* Write in small blocks */ - u8 obuf[19]; - obuf[0] = 0xaa; - obuf[1] = 0x11; - obuf[2] = 0xf7; - len = msg[0].len - 1; - i = 1; - do { - memcpy(obuf + 3, msg[0].buf + i, (len > 16 ? 16 : len)); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, (len > 16 ? 16 : len) + 3, DW210X_WRITE_MSG); - i += 16; - len -= 16; - } while (len > 0); - } else { - /* write to register */ - u8 obuf[msg[0].len + 2]; - obuf[0] = 0xaa; - obuf[1] = msg[0].len; - memcpy(obuf + 2, msg[0].buf, msg[0].len); - ret = dw210x_op_rw(d->udev, 0xc2, 0, 0, - obuf, msg[0].len + 2, DW210X_WRITE_MSG); - } - break; - } - case(DW2102_RC_QUERY): { - u8 ibuf[2]; - ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, - ibuf, 2, DW210X_READ_MSG); - memcpy(msg[0].buf, ibuf , 2); - break; - } - case(DW2102_VOLTAGE_CTRL): { - u8 obuf[2]; - obuf[0] = 0x30; - obuf[1] = msg[0].buf[0]; - ret = dw210x_op_rw(d->udev, 0xb2, 0, 0, - obuf, 2, DW210X_WRITE_MSG); - break; - } - } - - break; - } - - mutex_unlock(&d->i2c_mutex); - return num; -} - -static u32 dw210x_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm dw2102_i2c_algo = { - .master_xfer = dw2102_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static struct i2c_algorithm dw2102_serit_i2c_algo = { - .master_xfer = dw2102_serit_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static struct i2c_algorithm dw2102_earda_i2c_algo = { - .master_xfer = dw2102_earda_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static struct i2c_algorithm dw2104_i2c_algo = { - .master_xfer = dw2104_i2c_transfer, - .functionality = dw210x_i2c_func, -}; - -static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -{ - int i; - u8 ibuf[] = {0, 0}; - u8 eeprom[256], eepromline[16]; - - for (i = 0; i < 256; i++) { - if (dw210x_op_rw(d->udev, 0xb6, 0xa0 , i, ibuf, 2, DW210X_READ_MSG) < 0) { - err("read eeprom failed."); - return -1; - } else { - eepromline[i%16] = ibuf[0]; - eeprom[i] = ibuf[0]; - } - if ((i % 16) == 15) { - deb_xfer("%02x: ", i - 15); - debug_dump(eepromline, 16, deb_xfer); - } - } - memcpy(mac, eeprom + 8, 6); - return 0; -}; - -static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - static u8 command_13v[1] = {0x00}; - static u8 command_18v[1] = {0x01}; - struct i2c_msg msg[] = { - {.addr = DW2102_VOLTAGE_CTRL, .flags = 0, - .buf = command_13v, .len = 1}, - }; - - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); - if (voltage == SEC_VOLTAGE_18) - msg[0].buf = command_18v; - i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); - return 0; -} - -static struct stv0299_config sharp_z0194a_config = { - .demod_address = 0x68, - .inittab = sharp_z0194a_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = sharp_z0194a_set_symbol_rate, -}; - -static struct cx24116_config dw2104_config = { - .demod_address = 0x55, - .mpg_clk_pos_pol = 0x01, -}; - -static struct si21xx_config serit_sp1511lhb_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - -}; - -static int dw2104_frontend_attach(struct dvb_usb_adapter *d) -{ - if ((d->fe = dvb_attach(cx24116_attach, &dw2104_config, - &d->dev->i2c_adap)) != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached cx24116!\n"); - return 0; - } - return -EIO; -} - -static struct dvb_usb_device_properties dw2102_properties; - -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->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached si21xx!\n"); - return 0; - } - } - if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { - /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ - d->fe = dvb_attach(stv0288_attach, &earda_config, - &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached stv0288!\n"); - return 0; - } - } - - 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->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; - info("Attached stv0299!\n"); - return 0; - } - } - return -EIO; -} - -static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(dvb_pll_attach, adap->fe, 0x60, - &adap->dev->i2c_adap, DVB_PLL_OPERA1); - return 0; -} - -static int dw2102_earda_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach(stb6000_attach, adap->fe, 0x61, - &adap->dev->i2c_adap); - - return 0; -} - -static struct dvb_usb_rc_key dw210x_rc_keys[] = { - { 0xf8, 0x0a, KEY_Q }, /*power*/ - { 0xf8, 0x0c, KEY_M }, /*mute*/ - { 0xf8, 0x11, KEY_1 }, - { 0xf8, 0x12, KEY_2 }, - { 0xf8, 0x13, KEY_3 }, - { 0xf8, 0x14, KEY_4 }, - { 0xf8, 0x15, KEY_5 }, - { 0xf8, 0x16, KEY_6 }, - { 0xf8, 0x17, KEY_7 }, - { 0xf8, 0x18, KEY_8 }, - { 0xf8, 0x19, KEY_9 }, - { 0xf8, 0x10, KEY_0 }, - { 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/ - { 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/ - { 0xf8, 0x1a, KEY_O }, /*vol+*/ - { 0xf8, 0x0e, KEY_Z }, /*vol-*/ - { 0xf8, 0x04, KEY_R }, /*rec*/ - { 0xf8, 0x09, KEY_D }, /*fav*/ - { 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/ - { 0xf8, 0x07, KEY_A }, /*fast*/ - { 0xf8, 0x0b, KEY_P }, /*pause*/ - { 0xf8, 0x02, KEY_ESC }, /*cancel*/ - { 0xf8, 0x03, KEY_G }, /*tab*/ - { 0xf8, 0x00, KEY_UP }, /*up*/ - { 0xf8, 0x1f, KEY_ENTER }, /*ok*/ - { 0xf8, 0x01, KEY_DOWN }, /*down*/ - { 0xf8, 0x05, KEY_C }, /*cap*/ - { 0xf8, 0x06, KEY_S }, /*stop*/ - { 0xf8, 0x40, KEY_F }, /*full*/ - { 0xf8, 0x1e, KEY_W }, /*tvmode*/ - { 0xf8, 0x1b, KEY_B }, /*recall*/ - -}; - - - -static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct dw210x_state *st = d->priv; - u8 key[2]; - struct i2c_msg msg[] = { - {.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key, - .len = 2}, - }; - int i; - - *state = REMOTE_NO_KEY_PRESSED; - if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) { - for (i = 0; i < ARRAY_SIZE(dw210x_rc_keys); i++) { - if (dw210x_rc_keys[i].data == msg[0].buf[0]) { - *state = REMOTE_KEY_PRESSED; - *event = dw210x_rc_keys[i].event; - st->last_key_pressed = - dw210x_rc_keys[i].event; - break; - } - st->last_key_pressed = 0; - } - } - /* info("key: %x %x\n",key[0],key[1]); */ - return 0; -} - -static struct usb_device_id dw2102_table[] = { - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)}, - {USB_DEVICE(USB_VID_CYPRESS, 0x2101)}, - {USB_DEVICE(USB_VID_CYPRESS, 0x2104)}, - {USB_DEVICE(0x9022, 0xd650)}, - {USB_DEVICE(USB_VID_TERRATEC, USB_PID_CINERGY_S)}, - { } -}; - -MODULE_DEVICE_TABLE(usb, dw2102_table); - -static int dw2102_load_firmware(struct usb_device *dev, - const struct firmware *frmwr) -{ - u8 *b, *p; - int ret = 0, i; - u8 reset; - u8 reset16[] = {0, 0, 0, 0, 0, 0, 0}; - const struct firmware *fw; - const char *filename = "dvb-usb-dw2101.fw"; - switch (dev->descriptor.idProduct) { - case 0x2101: - ret = request_firmware(&fw, filename, &dev->dev); - if (ret != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details " - "on firmware-problems.", filename); - return ret; - } - break; - default: - fw = frmwr; - break; - } - info("start downloading DW210X firmware"); - p = kmalloc(fw->size, GFP_KERNEL); - reset = 1; - /*stop the CPU*/ - dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, DW210X_WRITE_MSG); - - if (p != NULL) { - memcpy(p, fw->data, fw->size); - for (i = 0; i < fw->size; i += 0x40) { - b = (u8 *) p + i; - if (dw210x_op_rw(dev, 0xa0, i, 0, b , 0x40, - DW210X_WRITE_MSG) != 0x40) { - err("error while transferring firmware"); - ret = -EINVAL; - break; - } - } - /* restart the CPU */ - reset = 0; - if (ret || dw210x_op_rw(dev, 0xa0, 0x7f92, 0, &reset, 1, - DW210X_WRITE_MSG) != 1) { - err("could not restart the USB controller CPU."); - ret = -EINVAL; - } - if (ret || dw210x_op_rw(dev, 0xa0, 0xe600, 0, &reset, 1, - DW210X_WRITE_MSG) != 1) { - err("could not restart the USB controller CPU."); - ret = -EINVAL; - } - /* init registers */ - switch (dev->descriptor.idProduct) { - case USB_PID_DW2104: - case 0xd650: - reset = 1; - dw210x_op_rw(dev, 0xc4, 0x0000, 0, &reset, 1, - DW210X_WRITE_MSG); - reset = 0; - dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, - DW210X_WRITE_MSG); - break; - case USB_PID_CINERGY_S: - case USB_PID_DW2102: - dw210x_op_rw(dev, 0xbf, 0x0040, 0, &reset, 0, - DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, - DW210X_READ_MSG); - /* check STV0299 frontend */ - dw210x_op_rw(dev, 0xb5, 0, 0, &reset16[0], 2, - 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; - break; - } else { - /* check STV0288 frontend */ - reset16[0] = 0xd0; - reset16[1] = 1; - reset16[2] = 0; - dw210x_op_rw(dev, 0xc2, 0, 0, &reset16[0], 3, - DW210X_WRITE_MSG); - dw210x_op_rw(dev, 0xc3, 0xd1, 0, &reset16[0], 3, - DW210X_READ_MSG); - if (reset16[2] == 0x11) { - dw2102_properties.i2c_algo = &dw2102_earda_i2c_algo; - dw2102_properties.adapter->tuner_attach = &dw2102_earda_tuner_attach; - break; - } - } - case 0x2101: - dw210x_op_rw(dev, 0xbc, 0x0030, 0, &reset16[0], 2, - DW210X_READ_MSG); - dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, - DW210X_READ_MSG); - dw210x_op_rw(dev, 0xba, 0x0000, 0, &reset16[0], 7, - DW210X_READ_MSG); - dw210x_op_rw(dev, 0xb9, 0x0000, 0, &reset16[0], 2, - DW210X_READ_MSG); - break; - } - msleep(100); - kfree(p); - } - return ret; -} - -static struct dvb_usb_device_properties dw2102_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-dw2102.fw", - .size_of_priv = sizeof(struct dw210x_state), - .no_reconnect = 1, - - .i2c_algo = &dw2102_serit_i2c_algo, - .rc_key_map = dw210x_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), - .rc_interval = 150, - .rc_query = dw2102_rc_query, - - .generic_bulk_ctrl_endpoint = 0x81, - /* parameter for the MPEG2-data transfer */ - .num_adapters = 1, - .download_firmware = dw2102_load_firmware, - .read_mac_address = dw210x_read_mac_address, - .adapter = { - { - .frontend_attach = dw2102_frontend_attach, - .streaming_ctrl = NULL, - .tuner_attach = NULL, - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .num_device_descs = 3, - .devices = { - {"DVBWorld DVB-S 2102 USB2.0", - {&dw2102_table[0], NULL}, - {NULL}, - }, - {"DVBWorld DVB-S 2101 USB2.0", - {&dw2102_table[1], NULL}, - {NULL}, - }, - {"TerraTec Cinergy S USB", - {&dw2102_table[4], NULL}, - {NULL}, - }, - } -}; - -static struct dvb_usb_device_properties dw2104_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-dw2104.fw", - .size_of_priv = sizeof(struct dw210x_state), - .no_reconnect = 1, - - .i2c_algo = &dw2104_i2c_algo, - .rc_key_map = dw210x_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dw210x_rc_keys), - .rc_interval = 150, - .rc_query = dw2102_rc_query, - - .generic_bulk_ctrl_endpoint = 0x81, - /* parameter for the MPEG2-data transfer */ - .num_adapters = 1, - .download_firmware = dw2102_load_firmware, - .read_mac_address = dw210x_read_mac_address, - .adapter = { - { - .frontend_attach = dw2104_frontend_attach, - .streaming_ctrl = NULL, - /*.tuner_attach = dw2104_tuner_attach,*/ - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .num_device_descs = 2, - .devices = { - { "DVBWorld DW2104 USB2.0", - {&dw2102_table[2], NULL}, - {NULL}, - }, - { "TeVii S650 USB2.0", - {&dw2102_table[3], NULL}, - {NULL}, - }, - } -}; - -static int dw2102_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - if (0 == dvb_usb_device_init(intf, &dw2102_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &dw2104_properties, - THIS_MODULE, NULL, adapter_nr)) { - return 0; - } - return -ENODEV; -} - -static struct usb_driver dw2102_driver = { - .name = "dw2102", - .probe = dw2102_probe, - .disconnect = dvb_usb_device_exit, - .id_table = dw2102_table, -}; - -static int __init dw2102_module_init(void) -{ - int ret = usb_register(&dw2102_driver); - if (ret) - err("usb_register failed. Error number %d", ret); - - return ret; -} - -static void __exit dw2102_module_exit(void) -{ - usb_deregister(&dw2102_driver); -} - -module_init(dw2102_module_init); -module_exit(dw2102_module_exit); - -MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); -MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104 USB2.0 device"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/dw2102.h b/drivers/media/dvb/dvb-usb/dw2102.h deleted file mode 100644 index e3370734e95..00000000000 --- a/drivers/media/dvb/dvb-usb/dw2102.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _DW2102_H_ -#define _DW2102_H_ - -#define DVB_USB_LOG_PREFIX "dw2102" -#include "dvb-usb.h" - -#define deb_xfer(args...) dprintk(dvb_usb_dw2102_debug, 0x02, args) -#endif diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c deleted file mode 100644 index 6f596ed4176..00000000000 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ /dev/null @@ -1,233 +0,0 @@ -/* DVB USB compliant linux driver for GL861 USB2.0 devices. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "gl861.h" - -#include "zl10353.h" -#include "qt1010.h" - -/* debug */ -static int dvb_usb_gl861_debug; -module_param_named(debug, dvb_usb_gl861_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." - DVB_USB_DEBUG_STATUS); -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr, - u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen) -{ - u16 index; - u16 value = addr << (8 + 1); - int wo = (rbuf == NULL || rlen == 0); /* write-only */ - u8 req, type; - - if (wo) { - req = GL861_REQ_I2C_WRITE; - type = GL861_WRITE; - } else { /* rw */ - req = GL861_REQ_I2C_READ; - type = GL861_READ; - } - - switch (wlen) { - case 1: - index = wbuf[0]; - break; - case 2: - index = wbuf[0]; - value = value + wbuf[1]; - break; - default: - warn("wlen = %x, aborting.", wlen); - return -EINVAL; - } - - msleep(1); /* avoid I2C errors */ - - return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type, - value, index, rbuf, rlen, 2000); -} - -/* I2C */ -static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i; - - if (num > 2) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - /* write/read request */ - if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) { - if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, msg[i+1].buf, msg[i+1].len) < 0) - break; - i++; - } else - if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf, - msg[i].len, NULL, 0) < 0) - break; - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static u32 gl861_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm gl861_i2c_algo = { - .master_xfer = gl861_i2c_xfer, - .functionality = gl861_i2c_func, -}; - -/* Callbacks for DVB USB */ -static struct zl10353_config gl861_zl10353_config = { - .demod_address = 0x0f, - .no_tuner = 1, - .parallel_ts = 1, -}; - -static int gl861_frontend_attach(struct dvb_usb_adapter *adap) -{ - - adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, - &adap->dev->i2c_adap); - if (adap->fe == NULL) - return -EIO; - - return 0; -} - -static struct qt1010_config gl861_qt1010_config = { - .i2c_address = 0x62 -}; - -static int gl861_tuner_attach(struct dvb_usb_adapter *adap) -{ - return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, - &gl861_qt1010_config) == NULL ? -ENODEV : 0; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties gl861_properties; - -static int gl861_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct dvb_usb_device *d; - struct usb_host_interface *alt; - int ret; - - if (intf->num_altsetting < 2) - return -ENODEV; - - ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d, - adapter_nr); - if (ret == 0) { - alt = usb_altnum_to_altsetting(intf, 0); - - if (alt == NULL) { - deb_rc("not alt found!\n"); - return -ENODEV; - } - - ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); - } - - return ret; -} - -static struct usb_device_id gl861_table [] = { - { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) }, - { USB_DEVICE(USB_VID_ALINK, USB_VID_ALINK_DTU) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, gl861_table); - -static struct dvb_usb_device_properties gl861_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = DEVICE_SPECIFIC, - - .size_of_priv = 0, - - .num_adapters = 1, - .adapter = {{ - - .frontend_attach = gl861_frontend_attach, - .tuner_attach = gl861_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - } }, - .i2c_algo = &gl861_i2c_algo, - - .num_device_descs = 2, - .devices = { - { - .name = "MSI Mega Sky 55801 DVB-T USB2.0", - .cold_ids = { NULL }, - .warm_ids = { &gl861_table[0], NULL }, - }, - { - .name = "A-LINK DTU DVB-T USB2.0", - .cold_ids = { NULL }, - .warm_ids = { &gl861_table[1], NULL }, - }, - } -}; - -static struct usb_driver gl861_driver = { - .name = "dvb_usb_gl861", - .probe = gl861_probe, - .disconnect = dvb_usb_device_exit, - .id_table = gl861_table, -}; - -/* module stuff */ -static int __init gl861_module_init(void) -{ - int ret; - - ret = usb_register(&gl861_driver); - if (ret) - err("usb_register failed. Error number %d", ret); - - return ret; -} - -static void __exit gl861_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&gl861_driver); -} - -module_init(gl861_module_init); -module_exit(gl861_module_exit); - -MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>"); -MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/gl861.h b/drivers/media/dvb/dvb-usb/gl861.h deleted file mode 100644 index c54855e2c23..00000000000 --- a/drivers/media/dvb/dvb-usb/gl861.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _DVB_USB_GL861_H_ -#define _DVB_USB_GL861_H_ - -#define DVB_USB_LOG_PREFIX "gl861" -#include "dvb-usb.h" - -#define deb_rc(args...) dprintk(dvb_usb_gl861_debug, 0x01, args) - -#define GL861_WRITE 0x40 -#define GL861_READ 0xc0 - -#define GL861_REQ_I2C_WRITE 0x01 -#define GL861_REQ_I2C_READ 0x02 - -#endif diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c deleted file mode 100644 index 20eadf9318e..00000000000 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ /dev/null @@ -1,378 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module - * - * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com) - * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com) - * - * Thanks to GENPIX for the sample code used to implement this module. - * - * This module is based off the vp7045 and vp702x modules - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "gp8psk.h" - -struct gp8psk_fe_state { - struct dvb_frontend fe; - struct dvb_usb_device *d; - u8 lock; - u16 snr; - unsigned long next_status_check; - unsigned long status_check_interval; -}; - -static int gp8psk_tuned_to_DCII(struct dvb_frontend *fe) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - u8 status; - gp8psk_usb_in_op(st->d, GET_8PSK_CONFIG, 0, 0, &status, 1); - return status & bmDCtuned; -} - -static int gp8psk_set_tuner_mode(struct dvb_frontend *fe, int mode) -{ - struct gp8psk_fe_state *state = fe->demodulator_priv; - return gp8psk_usb_out_op(state->d, SET_8PSK_CONFIG, mode, 0, NULL, 0); -} - -static int gp8psk_fe_update_status(struct gp8psk_fe_state *st) -{ - u8 buf[6]; - if (time_after(jiffies,st->next_status_check)) { - gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0,0,&st->lock,1); - gp8psk_usb_in_op(st->d, GET_SIGNAL_STRENGTH, 0,0,buf,6); - st->snr = (buf[1]) << 8 | buf[0]; - st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; - } - return 0; -} - -static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - gp8psk_fe_update_status(st); - - if (st->lock) - *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; - else - *status = 0; - - if (*status & FE_HAS_LOCK) - st->status_check_interval = 1000; - else - st->status_check_interval = 100; - return 0; -} - -/* not supported by this Frontend */ -static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - (void) fe; - *ber = 0; - return 0; -} - -/* not supported by this Frontend */ -static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - (void) fe; - *unc = 0; - return 0; -} - -static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - gp8psk_fe_update_status(st); - /* snr is reported in dBu*256 */ - *snr = st->snr; - return 0; -} - -static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - gp8psk_fe_update_status(st); - /* snr is reported in dBu*256 */ - /* snr / 38.4 ~= 100% strength */ - /* snr * 17 returns 100% strength as 65535 */ - if (st->snr > 0xf00) - *strength = 0xffff; - else - *strength = (st->snr << 4) + st->snr; /* snr*17 */ - return 0; -} - -static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 200; - return 0; -} - -static int gp8psk_fe_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - deb_fe("%s(..)\n", __func__); - return 0; -} - -static int gp8psk_fe_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - deb_fe("%s(..)\n", __func__); - return 0; -} - - -static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct gp8psk_fe_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - u8 cmd[10]; - u32 freq = fep->frequency * 1000; - int gp_product_id = le16_to_cpu(state->d->udev->descriptor.idProduct); - - deb_fe("%s()\n", __func__); - - cmd[4] = freq & 0xff; - cmd[5] = (freq >> 8) & 0xff; - cmd[6] = (freq >> 16) & 0xff; - cmd[7] = (freq >> 24) & 0xff; - - switch (c->delivery_system) { - case SYS_DVBS: - /* Only QPSK is supported for DVB-S */ - 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: - deb_fe("%s: DVB-S2 delivery system selected\n", __func__); - break; - - default: - deb_fe("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - cmd[0] = c->symbol_rate & 0xff; - cmd[1] = (c->symbol_rate >> 8) & 0xff; - cmd[2] = (c->symbol_rate >> 16) & 0xff; - cmd[3] = (c->symbol_rate >> 24) & 0xff; - switch (c->modulation) { - case QPSK: - if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) - if (gp8psk_tuned_to_DCII(fe)) - gp8psk_bcm4500_reload(state->d); - switch (c->fec_inner) { - case FEC_1_2: - cmd[9] = 0; break; - case FEC_2_3: - cmd[9] = 1; break; - case FEC_3_4: - cmd[9] = 2; break; - case FEC_5_6: - cmd[9] = 3; break; - case FEC_7_8: - cmd[9] = 4; break; - case FEC_AUTO: - cmd[9] = 5; break; - default: - cmd[9] = 5; break; - } - cmd[8] = ADV_MOD_DVB_QPSK; - break; - case PSK_8: /* PSK_8 is for compatibility with DN */ - cmd[8] = ADV_MOD_TURBO_8PSK; - switch (c->fec_inner) { - case FEC_2_3: - cmd[9] = 0; break; - case FEC_3_4: - cmd[9] = 1; break; - case FEC_3_5: - cmd[9] = 2; break; - case FEC_5_6: - cmd[9] = 3; break; - case FEC_8_9: - cmd[9] = 4; break; - default: - cmd[9] = 0; break; - } - break; - case QAM_16: /* QAM_16 is for compatibility with DN */ - cmd[8] = ADV_MOD_TURBO_16QAM; - cmd[9] = 0; - break; - default: /* Unknown modulation */ - deb_fe("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) - gp8psk_set_tuner_mode(fe, 0); - gp8psk_usb_out_op(state->d, TUNE_8PSK, 0, 0, cmd, 10); - - state->lock = 0; - state->next_status_check = jiffies; - state->status_check_interval = 200; - - return 0; -} - -static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - - deb_fe("%s\n",__func__); - - if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0, - m->msg, m->msg_len)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe, - fe_sec_mini_cmd_t burst) -{ - struct gp8psk_fe_state *st = fe->demodulator_priv; - u8 cmd; - - deb_fe("%s\n",__func__); - - /* These commands are certainly wrong */ - cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01; - - if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0, - &cmd, 0)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - - if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE, - (tone == SEC_TONE_ON), 0, NULL, 0)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - - if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, - voltage == SEC_VOLTAGE_18, 0, NULL, 0)) { - return -EINVAL; - } - return 0; -} - -static int gp8psk_fe_enable_high_lnb_voltage(struct dvb_frontend* fe, long onoff) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - return gp8psk_usb_out_op(state->d, USE_EXTRA_VOLT, onoff, 0,NULL,0); -} - -static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd) -{ - struct gp8psk_fe_state* state = fe->demodulator_priv; - u8 cmd = sw_cmd & 0x7f; - - if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0, - NULL, 0)) { - return -EINVAL; - } - if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80), - 0, NULL, 0)) { - return -EINVAL; - } - - return 0; -} - -static void gp8psk_fe_release(struct dvb_frontend* fe) -{ - struct gp8psk_fe_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops gp8psk_fe_ops; - -struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d) -{ - struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); - if (s == NULL) - goto error; - - s->d = d; - memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; - - goto success; -error: - return NULL; -success: - return &s->fe; -} - - -static struct dvb_frontend_ops gp8psk_fe_ops = { - .info = { - .name = "Genpix 8psk-to-USB2 DVB-S", - .type = FE_QPSK, - .frequency_min = 800000, - .frequency_max = 2250000, - .frequency_stepsize = 100, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - /* - * FE_CAN_QAM_16 is for compatibility - * (Myth incorrectly detects Turbo-QPSK as plain QAM-16) - */ - FE_CAN_QPSK | FE_CAN_QAM_16 - }, - - .release = gp8psk_fe_release, - - .init = NULL, - .sleep = NULL, - - .set_property = gp8psk_fe_set_property, - .get_property = gp8psk_fe_get_property, - .set_frontend = gp8psk_fe_set_frontend, - - .get_tune_settings = gp8psk_fe_get_tune_settings, - - .read_status = gp8psk_fe_read_status, - .read_ber = gp8psk_fe_read_ber, - .read_signal_strength = gp8psk_fe_read_signal_strength, - .read_snr = gp8psk_fe_read_snr, - .read_ucblocks = gp8psk_fe_read_unc_blocks, - - .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg, - .diseqc_send_burst = gp8psk_fe_send_diseqc_burst, - .set_tone = gp8psk_fe_set_tone, - .set_voltage = gp8psk_fe_set_voltage, - .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd, - .enable_high_lnb_voltage = gp8psk_fe_enable_high_lnb_voltage -}; diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c deleted file mode 100644 index 3dd6843864e..00000000000 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ /dev/null @@ -1,311 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module - * - * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com) - * Copyright (C) 2006,2007 Genpix Electronics (genpix@genpix-electronics.com) - * - * Thanks to GENPIX for the sample code used to implement this module. - * - * This module is based off the vp7045 and vp702x modules - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "gp8psk.h" - -/* debug */ -static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw"; -int dvb_usb_gp8psk_debug; -module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) -{ - int ret = 0,try = 0; - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - while (ret >= 0 && ret != blen && try < 3) { - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_IN, - value,index,b,blen, - 2000); - deb_info("reading number %d (ret: %d)\n",try,ret); - try++; - } - - if (ret < 0 || ret != blen) { - warn("usb in %d operation failed.", req); - ret = -EIO; - } else - ret = 0; - - deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); - - mutex_unlock(&d->usb_mutex); - - return ret; -} - -int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, - u16 index, u8 *b, int blen) -{ - int ret; - - deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - if (usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 2000) != blen) { - warn("usb out operation failed."); - ret = -EIO; - } else - ret = 0; - mutex_unlock(&d->usb_mutex); - - return ret; -} - -static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d) -{ - int ret; - const struct firmware *fw = NULL; - const u8 *ptr; - u8 *buf; - if ((ret = request_firmware(&fw, bcm4500_firmware, - &d->udev->dev)) != 0) { - err("did not find the bcm4500 firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", - bcm4500_firmware,ret); - return ret; - } - - ret = -EINVAL; - - if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) - goto out_rel_fw; - - info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware); - - ptr = fw->data; - buf = kmalloc(64, GFP_KERNEL | GFP_DMA); - - while (ptr[0] != 0xff) { - u16 buflen = ptr[0] + 4; - if (ptr + buflen >= fw->data + fw->size) { - err("failed to load bcm4500 firmware."); - goto out_free; - } - memcpy(buf, ptr, buflen); - if (dvb_usb_generic_write(d, buf, buflen)) { - err("failed to load bcm4500 firmware."); - goto out_free; - } - ptr += buflen; - } - - ret = 0; - -out_free: - kfree(buf); -out_rel_fw: - release_firmware(fw); - - return ret; -} - -static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 status, buf; - int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct); - - if (onoff) { - gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1); - if (! (status & bm8pskStarted)) { /* started */ - if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K) - gp8psk_usb_out_op(d, CW3K_INIT, 1, 0, NULL, 0); - if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1)) - return -EINVAL; - } - - if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) - if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */ - if(gp8psk_load_bcm4500fw(d)) - return -EINVAL; - - if (! (status & bmIntersilOn)) /* LNB Power */ - if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, - &buf, 1)) - return -EINVAL; - - /* Set DVB mode to 1 */ - if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) - if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) - return -EINVAL; - /* Abort possible TS (if previous tune crashed) */ - if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0)) - return -EINVAL; - } else { - /* Turn off LNB power */ - if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) - return -EINVAL; - /* Turn off 8psk power */ - if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) - return -EINVAL; - if(gp_product_id == USB_PID_GENPIX_SKYWALKER_CW3K) - gp8psk_usb_out_op(d, CW3K_INIT, 0, 0, NULL, 0); - } - return 0; -} - -int gp8psk_bcm4500_reload(struct dvb_usb_device *d) -{ - u8 buf; - int gp_product_id = le16_to_cpu(d->udev->descriptor.idProduct); - /* Turn off 8psk power */ - if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) - return -EINVAL; - /* Turn On 8psk power */ - if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1)) - return -EINVAL; - /* load BCM4500 firmware */ - if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) - if (gp8psk_load_bcm4500fw(d)) - return -EINVAL; - return 0; -} - -static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - return gp8psk_usb_out_op(adap->dev, ARM_TRANSFER, onoff, 0 , NULL, 0); -} - -static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap) -{ - adap->fe = gp8psk_fe_attach(adap->dev); - return 0; -} - -static struct dvb_usb_device_properties gp8psk_properties; - -static int gp8psk_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - int ret; - struct usb_device *udev = interface_to_usbdev(intf); - ret = dvb_usb_device_init(intf, &gp8psk_properties, - THIS_MODULE, NULL, adapter_nr); - if (ret == 0) { - info("found Genpix USB device pID = %x (hex)", - le16_to_cpu(udev->descriptor.idProduct)); - } - return ret; -} - -static struct usb_device_id gp8psk_usb_table [] = { - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_COLD) }, - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_1_WARM) }, - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_REV_2) }, - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_1) }, - { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_SKYWALKER_CW3K) }, - { 0 }, -}; -MODULE_DEVICE_TABLE(usb, gp8psk_usb_table); - -static struct dvb_usb_device_properties gp8psk_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-gp8psk-01.fw", - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = gp8psk_streaming_ctrl, - .frontend_attach = gp8psk_frontend_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - } - }, - .power_ctrl = gp8psk_power_ctrl, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 4, - .devices = { - { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver", - .cold_ids = { &gp8psk_usb_table[0], NULL }, - .warm_ids = { &gp8psk_usb_table[1], NULL }, - }, - { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver", - .cold_ids = { NULL }, - .warm_ids = { &gp8psk_usb_table[2], NULL }, - }, - { .name = "Genpix SkyWalker-1 DVB-S receiver", - .cold_ids = { NULL }, - .warm_ids = { &gp8psk_usb_table[3], NULL }, - }, - { .name = "Genpix SkyWalker-CW3K DVB-S receiver", - .cold_ids = { NULL }, - .warm_ids = { &gp8psk_usb_table[4], NULL }, - }, - { NULL }, - } -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver gp8psk_usb_driver = { - .name = "dvb_usb_gp8psk", - .probe = gp8psk_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = gp8psk_usb_table, -}; - -/* module stuff */ -static int __init gp8psk_usb_module_init(void) -{ - int result; - if ((result = usb_register(&gp8psk_usb_driver))) { - err("usb_register failed. (%d)",result); - return result; - } - - return 0; -} - -static void __exit gp8psk_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&gp8psk_usb_driver); -} - -module_init(gp8psk_usb_module_init); -module_exit(gp8psk_usb_module_exit); - -MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>"); -MODULE_DESCRIPTION("Driver for Genpix 8psk-to-USB2 DVB-S"); -MODULE_VERSION("1.1"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h deleted file mode 100644 index e83a57506cf..00000000000 --- a/drivers/media/dvb/dvb-usb/gp8psk.h +++ /dev/null @@ -1,97 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - GENPIX 8pks/qpsk/DCII USB2.0 DVB-S module - * - * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com) - * Copyright (C) 2006,2007 Alan Nisota (alannisota@gmail.com) - * - * Thanks to GENPIX for the sample code used to implement this module. - * - * This module is based off the vp7045 and vp702x modules - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_GP8PSK_H_ -#define _DVB_USB_GP8PSK_H_ - -#define DVB_USB_LOG_PREFIX "gp8psk" -#include "dvb-usb.h" - -extern int dvb_usb_gp8psk_debug; -#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args) -#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args) -/* gp8psk commands */ - -/* Twinhan Vendor requests */ -#define TH_COMMAND_IN 0xC0 -#define TH_COMMAND_OUT 0xC1 - -/* gp8psk commands */ - -#define GET_8PSK_CONFIG 0x80 /* in */ -#define SET_8PSK_CONFIG 0x81 -#define I2C_WRITE 0x83 -#define I2C_READ 0x84 -#define ARM_TRANSFER 0x85 -#define TUNE_8PSK 0x86 -#define GET_SIGNAL_STRENGTH 0x87 /* in */ -#define LOAD_BCM4500 0x88 -#define BOOT_8PSK 0x89 /* in */ -#define START_INTERSIL 0x8A /* in */ -#define SET_LNB_VOLTAGE 0x8B -#define SET_22KHZ_TONE 0x8C -#define SEND_DISEQC_COMMAND 0x8D -#define SET_DVB_MODE 0x8E -#define SET_DN_SWITCH 0x8F -#define GET_SIGNAL_LOCK 0x90 /* in */ -#define GET_SERIAL_NUMBER 0x93 /* in */ -#define USE_EXTRA_VOLT 0x94 -#define CW3K_INIT 0x9d - -/* PSK_configuration bits */ -#define bm8pskStarted 0x01 -#define bm8pskFW_Loaded 0x02 -#define bmIntersilOn 0x04 -#define bmDVBmode 0x08 -#define bm22kHz 0x10 -#define bmSEL18V 0x20 -#define bmDCtuned 0x40 -#define bmArmed 0x80 - -/* Satellite modulation modes */ -#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */ -#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */ -#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */ -#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */ - -#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */ -#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */ -#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */ -#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */ -#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */ -#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 - -#define FW_VERSION_READ 0x0B -#define VENDOR_STRING_READ 0x0C -#define PRODUCT_STRING_READ 0x0D -#define FW_BCD_VERSION_READ 0x14 - -extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d); -extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); -extern int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, - u16 index, u8 *b, int blen); -extern int gp8psk_bcm4500_reload(struct dvb_usb_device *d); - -#endif diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c deleted file mode 100644 index 54626a0dbf6..00000000000 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ /dev/null @@ -1,933 +0,0 @@ -/* DVB USB compliant linux driver for MSI Mega Sky 580 DVB-T USB2.0 receiver - * - * Copyright (C) 2006 Aapo Tahkola (aet@rasterburn.org) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ - -#include "m920x.h" - -#include "mt352.h" -#include "mt352_priv.h" -#include "qt1010.h" -#include "tda1004x.h" -#include "tda827x.h" -#include <asm/unaligned.h> - -/* debug */ -static int dvb_usb_m920x_debug; -module_param_named(debug,dvb_usb_m920x_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid); - -static inline int m920x_read(struct usb_device *udev, u8 request, u16 value, - u16 index, void *data, int size) -{ - int ret; - - ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - request, USB_TYPE_VENDOR | USB_DIR_IN, - value, index, data, size, 2000); - if (ret < 0) { - printk(KERN_INFO "m920x_read = error: %d\n", ret); - return ret; - } - - if (ret != size) { - deb("m920x_read = no data\n"); - return -EIO; - } - - return 0; -} - -static inline int m920x_write(struct usb_device *udev, u8 request, - u16 value, u16 index) -{ - int ret; - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), - request, USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, NULL, 0, 2000); - - return ret; -} - -static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) -{ - int ret = 0, i, epi, flags = 0; - int adap_enabled[M9206_MAX_ADAPTERS] = { 0 }; - - /* Remote controller init. */ - if (d->props.rc_query) { - deb("Initialising remote control\n"); - while (rc_seq->address) { - if ((ret = m920x_write(d->udev, M9206_CORE, - rc_seq->data, - rc_seq->address)) != 0) { - deb("Initialising remote control failed\n"); - return ret; - } - - rc_seq++; - } - - deb("Initialising remote control success\n"); - } - - for (i = 0; i < d->props.num_adapters; i++) - flags |= d->adapter[i].props.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; - - if (epi < 0 || epi >= M9206_MAX_ADAPTERS) { - printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n"); - return -EINVAL; - } - - adap_enabled[epi] = 1; - } - - for (i = 0; i < M9206_MAX_ADAPTERS; i++) { - if (adap_enabled[i]) - continue; - - if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0) - return ret; - - if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0) - return ret; - } - } - - return ret; -} - -static int m920x_init_ep(struct usb_interface *intf) -{ - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_interface *alt; - - if ((alt = usb_altnum_to_altsetting(intf, 1)) == NULL) { - deb("No alt found!\n"); - return -ENODEV; - } - - return usb_set_interface(udev, alt->desc.bInterfaceNumber, - alt->desc.bAlternateSetting); -} - -static int m920x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct m920x_state *m = d->priv; - int i, ret = 0; - u8 rc_state[2]; - - if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0) - goto unlock; - - if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0) - goto unlock; - - for (i = 0; i < d->props.rc_key_map_size; i++) - if (d->props.rc_key_map[i].data == rc_state[1]) { - *event = d->props.rc_key_map[i].event; - - switch(rc_state[0]) { - case 0x80: - *state = REMOTE_NO_KEY_PRESSED; - goto unlock; - - case 0x88: /* framing error or "invalid code" */ - case 0x99: - case 0xc0: - case 0xd8: - *state = REMOTE_NO_KEY_PRESSED; - m->rep_count = 0; - goto unlock; - - case 0x93: - case 0x92: - m->rep_count = 0; - *state = REMOTE_KEY_PRESSED; - goto unlock; - - case 0x91: - /* prevent immediate auto-repeat */ - if (++m->rep_count > 2) - *state = REMOTE_KEY_REPEAT; - else - *state = REMOTE_NO_KEY_PRESSED; - goto unlock; - - default: - deb("Unexpected rc state %02x\n", rc_state[0]); - *state = REMOTE_NO_KEY_PRESSED; - goto unlock; - } - } - - if (rc_state[1] != 0) - deb("Unknown rc key %02x\n", rc_state[1]); - - *state = REMOTE_NO_KEY_PRESSED; - - unlock: - - return ret; -} - -/* I2C */ -static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i, j; - int ret = 0; - - if (!num) - return -EINVAL; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - if (msg[i].flags & (I2C_M_NO_RD_ACK | I2C_M_IGNORE_NAK | I2C_M_TEN) || msg[i].len == 0) { - /* For a 0 byte message, I think sending the address - * to index 0x80|0x40 would be the correct thing to - * do. However, zero byte messages are only used for - * probing, and since we don't know how to get the - * slave's ack, we can't probe. */ - ret = -ENOTSUPP; - goto unlock; - } - /* Send START & address/RW bit */ - if (!(msg[i].flags & I2C_M_NOSTART)) { - if ((ret = m920x_write(d->udev, M9206_I2C, - (msg[i].addr << 1) | - (msg[i].flags & I2C_M_RD ? 0x01 : 0), 0x80)) != 0) - goto unlock; - /* Should check for ack here, if we knew how. */ - } - if (msg[i].flags & I2C_M_RD) { - for (j = 0; j < msg[i].len; j++) { - /* Last byte of transaction? - * Send STOP, otherwise send ACK. */ - int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x01; - - if ((ret = m920x_read(d->udev, M9206_I2C, 0x0, - 0x20 | stop, - &msg[i].buf[j], 1)) != 0) - goto unlock; - } - } else { - for (j = 0; j < msg[i].len; j++) { - /* Last byte of transaction? Then send STOP. */ - int stop = (i+1 == num && j+1 == msg[i].len) ? 0x40 : 0x00; - - if ((ret = m920x_write(d->udev, M9206_I2C, msg[i].buf[j], stop)) != 0) - goto unlock; - /* Should check for ack here too. */ - } - } - } - ret = num; - - unlock: - mutex_unlock(&d->i2c_mutex); - - return ret; -} - -static u32 m920x_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm m920x_i2c_algo = { - .master_xfer = m920x_i2c_xfer, - .functionality = m920x_i2c_func, -}; - -/* pid filter */ -static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid) -{ - int ret = 0; - - if (pid >= 0x8000) - return -EINVAL; - - pid |= 0x8000; - - if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0) - return ret; - - if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0) - return ret; - - return ret; -} - -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; - - for (i = 0; i < M9206_MAX_FILTERS; i++) - if (m->filters[adap->id][i] == 8192) - enabled = 0; - - /* Disable all filters */ - if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0) - return ret; - - for (i = 0; i < M9206_MAX_FILTERS; i++) - if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0) - return ret; - - /* Set */ - if (enabled) { - for (i = 0; i < M9206_MAX_FILTERS; i++) { - if (m->filters[adap->id][i] == 0) - continue; - - if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0) - return ret; - - filter++; - } - } - - return ret; -} - -static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - struct m920x_state *m = adap->dev->priv; - - m->filtering_enabled[adap->id] = onoff ? 1 : 0; - - return m920x_update_filters(adap); -} - -static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) -{ - struct m920x_state *m = adap->dev->priv; - - m->filters[adap->id][index] = onoff ? pid : 0; - - return m920x_update_filters(adap); -} - -static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw) -{ - u16 value, index, size; - u8 read[4], *buff; - int i, pass, ret = 0; - - buff = kmalloc(65536, GFP_KERNEL); - - if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) - goto done; - deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]); - - if ((ret = m920x_read(udev, M9206_FW, 0x0, 0x0, read, 1)) != 0) - goto done; - deb("%x\n", read[0]); - - for (pass = 0; pass < 2; pass++) { - for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { - value = get_unaligned_le16(fw->data + i); - i += sizeof(u16); - - index = get_unaligned_le16(fw->data + i); - i += sizeof(u16); - - size = get_unaligned_le16(fw->data + i); - i += sizeof(u16); - - if (pass == 1) { - /* Will stall if using fw->data ... */ - memcpy(buff, fw->data + i, size); - - ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), - M9206_FW, - USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, buff, size, 20); - if (ret != size) { - deb("error while uploading fw!\n"); - ret = -EIO; - goto done; - } - msleep(3); - } - i += size; - } - if (i != fw->size) { - deb("bad firmware file!\n"); - ret = -EINVAL; - goto done; - } - } - - msleep(36); - - /* m920x will disconnect itself from the bus after this. */ - (void) m920x_write(udev, M9206_CORE, 0x01, M9206_FW_GO); - deb("firmware uploaded!\n"); - - done: - kfree(buff); - - return ret; -} - -/* Callbacks for DVB USB */ -static int m920x_identify_state(struct usb_device *udev, - struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, - int *cold) -{ - struct usb_host_interface *alt; - - alt = usb_altnum_to_altsetting(usb_ifnum_to_if(udev, 0), 1); - *cold = (alt == NULL) ? 1 : 0; - - return 0; -} - -/* demod configurations */ -static int m920x_mt352_demod_init(struct dvb_frontend *fe) -{ - int ret; - u8 config[] = { CONFIG, 0x3d }; - u8 clock[] = { CLOCK_CTL, 0x30 }; - u8 reset[] = { RESET, 0x80 }; - u8 adc_ctl[] = { ADC_CTL_1, 0x40 }; - u8 agc[] = { AGC_TARGET, 0x1c, 0x20 }; - u8 sec_agc[] = { 0x69, 0x00, 0xff, 0xff, 0x40, 0xff, 0x00, 0x40, 0x40 }; - u8 unk1[] = { 0x93, 0x1a }; - u8 unk2[] = { 0xb5, 0x7a }; - - deb("Demod init!\n"); - - if ((ret = mt352_write(fe, config, ARRAY_SIZE(config))) != 0) - return ret; - if ((ret = mt352_write(fe, clock, ARRAY_SIZE(clock))) != 0) - return ret; - if ((ret = mt352_write(fe, reset, ARRAY_SIZE(reset))) != 0) - return ret; - if ((ret = mt352_write(fe, adc_ctl, ARRAY_SIZE(adc_ctl))) != 0) - return ret; - if ((ret = mt352_write(fe, agc, ARRAY_SIZE(agc))) != 0) - return ret; - if ((ret = mt352_write(fe, sec_agc, ARRAY_SIZE(sec_agc))) != 0) - return ret; - if ((ret = mt352_write(fe, unk1, ARRAY_SIZE(unk1))) != 0) - return ret; - if ((ret = mt352_write(fe, unk2, ARRAY_SIZE(unk2))) != 0) - return ret; - - return 0; -} - -static struct mt352_config m920x_mt352_config = { - .demod_address = 0x0f, - .no_tuner = 1, - .demod_init = m920x_mt352_demod_init, -}; - -static struct tda1004x_config m920x_tda10046_08_config = { - .demod_address = 0x08, - .invert = 0, - .invert_oclk = 0, - .ts_mode = TDA10046_TS_SERIAL, - .xtal_freq = TDA10046_XTAL_16M, - .if_freq = TDA10046_FREQ_045, - .agc_config = TDA10046_AGC_TDA827X, - .gpio_config = TDA10046_GPTRI, - .request_firmware = NULL, -}; - -static struct tda1004x_config m920x_tda10046_0b_config = { - .demod_address = 0x0b, - .invert = 0, - .invert_oclk = 0, - .ts_mode = TDA10046_TS_SERIAL, - .xtal_freq = TDA10046_XTAL_16M, - .if_freq = TDA10046_FREQ_045, - .agc_config = TDA10046_AGC_TDA827X, - .gpio_config = TDA10046_GPTRI, - .request_firmware = NULL, /* uses firmware EEPROM */ -}; - -/* tuner configurations */ -static struct qt1010_config m920x_qt1010_config = { - .i2c_address = 0x62 -}; - -/* Callbacks for DVB USB */ -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) - return -EIO; - - return 0; -} - -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) - return -EIO; - - return 0; -} - -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) - return -EIO; - - return 0; -} - -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) - return -ENODEV; - - return 0; -} - -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) - return -ENODEV; - - return 0; -} - -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) - return -ENODEV; - - return 0; -} - -/* device-specific initialization */ -static struct m920x_inits megasky_rc_init [] = { - { M9206_RC_INIT2, 0xa8 }, - { M9206_RC_INIT1, 0x51 }, - { } /* terminating entry */ -}; - -static struct m920x_inits tvwalkertwin_rc_init [] = { - { M9206_RC_INIT2, 0x00 }, - { M9206_RC_INIT1, 0xef }, - { 0xff28, 0x00 }, - { 0xff23, 0x00 }, - { 0xff21, 0x30 }, - { } /* terminating entry */ -}; - -/* ir keymaps */ -static struct dvb_usb_rc_key megasky_rc_keys [] = { - { 0x0, 0x12, KEY_POWER }, - { 0x0, 0x1e, KEY_CYCLEWINDOWS }, /* min/max */ - { 0x0, 0x02, KEY_CHANNELUP }, - { 0x0, 0x05, KEY_CHANNELDOWN }, - { 0x0, 0x03, KEY_VOLUMEUP }, - { 0x0, 0x06, KEY_VOLUMEDOWN }, - { 0x0, 0x04, KEY_MUTE }, - { 0x0, 0x07, KEY_OK }, /* TS */ - { 0x0, 0x08, KEY_STOP }, - { 0x0, 0x09, KEY_MENU }, /* swap */ - { 0x0, 0x0a, KEY_REWIND }, - { 0x0, 0x1b, KEY_PAUSE }, - { 0x0, 0x1f, KEY_FASTFORWARD }, - { 0x0, 0x0c, KEY_RECORD }, - { 0x0, 0x0d, KEY_CAMERA }, /* screenshot */ - { 0x0, 0x0e, KEY_COFFEE }, /* "MTS" */ -}; - -static struct dvb_usb_rc_key tvwalkertwin_rc_keys [] = { - { 0x0, 0x01, KEY_ZOOM }, /* Full Screen */ - { 0x0, 0x02, KEY_CAMERA }, /* snapshot */ - { 0x0, 0x03, KEY_MUTE }, - { 0x0, 0x04, KEY_REWIND }, - { 0x0, 0x05, KEY_PLAYPAUSE }, /* Play/Pause */ - { 0x0, 0x06, KEY_FASTFORWARD }, - { 0x0, 0x07, KEY_RECORD }, - { 0x0, 0x08, KEY_STOP }, - { 0x0, 0x09, KEY_TIME }, /* Timeshift */ - { 0x0, 0x0c, KEY_COFFEE }, /* Recall */ - { 0x0, 0x0e, KEY_CHANNELUP }, - { 0x0, 0x12, KEY_POWER }, - { 0x0, 0x15, KEY_MENU }, /* source */ - { 0x0, 0x18, KEY_CYCLEWINDOWS }, /* TWIN PIP */ - { 0x0, 0x1a, KEY_CHANNELDOWN }, - { 0x0, 0x1b, KEY_VOLUMEDOWN }, - { 0x0, 0x1e, KEY_VOLUMEUP }, -}; - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties megasky_properties; -static struct dvb_usb_device_properties digivox_mini_ii_properties; -static struct dvb_usb_device_properties tvwalkertwin_properties; -static struct dvb_usb_device_properties dposh_properties; - -static int m920x_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct dvb_usb_device *d = NULL; - int ret; - struct m920x_inits *rc_init_seq = NULL; - int bInterfaceNumber = intf->cur_altsetting->desc.bInterfaceNumber; - - deb("Probing for m920x device at interface %d\n", bInterfaceNumber); - - if (bInterfaceNumber == 0) { - /* Single-tuner device, or first interface on - * multi-tuner device - */ - - ret = dvb_usb_device_init(intf, &megasky_properties, - THIS_MODULE, &d, adapter_nr); - if (ret == 0) { - rc_init_seq = megasky_rc_init; - goto found; - } - - ret = dvb_usb_device_init(intf, &digivox_mini_ii_properties, - THIS_MODULE, &d, adapter_nr); - if (ret == 0) { - /* No remote control, so no rc_init_seq */ - goto found; - } - - /* This configures both tuners on the TV Walker Twin */ - ret = dvb_usb_device_init(intf, &tvwalkertwin_properties, - THIS_MODULE, &d, adapter_nr); - if (ret == 0) { - rc_init_seq = tvwalkertwin_rc_init; - goto found; - } - - ret = dvb_usb_device_init(intf, &dposh_properties, - THIS_MODULE, &d, adapter_nr); - if (ret == 0) { - /* Remote controller not supported yet. */ - goto found; - } - - return ret; - } else { - /* Another interface on a multi-tuner device */ - - /* The LifeView TV Walker Twin gets here, but struct - * tvwalkertwin_properties already configured both - * tuners, so there is nothing for us to do here - */ - } - - found: - if ((ret = m920x_init_ep(intf)) < 0) - return ret; - - if (d && (ret = m920x_init(d, rc_init_seq)) != 0) - return ret; - - return ret; -} - -static struct usb_device_id m920x_table [] = { - { USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) }, - { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, - USB_PID_MSI_DIGI_VOX_MINI_II) }, - { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, - USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD) }, - { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC, - USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM) }, - { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_COLD) }, - { USB_DEVICE(USB_VID_DPOSH, USB_PID_DPOSH_M9206_WARM) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, m920x_table); - -static struct dvb_usb_device_properties megasky_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-megasky-02.fw", - .download_firmware = m920x_firmware_download, - - .rc_interval = 100, - .rc_key_map = megasky_rc_keys, - .rc_key_map_size = ARRAY_SIZE(megasky_rc_keys), - .rc_query = m920x_rc_query, - - .size_of_priv = sizeof(struct m920x_state), - - .identify_state = m920x_identify_state, - .num_adapters = 1, - .adapter = {{ - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 8, - .pid_filter = m920x_pid_filter, - .pid_filter_ctrl = m920x_pid_filter_ctrl, - - .frontend_attach = m920x_mt352_frontend_attach, - .tuner_attach = m920x_qt1010_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - }}, - .i2c_algo = &m920x_i2c_algo, - - .num_device_descs = 1, - .devices = { - { "MSI Mega Sky 580 DVB-T USB2.0", - { &m920x_table[0], NULL }, - { NULL }, - } - } -}; - -static struct dvb_usb_device_properties digivox_mini_ii_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-digivox-02.fw", - .download_firmware = m920x_firmware_download, - - .size_of_priv = sizeof(struct m920x_state), - - .identify_state = m920x_identify_state, - .num_adapters = 1, - .adapter = {{ - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 8, - .pid_filter = m920x_pid_filter, - .pid_filter_ctrl = m920x_pid_filter_ctrl, - - .frontend_attach = m920x_tda10046_08_frontend_attach, - .tuner_attach = m920x_tda8275_60_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 0x4000, - } - } - }, - }}, - .i2c_algo = &m920x_i2c_algo, - - .num_device_descs = 1, - .devices = { - { "MSI DIGI VOX mini II DVB-T USB2.0", - { &m920x_table[1], NULL }, - { NULL }, - }, - } -}; - -/* LifeView TV Walker Twin support by Nick Andrew <nick@nick-andrew.net> - * - * LifeView TV Walker Twin has 1 x M9206, 2 x TDA10046, 2 x TDA8275A - * TDA10046 #0 is located at i2c address 0x08 - * TDA10046 #1 is located at i2c address 0x0b - * TDA8275A #0 is located at i2c address 0x60 - * TDA8275A #1 is located at i2c address 0x61 - */ -static struct dvb_usb_device_properties tvwalkertwin_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-tvwalkert.fw", - .download_firmware = m920x_firmware_download, - - .rc_interval = 100, - .rc_key_map = tvwalkertwin_rc_keys, - .rc_key_map_size = ARRAY_SIZE(tvwalkertwin_rc_keys), - .rc_query = m920x_rc_query, - - .size_of_priv = sizeof(struct m920x_state), - - .identify_state = m920x_identify_state, - .num_adapters = 2, - .adapter = {{ - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 8, - .pid_filter = m920x_pid_filter, - .pid_filter_ctrl = m920x_pid_filter_ctrl, - - .frontend_attach = m920x_tda10046_08_frontend_attach, - .tuner_attach = m920x_tda8275_60_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 512, - } - } - }},{ - .caps = DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - - .pid_filter_count = 8, - .pid_filter = m920x_pid_filter, - .pid_filter_ctrl = m920x_pid_filter_ctrl, - - .frontend_attach = m920x_tda10046_0b_frontend_attach, - .tuner_attach = m920x_tda8275_61_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - }}, - .i2c_algo = &m920x_i2c_algo, - - .num_device_descs = 1, - .devices = { - { .name = "LifeView TV Walker Twin DVB-T USB2.0", - .cold_ids = { &m920x_table[2], NULL }, - .warm_ids = { &m920x_table[3], NULL }, - }, - } -}; - -static struct dvb_usb_device_properties dposh_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-dposh-01.fw", - .download_firmware = m920x_firmware_download, - - .size_of_priv = sizeof(struct m920x_state), - - .identify_state = m920x_identify_state, - .num_adapters = 1, - .adapter = {{ - /* Hardware pid filters don't work with this device/firmware */ - - .frontend_attach = m920x_mt352_frontend_attach, - .tuner_attach = m920x_qt1010_tuner_attach, - - .stream = { - .type = USB_BULK, - .count = 8, - .endpoint = 0x81, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - }}, - .i2c_algo = &m920x_i2c_algo, - - .num_device_descs = 1, - .devices = { - { .name = "Dposh DVB-T USB2.0", - .cold_ids = { &m920x_table[4], NULL }, - .warm_ids = { &m920x_table[5], NULL }, - }, - } -}; - -static struct usb_driver m920x_driver = { - .name = "dvb_usb_m920x", - .probe = m920x_probe, - .disconnect = dvb_usb_device_exit, - .id_table = m920x_table, -}; - -/* module stuff */ -static int __init m920x_module_init(void) -{ - int ret; - - if ((ret = usb_register(&m920x_driver))) { - err("usb_register failed. Error number %d", ret); - return ret; - } - - return 0; -} - -static void __exit m920x_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&m920x_driver); -} - -module_init (m920x_module_init); -module_exit (m920x_module_exit); - -MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>"); -MODULE_DESCRIPTION("DVB Driver for ULI M920x"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h deleted file mode 100644 index 37532890acc..00000000000 --- a/drivers/media/dvb/dvb-usb/m920x.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef _DVB_USB_M920X_H_ -#define _DVB_USB_M920X_H_ - -#define DVB_USB_LOG_PREFIX "m920x" -#include "dvb-usb.h" - -#define deb(args...) dprintk(dvb_usb_m920x_debug,0x01,args) - -#define M9206_CORE 0x22 -#define M9206_RC_STATE 0xff51 -#define M9206_RC_KEY 0xff52 -#define M9206_RC_INIT1 0xff54 -#define M9206_RC_INIT2 0xff55 -#define M9206_FW_GO 0xff69 - -#define M9206_I2C 0x23 -#define M9206_FILTER 0x25 -#define M9206_FW 0x30 - -#define M9206_MAX_FILTERS 8 -#define M9206_MAX_ADAPTERS 2 - -/* -sequences found in logs: -[index value] -0x80 write addr -(0x00 out byte)* -0x40 out byte - -0x80 write addr -(0x00 out byte)* -0x80 read addr -(0x21 in byte)* -0x60 in byte - -this sequence works: -0x80 read addr -(0x21 in byte)* -0x60 in byte - -Guess at API of the I2C function: -I2C operation is done one byte at a time with USB control messages. The -index the messages is sent to is made up of a set of flags that control -the I2C bus state: -0x80: Send START condition. After a START condition, one would normally - always send the 7-bit slave I2C address as the 7 MSB, followed by - the read/write bit as the LSB. -0x40: Send STOP condition. This should be set on the last byte of an - I2C transaction. -0x20: Read a byte from the slave. As opposed to writing a byte to the - slave. The slave will normally not produce any data unless you - set the R/W bit to 1 when sending the slave's address after the - START condition. -0x01: Respond with ACK, as opposed to a NACK. For a multi-byte read, - the master should send an ACK, that is pull SDA low during the 9th - clock cycle, after every byte but the last. This flags only makes - sense when bit 0x20 is set, indicating a read. - -What any other bits might mean, or how to get the slave's ACK/NACK -response to a write, is unknown. -*/ - -struct m920x_state { - u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS]; - int filtering_enabled[M9206_MAX_ADAPTERS]; - int rep_count; -}; - -/* Initialisation data for the m920x - */ - -struct m920x_inits { - u16 address; - u8 data; -}; - -#endif diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c deleted file mode 100644 index 07fb843c7c2..00000000000 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ /dev/null @@ -1,247 +0,0 @@ -/* DVB USB framework compliant Linux driver for the Hauppauge WinTV-NOVA-T usb2 - * DVB-T receiver. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dibusb.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=rc,2=eeprom (|-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define deb_rc(args...) dprintk(debug,0x01,args) -#define deb_ee(args...) dprintk(debug,0x02,args) - -/* Hauppauge NOVA-T USB2 keys */ -static struct dvb_usb_rc_key haupp_rc_keys [] = { - { 0x1e, 0x00, KEY_0 }, - { 0x1e, 0x01, KEY_1 }, - { 0x1e, 0x02, KEY_2 }, - { 0x1e, 0x03, KEY_3 }, - { 0x1e, 0x04, KEY_4 }, - { 0x1e, 0x05, KEY_5 }, - { 0x1e, 0x06, KEY_6 }, - { 0x1e, 0x07, KEY_7 }, - { 0x1e, 0x08, KEY_8 }, - { 0x1e, 0x09, KEY_9 }, - { 0x1e, 0x0a, KEY_KPASTERISK }, - { 0x1e, 0x0b, KEY_RED }, - { 0x1e, 0x0c, KEY_RADIO }, - { 0x1e, 0x0d, KEY_MENU }, - { 0x1e, 0x0e, KEY_GRAVE }, /* # */ - { 0x1e, 0x0f, KEY_MUTE }, - { 0x1e, 0x10, KEY_VOLUMEUP }, - { 0x1e, 0x11, KEY_VOLUMEDOWN }, - { 0x1e, 0x12, KEY_CHANNEL }, - { 0x1e, 0x14, KEY_UP }, - { 0x1e, 0x15, KEY_DOWN }, - { 0x1e, 0x16, KEY_LEFT }, - { 0x1e, 0x17, KEY_RIGHT }, - { 0x1e, 0x18, KEY_VIDEO }, - { 0x1e, 0x19, KEY_AUDIO }, - { 0x1e, 0x1a, KEY_MEDIA }, - { 0x1e, 0x1b, KEY_EPG }, - { 0x1e, 0x1c, KEY_TV }, - { 0x1e, 0x1e, KEY_NEXT }, - { 0x1e, 0x1f, KEY_BACK }, - { 0x1e, 0x20, KEY_CHANNELUP }, - { 0x1e, 0x21, KEY_CHANNELDOWN }, - { 0x1e, 0x24, KEY_LAST }, /* Skip backwards */ - { 0x1e, 0x25, KEY_OK }, - { 0x1e, 0x29, KEY_BLUE}, - { 0x1e, 0x2e, KEY_GREEN }, - { 0x1e, 0x30, KEY_PAUSE }, - { 0x1e, 0x32, KEY_REWIND }, - { 0x1e, 0x34, KEY_FASTFORWARD }, - { 0x1e, 0x35, KEY_PLAY }, - { 0x1e, 0x36, KEY_STOP }, - { 0x1e, 0x37, KEY_RECORD }, - { 0x1e, 0x38, KEY_YELLOW }, - { 0x1e, 0x3b, KEY_GOTO }, - { 0x1e, 0x3d, KEY_POWER }, -}; - -/* Firmware bug? sometimes, when a new key is pressed, the previous pressed key - * is delivered. No workaround yet, maybe a new firmware. - */ -static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom; - u16 raw; - int i; - struct dibusb_device_state *st = d->priv; - - dvb_usb_generic_rw(d,cmd,2,key,5,0); - - *state = REMOTE_NO_KEY_PRESSED; - switch (key[0]) { - case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED: - raw = ((key[1] << 8) | key[2]) >> 3; - toggle = !!(raw & 0x800); - data = raw & 0x3f; - custom = (raw >> 6) & 0x1f; - - deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x toggle: %d\n",key[1],key[2],key[3],custom,data,toggle); - - for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) { - if (haupp_rc_keys[i].data == data && - haupp_rc_keys[i].custom == custom) { - - deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom); - - *event = haupp_rc_keys[i].event; - *state = REMOTE_KEY_PRESSED; - if (st->old_toggle == toggle) { - if (st->last_repeat_count++ < 2) - *state = REMOTE_NO_KEY_PRESSED; - } else { - st->last_repeat_count = 0; - st->old_toggle = toggle; - } - break; - } - } - - break; - case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY: - default: - break; - } - - return 0; -} - -static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) -{ - int i; - u8 b; - - mac[0] = 0x00; - mac[1] = 0x0d; - mac[2] = 0xfe; - - /* this is a complete guess, but works for my box */ - for (i = 136; i < 139; i++) { - dibusb_read_eeprom_byte(d,i, &b); - - mac[5 - (i - 136)] = b; - } - - return 0; -} - -/* USB Driver stuff */ -static struct dvb_usb_device_properties nova_t_properties; - -static int nova_t_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &nova_t_properties, - THIS_MODULE, NULL, adapter_nr); -} - -/* do not change the order of the ID table */ -static struct usb_device_id nova_t_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_COLD) }, -/* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, nova_t_table); - -static struct dvb_usb_device_properties nova_t_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-nova-t-usb2-02.fw", - - .num_adapters = 1, - .adapter = { - { - .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, - .pid_filter = dibusb_pid_filter, - .pid_filter_ctrl = dibusb_pid_filter_ctrl, - .frontend_attach = dibusb_dib3000mc_frontend_attach, - .tuner_attach = dibusb_dib3000mc_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - - .size_of_priv = sizeof(struct dibusb_state), - } - }, - .size_of_priv = sizeof(struct dibusb_device_state), - - .power_ctrl = dibusb2_0_power_ctrl, - .read_mac_address = nova_t_read_mac_address, - - .rc_interval = 100, - .rc_key_map = haupp_rc_keys, - .rc_key_map_size = ARRAY_SIZE(haupp_rc_keys), - .rc_query = nova_t_rc_query, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "Hauppauge WinTV-NOVA-T usb2", - { &nova_t_table[0], NULL }, - { &nova_t_table[1], NULL }, - }, - { NULL }, - } -}; - -static struct usb_driver nova_t_driver = { - .name = "dvb_usb_nova_t_usb2", - .probe = nova_t_probe, - .disconnect = dvb_usb_device_exit, - .id_table = nova_t_table, -}; - -/* module stuff */ -static int __init nova_t_module_init(void) -{ - int result; - if ((result = usb_register(&nova_t_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit nova_t_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&nova_t_driver); -} - -module_init (nova_t_module_init); -module_exit (nova_t_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Hauppauge WinTV-NOVA-T usb2"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c deleted file mode 100644 index 7e32d11f32b..00000000000 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ /dev/null @@ -1,588 +0,0 @@ -/* DVB USB framework compliant Linux driver for the Opera1 DVB-S Card -* -* Copyright (C) 2006 Mario Hlawitschka (dh1pa@amsat.org) -* Copyright (C) 2006 Marco Gittler (g.marco@freenet.de) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the Free -* Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ - -#define DVB_USB_LOG_PREFIX "opera" - -#include "dvb-usb.h" -#include "stv0299.h" - -#define OPERA_READ_MSG 0 -#define OPERA_WRITE_MSG 1 -#define OPERA_I2C_TUNER 0xd1 - -#define READ_FX2_REG_REQ 0xba -#define READ_MAC_ADDR 0x08 -#define OPERA_WRITE_FX2 0xbb -#define OPERA_TUNER_REQ 0xb1 -#define REG_1F_SYMBOLRATE_BYTE0 0x1f -#define REG_20_SYMBOLRATE_BYTE1 0x20 -#define REG_21_SYMBOLRATE_BYTE2 0x21 - -#define ADDR_B600_VOLTAGE_13V (0x02) -#define ADDR_B601_VOLTAGE_18V (0x03) -#define ADDR_B1A6_STREAM_CTRL (0x04) -#define ADDR_B880_READ_REMOTE (0x05) - -struct opera1_state { - u32 last_key_pressed; -}; -struct opera_rc_keys { - u32 keycode; - u32 event; -}; - -static int dvb_usb_opera1_debug; -module_param_named(debug, dvb_usb_opera1_debug, int, 0644); -MODULE_PARM_DESC(debug, - "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64 (or-able))." - DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - - -static int opera1_xilinx_rw(struct usb_device *dev, u8 request, u16 value, - u8 * data, u16 len, int flags) -{ - int ret; - u8 r; - u8 u8buf[len]; - - unsigned int pipe = (flags == OPERA_READ_MSG) ? - usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0); - u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT; - - if (flags == OPERA_WRITE_MSG) - memcpy(u8buf, data, len); - ret = - usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR, - value, 0x0, u8buf, len, 2000); - - if (request == OPERA_TUNER_REQ) { - if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR, - 0x01, 0x0, &r, 1, 2000)<1 || r!=0x08) - return 0; - } - if (flags == OPERA_READ_MSG) - memcpy(data, u8buf, len); - return ret; -} - -/* I2C */ - -static int opera1_usb_i2c_msgxfer(struct dvb_usb_device *dev, u16 addr, - u8 * buf, u16 len) -{ - int ret = 0; - u8 request; - u16 value; - - if (!dev) { - info("no usb_device"); - return -EINVAL; - } - if (mutex_lock_interruptible(&dev->usb_mutex) < 0) - return -EAGAIN; - - switch (addr>>1){ - case ADDR_B600_VOLTAGE_13V: - request=0xb6; - value=0x00; - break; - case ADDR_B601_VOLTAGE_18V: - request=0xb6; - value=0x01; - break; - case ADDR_B1A6_STREAM_CTRL: - request=0xb1; - value=0xa6; - break; - case ADDR_B880_READ_REMOTE: - request=0xb8; - value=0x80; - break; - default: - request=0xb1; - value=addr; - } - ret = opera1_xilinx_rw(dev->udev, request, - value, buf, len, - addr&0x01?OPERA_READ_MSG:OPERA_WRITE_MSG); - - mutex_unlock(&dev->usb_mutex); - return ret; -} - -static int opera1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], - int num) -{ - struct dvb_usb_device *d = i2c_get_adapdata(adap); - int i = 0, tmp = 0; - - if (!d) - return -ENODEV; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - for (i = 0; i < num; i++) { - if ((tmp = opera1_usb_i2c_msgxfer(d, - (msg[i].addr<<1)|(msg[i].flags&I2C_M_RD?0x01:0), - msg[i].buf, - msg[i].len - )!= msg[i].len)) { - break; - } - if (dvb_usb_opera1_debug & 0x10) - info("sending i2c mesage %d %d", tmp, msg[i].len); - } - mutex_unlock(&d->i2c_mutex); - return num; -} - -static u32 opera1_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm opera1_i2c_algo = { - .master_xfer = opera1_i2c_xfer, - .functionality = opera1_i2c_func, -}; - -static int opera1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - static u8 command_13v[1]={0x00}; - static u8 command_18v[1]={0x01}; - struct i2c_msg msg[] = { - {.addr = ADDR_B600_VOLTAGE_13V,.flags = 0,.buf = command_13v,.len = 1}, - }; - struct dvb_usb_adapter *udev_adap = - (struct dvb_usb_adapter *)(fe->dvb->priv); - if (voltage == SEC_VOLTAGE_18) { - msg[0].addr = ADDR_B601_VOLTAGE_18V; - msg[0].buf = command_18v; - } - i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1); - return 0; -} - -static int opera1_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, - u32 ratio) -{ - stv0299_writereg(fe, 0x13, 0x98); - stv0299_writereg(fe, 0x14, 0x95); - stv0299_writereg(fe, REG_1F_SYMBOLRATE_BYTE0, (ratio >> 16) & 0xff); - stv0299_writereg(fe, REG_20_SYMBOLRATE_BYTE1, (ratio >> 8) & 0xff); - stv0299_writereg(fe, REG_21_SYMBOLRATE_BYTE2, (ratio) & 0xf0); - return 0; - -} -static u8 opera1_inittab[] = { - 0x00, 0xa1, - 0x01, 0x15, - 0x02, 0x00, - 0x03, 0x00, - 0x04, 0x7d, - 0x05, 0x05, - 0x06, 0x02, - 0x07, 0x00, - 0x0b, 0x00, - 0x0c, 0x01, - 0x0d, 0x81, - 0x0e, 0x44, - 0x0f, 0x19, - 0x10, 0x3f, - 0x11, 0x84, - 0x12, 0xda, - 0x13, 0x98, - 0x14, 0x95, - 0x15, 0xc9, - 0x16, 0xeb, - 0x17, 0x00, - 0x18, 0x19, - 0x19, 0x8b, - 0x1a, 0x00, - 0x1b, 0x82, - 0x1c, 0x7f, - 0x1d, 0x00, - 0x1e, 0x00, - REG_1F_SYMBOLRATE_BYTE0, 0x06, - REG_20_SYMBOLRATE_BYTE1, 0x50, - REG_21_SYMBOLRATE_BYTE2, 0x10, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x37, - 0x25, 0xbc, - 0x26, 0x00, - 0x27, 0x00, - 0x28, 0x00, - 0x29, 0x1e, - 0x2a, 0x14, - 0x2b, 0x1f, - 0x2c, 0x09, - 0x2d, 0x0a, - 0x2e, 0x00, - 0x2f, 0x00, - 0x30, 0x00, - 0x31, 0x1f, - 0x32, 0x19, - 0x33, 0xfc, - 0x34, 0x13, - 0xff, 0xff, -}; - -static struct stv0299_config opera1_stv0299_config = { - .demod_address = 0xd0>>1, - .min_delay_ms = 100, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_0, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .inittab = opera1_inittab, - .set_symbol_rate = opera1_stv0299_set_symbol_rate, -}; - -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; - return 0; - } - info("not attached stv0299"); - return -EIO; -} - -static int opera1_tuner_attach(struct dvb_usb_adapter *adap) -{ - dvb_attach( - dvb_pll_attach, adap->fe, 0xc0>>1, - &adap->dev->i2c_adap, DVB_PLL_OPERA1 - ); - return 0; -} - -static int opera1_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 val = onoff ? 0x01 : 0x00; - - if (dvb_usb_opera1_debug) - info("power %s", onoff ? "on" : "off"); - return opera1_xilinx_rw(d->udev, 0xb7, val, - &val, 1, OPERA_WRITE_MSG); -} - -static int opera1_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - static u8 buf_start[2] = { 0xff, 0x03 }; - static u8 buf_stop[2] = { 0xff, 0x00 }; - struct i2c_msg start_tuner[] = { - {.addr = ADDR_B1A6_STREAM_CTRL,.buf = onoff ? buf_start : buf_stop,.len = 2}, - }; - if (dvb_usb_opera1_debug) - info("streaming %s", onoff ? "on" : "off"); - i2c_transfer(&adap->dev->i2c_adap, start_tuner, 1); - return 0; -} - -static int opera1_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, - int onoff) -{ - u8 b_pid[3]; - struct i2c_msg msg[] = { - {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3}, - }; - if (dvb_usb_opera1_debug) - info("pidfilter index: %d pid: %d %s", index, pid, - onoff ? "on" : "off"); - b_pid[0] = (2 * index) + 4; - b_pid[1] = onoff ? (pid & 0xff) : (0x00); - b_pid[2] = onoff ? ((pid >> 8) & 0xff) : (0x00); - i2c_transfer(&adap->dev->i2c_adap, msg, 1); - return 0; -} - -static int opera1_pid_filter_control(struct dvb_usb_adapter *adap, int onoff) -{ - int u = 0x04; - u8 b_pid[3]; - struct i2c_msg msg[] = { - {.addr = ADDR_B1A6_STREAM_CTRL,.buf = b_pid,.len = 3}, - }; - if (dvb_usb_opera1_debug) - info("%s hw-pidfilter", onoff ? "enable" : "disable"); - for (; u < 0x7e; u += 2) { - b_pid[0] = u; - b_pid[1] = 0; - b_pid[2] = 0x80; - i2c_transfer(&adap->dev->i2c_adap, msg, 1); - } - return 0; -} - -static struct dvb_usb_rc_key opera1_rc_keys[] = { - {0x5f, 0xa0, KEY_1}, - {0x51, 0xaf, KEY_2}, - {0x5d, 0xa2, KEY_3}, - {0x41, 0xbe, KEY_4}, - {0x0b, 0xf5, KEY_5}, - {0x43, 0xbd, KEY_6}, - {0x47, 0xb8, KEY_7}, - {0x49, 0xb6, KEY_8}, - {0x05, 0xfa, KEY_9}, - {0x45, 0xba, KEY_0}, - {0x09, 0xf6, KEY_UP}, /*chanup */ - {0x1b, 0xe5, KEY_DOWN}, /*chandown */ - {0x5d, 0xa3, KEY_LEFT}, /*voldown */ - {0x5f, 0xa1, KEY_RIGHT}, /*volup */ - {0x07, 0xf8, KEY_SPACE}, /*tab */ - {0x1f, 0xe1, KEY_ENTER}, /*play ok */ - {0x1b, 0xe4, KEY_Z}, /*zoom */ - {0x59, 0xa6, KEY_M}, /*mute */ - {0x5b, 0xa5, KEY_F}, /*tv/f */ - {0x19, 0xe7, KEY_R}, /*rec */ - {0x01, 0xfe, KEY_S}, /*Stop */ - {0x03, 0xfd, KEY_P}, /*pause */ - {0x03, 0xfc, KEY_W}, /*<- -> */ - {0x07, 0xf9, KEY_C}, /*capture */ - {0x47, 0xb9, KEY_Q}, /*exit */ - {0x43, 0xbc, KEY_O}, /*power */ - -}; - -static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) -{ - struct opera1_state *opst = dev->priv; - u8 rcbuffer[32]; - const u16 startmarker1 = 0x10ed; - const u16 startmarker2 = 0x11ec; - struct i2c_msg read_remote[] = { - {.addr = ADDR_B880_READ_REMOTE,.buf = rcbuffer,.flags = I2C_M_RD,.len = 32}, - }; - int i = 0; - u32 send_key = 0; - - if (i2c_transfer(&dev->i2c_adap, read_remote, 1) == 1) { - for (i = 0; i < 32; i++) { - if (rcbuffer[i]) - send_key |= 1; - if (i < 31) - send_key = send_key << 1; - } - if (send_key & 0x8000) - send_key = (send_key << 1) | (send_key >> 15 & 0x01); - - if (send_key == 0xffff && opst->last_key_pressed != 0) { - *state = REMOTE_KEY_REPEAT; - *event = opst->last_key_pressed; - return 0; - } - for (; send_key != 0;) { - if (send_key >> 16 == startmarker2) { - break; - } else if (send_key >> 16 == startmarker1) { - send_key = - (send_key & 0xfffeffff) | (startmarker1 << 16); - break; - } else - send_key >>= 1; - } - - if (send_key == 0) - return 0; - - send_key = (send_key & 0xffff) | 0x0100; - - for (i = 0; i < ARRAY_SIZE(opera1_rc_keys); i++) { - if ((opera1_rc_keys[i].custom * 256 + - opera1_rc_keys[i].data) == (send_key & 0xffff)) { - *state = REMOTE_KEY_PRESSED; - *event = opera1_rc_keys[i].event; - opst->last_key_pressed = - opera1_rc_keys[i].event; - break; - } - opst->last_key_pressed = 0; - } - } else - *state = REMOTE_NO_KEY_PRESSED; - return 0; -} - -static struct usb_device_id opera1_table[] = { - {USB_DEVICE(USB_VID_CYPRESS, USB_PID_OPERA1_COLD)}, - {USB_DEVICE(USB_VID_OPERA1, USB_PID_OPERA1_WARM)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, opera1_table); - -static int opera1_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) -{ - u8 command[] = { READ_MAC_ADDR }; - opera1_xilinx_rw(d->udev, 0xb1, 0xa0, command, 1, OPERA_WRITE_MSG); - opera1_xilinx_rw(d->udev, 0xb1, 0xa1, mac, 6, OPERA_READ_MSG); - return 0; -} -static int opera1_xilinx_load_firmware(struct usb_device *dev, - const char *filename) -{ - const struct firmware *fw = NULL; - u8 *b, *p; - int ret = 0, i,fpgasize=40; - u8 testval; - info("start downloading fpga firmware %s",filename); - - if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems.", - filename); - return ret; - } else { - p = kmalloc(fw->size, GFP_KERNEL); - opera1_xilinx_rw(dev, 0xbc, 0x00, &testval, 1, OPERA_READ_MSG); - if (p != NULL && testval != 0x67) { - - u8 reset = 0, fpga_command = 0; - memcpy(p, fw->data, fw->size); - /* clear fpga ? */ - opera1_xilinx_rw(dev, 0xbc, 0xaa, &fpga_command, 1, - OPERA_WRITE_MSG); - for (i = 0; i < fw->size;) { - if ( (fw->size - i) <fpgasize){ - fpgasize=fw->size-i; - } - b = (u8 *) p + i; - if (opera1_xilinx_rw - (dev, OPERA_WRITE_FX2, 0x0, b , fpgasize, - OPERA_WRITE_MSG) != fpgasize - ) { - err("error while transferring firmware"); - ret = -EINVAL; - break; - } - i = i + fpgasize; - } - /* restart the CPU */ - if (ret || opera1_xilinx_rw - (dev, 0xa0, 0xe600, &reset, 1, - OPERA_WRITE_MSG) != 1) { - err("could not restart the USB controller CPU."); - ret = -EINVAL; - } - } - } - kfree(p); - if (fw) { - release_firmware(fw); - } - return ret; -} - -static struct dvb_usb_device_properties opera1_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-opera-01.fw", - .size_of_priv = sizeof(struct opera1_state), - - .power_ctrl = opera1_power_ctrl, - .i2c_algo = &opera1_i2c_algo, - - .rc_key_map = opera1_rc_keys, - .rc_key_map_size = ARRAY_SIZE(opera1_rc_keys), - .rc_interval = 200, - .rc_query = opera1_rc_query, - .read_mac_address = opera1_read_mac_address, - .generic_bulk_ctrl_endpoint = 0x00, - /* parameter for the MPEG2-data transfer */ - .num_adapters = 1, - .adapter = { - { - .frontend_attach = opera1_frontend_attach, - .streaming_ctrl = opera1_streaming_ctrl, - .tuner_attach = opera1_tuner_attach, - .caps = - DVB_USB_ADAP_HAS_PID_FILTER | - DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, - .pid_filter = opera1_pid_filter, - .pid_filter_ctrl = opera1_pid_filter_control, - .pid_filter_count = 252, - .stream = { - .type = USB_BULK, - .count = 10, - .endpoint = 0x82, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .num_device_descs = 1, - .devices = { - {"Opera1 DVB-S USB2.0", - {&opera1_table[0], NULL}, - {&opera1_table[1], NULL}, - }, - } -}; - -static int opera1_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - - if (udev->descriptor.idProduct == USB_PID_OPERA1_WARM && - udev->descriptor.idVendor == USB_VID_OPERA1 && - opera1_xilinx_load_firmware(udev, "dvb-usb-opera1-fpga-01.fw") != 0 - ) { - return -EINVAL; - } - - if (0 != dvb_usb_device_init(intf, &opera1_properties, - THIS_MODULE, NULL, adapter_nr)) - return -EINVAL; - return 0; -} - -static struct usb_driver opera1_driver = { - .name = "opera1", - .probe = opera1_probe, - .disconnect = dvb_usb_device_exit, - .id_table = opera1_table, -}; - -static int __init opera1_module_init(void) -{ - int result = 0; - if ((result = usb_register(&opera1_driver))) { - err("usb_register failed. Error number %d", result); - } - return result; -} - -static void __exit opera1_module_exit(void) -{ - usb_deregister(&opera1_driver); -} - -module_init(opera1_module_init); -module_exit(opera1_module_exit); - -MODULE_AUTHOR("Mario Hlawitschka (c) dh1pa@amsat.org"); -MODULE_AUTHOR("Marco Gittler (c) g.marco@freenet.de"); -MODULE_DESCRIPTION("Driver for Opera1 DVB-S device"); -MODULE_VERSION("0.1"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c deleted file mode 100644 index 20ca9d9ee99..00000000000 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ /dev/null @@ -1,335 +0,0 @@ -/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones - * (e.g. Pinnacle 400e DVB-S USB2.0). - * - * The Pinnacle 400e uses the same protocol as the Technotrend USB1.1 boxes. - * - * TDA8263 + TDA10086 - * - * I2C addresses: - * 0x08 - LNBP21PD - LNB power supply - * 0x0e - TDA10086 - Demodulator - * 0x50 - FX2 eeprom - * 0x60 - TDA8263 - Tuner - * 0x78 ??? - * - * Copyright (c) 2002 Holger Waechtler <holger@convergence.de> - * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> - * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#define DVB_USB_LOG_PREFIX "ttusb2" -#include "dvb-usb.h" - -#include "ttusb2.h" - -#include "tda826x.h" -#include "tda10086.h" -#include "lnbp21.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); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct ttusb2_state { - u8 id; -}; - -static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, - u8 *wbuf, int wlen, u8 *rbuf, int rlen) -{ - struct ttusb2_state *st = d->priv; - u8 s[wlen+4],r[64] = { 0 }; - int ret = 0; - - memset(s,0,wlen+4); - - s[0] = 0xaa; - s[1] = ++st->id; - s[2] = cmd; - s[3] = wlen; - memcpy(&s[4],wbuf,wlen); - - ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0); - - if (ret != 0 || - r[0] != 0x55 || - r[1] != s[1] || - r[2] != cmd || - (rlen > 0 && r[3] != rlen)) { - warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]); - return -EIO; - } - - if (rlen > 0) - memcpy(rbuf, &r[4], rlen); - - 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; - - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) - return -EAGAIN; - - if (num > 2) - 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); - - obuf[0] = (msg[i].addr << 1) | read; - obuf[1] = msg[i].len; - - /* read request */ - if (read) - obuf[2] = msg[i+1].len; - else - obuf[2] = 0; - - 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); - i++; - } - } - - mutex_unlock(&d->i2c_mutex); - return i; -} - -static u32 ttusb2_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm ttusb2_i2c_algo = { - .master_xfer = ttusb2_i2c_xfer, - .functionality = ttusb2_i2c_func, -}; - -/* Callbacks for DVB USB */ -static int ttusb2_identify_state (struct usb_device *udev, struct - dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, - int *cold) -{ - *cold = udev->descriptor.iManufacturer == 0 && udev->descriptor.iProduct == 0; - return 0; -} - -static int ttusb2_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 b = onoff; - ttusb2_msg(d, CMD_POWER, &b, 0, NULL, 0); - return ttusb2_msg(d, CMD_POWER, &b, 1, NULL, 0); -} - - -static struct tda10086_config tda10086_config = { - .demod_address = 0x0e, - .invert = 0, - .diseqc_tone = 1, - .xtal_freq = TDA10086_XTAL_16M, -}; - -static int ttusb2_frontend_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) { - deb_info("TDA10086 attach failed\n"); - return -ENODEV; - } - - return 0; -} - -static int ttusb2_tuner_attach(struct dvb_usb_adapter *adap) -{ - if (dvb_attach(tda826x_attach, adap->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) { - deb_info("LNBP21 attach failed\n"); - return -ENODEV; - } - return 0; -} - -/* DVB USB Driver stuff */ -static struct dvb_usb_device_properties ttusb2_properties; -static struct dvb_usb_device_properties ttusb2_properties_s2400; - -static int ttusb2_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - if (0 == dvb_usb_device_init(intf, &ttusb2_properties, - THIS_MODULE, NULL, adapter_nr) || - 0 == dvb_usb_device_init(intf, &ttusb2_properties_s2400, - THIS_MODULE, NULL, adapter_nr)) - return 0; - return -ENODEV; -} - -static struct usb_device_id ttusb2_table [] = { - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_400E) }, - { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PCTV_450E) }, - { USB_DEVICE(USB_VID_TECHNOTREND, - USB_PID_TECHNOTREND_CONNECT_S2400) }, - {} /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, ttusb2_table); - -static struct dvb_usb_device_properties ttusb2_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-pctv-400e-01.fw", - - .size_of_priv = sizeof(struct ttusb2_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, - - .frontend_attach = ttusb2_frontend_attach, - .tuner_attach = ttusb2_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_ISOC, - .count = 5, - .endpoint = 0x02, - .u = { - .isoc = { - .framesperurb = 4, - .framesize = 940, - .interval = 1, - } - } - } - } - }, - - .power_ctrl = ttusb2_power_ctrl, - .identify_state = ttusb2_identify_state, - - .i2c_algo = &ttusb2_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 2, - .devices = { - { "Pinnacle 400e DVB-S USB2.0", - { &ttusb2_table[0], NULL }, - { NULL }, - }, - { "Pinnacle 450e DVB-S USB2.0", - { &ttusb2_table[1], NULL }, - { NULL }, - }, - } -}; - -static struct dvb_usb_device_properties ttusb2_properties_s2400 = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-tt-s2400-01.fw", - - .size_of_priv = sizeof(struct ttusb2_state), - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = NULL, - - .frontend_attach = ttusb2_frontend_attach, - .tuner_attach = ttusb2_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_ISOC, - .count = 5, - .endpoint = 0x02, - .u = { - .isoc = { - .framesperurb = 4, - .framesize = 940, - .interval = 1, - } - } - } - } - }, - - .power_ctrl = ttusb2_power_ctrl, - .identify_state = ttusb2_identify_state, - - .i2c_algo = &ttusb2_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "Technotrend TT-connect S-2400", - { &ttusb2_table[2], NULL }, - { NULL }, - }, - } -}; - -static struct usb_driver ttusb2_driver = { - .name = "dvb_usb_ttusb2", - .probe = ttusb2_probe, - .disconnect = dvb_usb_device_exit, - .id_table = ttusb2_table, -}; - -/* module stuff */ -static int __init ttusb2_module_init(void) -{ - int result; - if ((result = usb_register(&ttusb2_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit ttusb2_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&ttusb2_driver); -} - -module_init (ttusb2_module_init); -module_exit (ttusb2_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for Pinnacle PCTV 400e DVB-S USB2.0"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/ttusb2.h b/drivers/media/dvb/dvb-usb/ttusb2.h deleted file mode 100644 index 52a63af4089..00000000000 --- a/drivers/media/dvb/dvb-usb/ttusb2.h +++ /dev/null @@ -1,70 +0,0 @@ -/* DVB USB compliant linux driver for Technotrend DVB USB boxes and clones - * (e.g. Pinnacle 400e DVB-S USB2.0). - * - * Copyright (c) 2002 Holger Waechtler <holger@convergence.de> - * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> - * Copyright (C) 2005-6 Patrick Boettcher <pb@linuxtv.de> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_TTUSB2_H_ -#define _DVB_USB_TTUSB2_H_ - -/* TTUSB protocol - * - * always to messages (out/in) - * out message: - * 0xaa <id> <cmdbyte> <datalen> <data...> - * - * in message (complete block is always 0x40 bytes long) - * 0x55 <id> <cmdbyte> <datalen> <data...> - * - * id is incremented for each transaction - */ - -#define CMD_DSP_DOWNLOAD 0x13 -/* out data: <byte>[28] - * last block must be empty */ - -#define CMD_DSP_BOOT 0x14 -/* out data: nothing */ - -#define CMD_POWER 0x15 -/* out data: <on=1/off=0> */ - -#define CMD_LNB 0x16 -/* out data: <power=1> <18V=0,13V=1> <tone> <??=1> <??=1> */ - -#define CMD_GET_VERSION 0x17 -/* in data: <version_byte>[5] */ - -#define CMD_DISEQC 0x18 -/* out data: <master=0xff/burst=??> <cmdlen> <cmdbytes>[cmdlen] */ - -#define CMD_PID_ENABLE 0x22 -/* out data: <index> <type: ts=1/sec=2> <pid msb> <pid lsb> */ - -#define CMD_PID_DISABLE 0x23 -/* out data: <index> */ - -#define CMD_FILTER_ENABLE 0x24 -/* out data: <index> <pid_idx> <filter>[12] <mask>[12] */ - -#define CMD_FILTER_DISABLE 0x25 -/* out data: <index> */ - -#define CMD_GET_DSP_VERSION 0x26 -/* in data: <version_byte>[28] */ - -#define CMD_I2C_XFER 0x31 -/* out data: <addr << 1> <sndlen> <rcvlen> <data>[sndlen] - * in data: <addr << 1> <sndlen> <rcvlen> <data>[rcvlen] */ - -#define CMD_I2C_BITRATE 0x32 -/* out data: <default=0> */ - -#endif diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c deleted file mode 100644 index 118aab1a3e5..00000000000 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ /dev/null @@ -1,168 +0,0 @@ -/* DVB USB framework compliant Linux driver for the HanfTek UMT-010 USB2.0 - * DVB-T receiver. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "dibusb.h" - -#include "mt352.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static int umt_mt352_demod_init(struct dvb_frontend *fe) -{ - static u8 mt352_clock_config[] = { 0x89, 0xb8, 0x2d }; - static u8 mt352_reset[] = { 0x50, 0x80 }; - static u8 mt352_mclk_ratio[] = { 0x8b, 0x00 }; - static u8 mt352_adc_ctl_1_cfg[] = { 0x8E, 0x40 }; - static u8 mt352_agc_cfg[] = { 0x67, 0x10, 0xa0 }; - - static u8 mt352_sec_agc_cfg1[] = { 0x6a, 0xff }; - static u8 mt352_sec_agc_cfg2[] = { 0x6d, 0xff }; - static u8 mt352_sec_agc_cfg3[] = { 0x70, 0x40 }; - static u8 mt352_sec_agc_cfg4[] = { 0x7b, 0x03 }; - static u8 mt352_sec_agc_cfg5[] = { 0x7d, 0x0f }; - - static u8 mt352_acq_ctl[] = { 0x53, 0x50 }; - static u8 mt352_input_freq_1[] = { 0x56, 0x31, 0x06 }; - - mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); - udelay(2000); - mt352_write(fe, mt352_reset, sizeof(mt352_reset)); - mt352_write(fe, mt352_mclk_ratio, sizeof(mt352_mclk_ratio)); - - mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); - mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); - - mt352_write(fe, mt352_sec_agc_cfg1, sizeof(mt352_sec_agc_cfg1)); - mt352_write(fe, mt352_sec_agc_cfg2, sizeof(mt352_sec_agc_cfg2)); - mt352_write(fe, mt352_sec_agc_cfg3, sizeof(mt352_sec_agc_cfg3)); - mt352_write(fe, mt352_sec_agc_cfg4, sizeof(mt352_sec_agc_cfg4)); - mt352_write(fe, mt352_sec_agc_cfg5, sizeof(mt352_sec_agc_cfg5)); - - mt352_write(fe, mt352_acq_ctl, sizeof(mt352_acq_ctl)); - mt352_write(fe, mt352_input_freq_1, sizeof(mt352_input_freq_1)); - - return 0; -} - -static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap) -{ - struct mt352_config umt_config; - - memset(&umt_config,0,sizeof(struct mt352_config)); - 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); - - return 0; -} - -static int umt_tuner_attach (struct dvb_usb_adapter *adap) -{ - dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_TUA6034); - return 0; -} - -/* USB Driver stuff */ -static struct dvb_usb_device_properties umt_properties; - -static int umt_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - if (0 == dvb_usb_device_init(intf, &umt_properties, - THIS_MODULE, NULL, adapter_nr)) - return 0; - return -EINVAL; -} - -/* do not change the order of the ID table */ -static struct usb_device_id umt_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_COLD) }, -/* 01 */ { USB_DEVICE(USB_VID_HANFTEK, USB_PID_HANFTEK_UMT_010_WARM) }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE (usb, umt_table); - -static struct dvb_usb_device_properties umt_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-umt-010-02.fw", - - .num_adapters = 1, - .adapter = { - { - .streaming_ctrl = dibusb2_0_streaming_ctrl, - .frontend_attach = umt_mt352_frontend_attach, - .tuner_attach = umt_tuner_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = MAX_NO_URBS_FOR_DATA_STREAM, - .endpoint = 0x06, - .u = { - .bulk = { - .buffersize = 512, - } - } - }, - - .size_of_priv = sizeof(struct dibusb_state), - } - }, - .power_ctrl = dibusb_power_ctrl, - - .i2c_algo = &dibusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - - .num_device_descs = 1, - .devices = { - { "Hanftek UMT-010 DVB-T USB2.0", - { &umt_table[0], NULL }, - { &umt_table[1], NULL }, - }, - } -}; - -static struct usb_driver umt_driver = { - .name = "dvb_usb_umt_010", - .probe = umt_probe, - .disconnect = dvb_usb_device_exit, - .id_table = umt_table, -}; - -/* module stuff */ -static int __init umt_module_init(void) -{ - int result; - if ((result = usb_register(&umt_driver))) { - err("usb_register failed. Error number %d",result); - return result; - } - - return 0; -} - -static void __exit umt_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&umt_driver); -} - -module_init (umt_module_init); -module_exit (umt_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for HanfTek UMT 010 USB2.0 DVB-T device"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c deleted file mode 100644 index 9da2cc95ca1..00000000000 --- a/drivers/media/dvb/dvb-usb/usb-urb.c +++ /dev/null @@ -1,253 +0,0 @@ -/* usb-urb.c is part of the DVB USB library. - * - * Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de) - * see dvb-usb-init.c for copyright information. - * - * This file keeps functions for initializing and handling the - * BULK and ISOC USB data transfers in a generic way. - * Can be used for DVB-only and also, that's the plan, for - * Hybrid USB devices (analog and DVB). - */ -#include "dvb-usb-common.h" - -/* URB stuff for streaming */ -static void usb_urb_complete(struct urb *urb) -{ - struct usb_data_stream *stream = urb->context; - int ptype = usb_pipetype(urb->pipe); - int i; - u8 *b; - - deb_uxfer("'%s' urb completed. status: %d, length: %d/%d, pack_num: %d, errors: %d\n", - ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", - urb->status,urb->actual_length,urb->transfer_buffer_length, - urb->number_of_packets,urb->error_count); - - switch (urb->status) { - case 0: /* success */ - case -ETIMEDOUT: /* NAK */ - break; - case -ECONNRESET: /* kill */ - case -ENOENT: - case -ESHUTDOWN: - return; - default: /* error */ - deb_ts("urb completition error %d.\n", urb->status); - break; - } - - b = (u8 *) urb->transfer_buffer; - switch (ptype) { - case PIPE_ISOCHRONOUS: - for (i = 0; i < urb->number_of_packets; i++) { - - if (urb->iso_frame_desc[i].status != 0) - deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status); - else if (urb->iso_frame_desc[i].actual_length > 0) - stream->complete(stream, b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); - - urb->iso_frame_desc[i].status = 0; - urb->iso_frame_desc[i].actual_length = 0; - } - debug_dump(b,20,deb_uxfer); - break; - case PIPE_BULK: - if (urb->actual_length > 0) - stream->complete(stream, b, urb->actual_length); - break; - default: - err("unkown endpoint type in completition handler."); - return; - } - usb_submit_urb(urb,GFP_ATOMIC); -} - -int usb_urb_kill(struct usb_data_stream *stream) -{ - int i; - for (i = 0; i < stream->urbs_submitted; i++) { - deb_ts("killing URB no. %d.\n",i); - - /* stop the URB */ - usb_kill_urb(stream->urb_list[i]); - } - stream->urbs_submitted = 0; - return 0; -} - -int usb_urb_submit(struct usb_data_stream *stream) -{ - int i,ret; - for (i = 0; i < stream->urbs_initialized; i++) { - deb_ts("submitting URB no. %d\n",i); - if ((ret = usb_submit_urb(stream->urb_list[i],GFP_ATOMIC))) { - err("could not submit URB no. %d - get them all back",i); - usb_urb_kill(stream); - return ret; - } - stream->urbs_submitted++; - } - return 0; -} - -static int usb_free_stream_buffers(struct usb_data_stream *stream) -{ - if (stream->state & USB_STATE_URB_BUF) { - while (stream->buf_num) { - stream->buf_num--; - deb_mem("freeing buffer %d\n",stream->buf_num); - usb_buffer_free(stream->udev, stream->buf_size, - stream->buf_list[stream->buf_num], stream->dma_addr[stream->buf_num]); - } - } - - stream->state &= ~USB_STATE_URB_BUF; - - return 0; -} - -static int usb_allocate_stream_buffers(struct usb_data_stream *stream, int num, unsigned long size) -{ - stream->buf_num = 0; - stream->buf_size = size; - - deb_mem("all in all I will use %lu bytes for streaming\n",num*size); - - for (stream->buf_num = 0; stream->buf_num < num; stream->buf_num++) { - deb_mem("allocating buffer %d\n",stream->buf_num); - if (( stream->buf_list[stream->buf_num] = - usb_buffer_alloc(stream->udev, size, GFP_ATOMIC, - &stream->dma_addr[stream->buf_num]) ) == NULL) { - deb_mem("not enough memory for urb-buffer allocation.\n"); - usb_free_stream_buffers(stream); - return -ENOMEM; - } - deb_mem("buffer %d: %p (dma: %Lu)\n", - stream->buf_num, -stream->buf_list[stream->buf_num], (long long)stream->dma_addr[stream->buf_num]); - memset(stream->buf_list[stream->buf_num],0,size); - stream->state |= USB_STATE_URB_BUF; - } - deb_mem("allocation successful\n"); - - return 0; -} - -static int usb_bulk_urb_init(struct usb_data_stream *stream) -{ - int i, j; - - if ((i = usb_allocate_stream_buffers(stream,stream->props.count, - stream->props.u.bulk.buffersize)) < 0) - return i; - - /* allocate the URBs */ - for (i = 0; i < stream->props.count; i++) { - stream->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); - 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]); - return -ENOMEM; - } - usb_fill_bulk_urb( stream->urb_list[i], stream->udev, - usb_rcvbulkpipe(stream->udev,stream->props.endpoint), - stream->buf_list[i], - stream->props.u.bulk.buffersize, - usb_urb_complete, stream); - - stream->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; - stream->urb_list[i]->transfer_dma = stream->dma_addr[i]; - stream->urbs_initialized++; - } - return 0; -} - -static int usb_isoc_urb_init(struct usb_data_stream *stream) -{ - int i,j; - - if ((i = usb_allocate_stream_buffers(stream,stream->props.count, - stream->props.u.isoc.framesize*stream->props.u.isoc.framesperurb)) < 0) - return i; - - /* allocate the URBs */ - for (i = 0; i < stream->props.count; i++) { - struct urb *urb; - int frame_offset = 0; - - stream->urb_list[i] = usb_alloc_urb(stream->props.u.isoc.framesperurb, GFP_ATOMIC); - 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]); - return -ENOMEM; - } - - urb = stream->urb_list[i]; - - urb->dev = stream->udev; - urb->context = stream; - urb->complete = usb_urb_complete; - urb->pipe = usb_rcvisocpipe(stream->udev,stream->props.endpoint); - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - urb->interval = stream->props.u.isoc.interval; - urb->number_of_packets = stream->props.u.isoc.framesperurb; - urb->transfer_buffer_length = stream->buf_size; - urb->transfer_buffer = stream->buf_list[i]; - urb->transfer_dma = stream->dma_addr[i]; - - for (j = 0; j < stream->props.u.isoc.framesperurb; j++) { - urb->iso_frame_desc[j].offset = frame_offset; - urb->iso_frame_desc[j].length = stream->props.u.isoc.framesize; - frame_offset += stream->props.u.isoc.framesize; - } - - stream->urbs_initialized++; - } - return 0; -} - -int usb_urb_init(struct usb_data_stream *stream, struct usb_data_stream_properties *props) -{ - if (stream == NULL || props == NULL) - return -EINVAL; - - memcpy(&stream->props, props, sizeof(*props)); - - usb_clear_halt(stream->udev,usb_rcvbulkpipe(stream->udev,stream->props.endpoint)); - - if (stream->complete == NULL) { - err("there is no data callback - this doesn't make sense."); - return -EINVAL; - } - - switch (stream->props.type) { - case USB_BULK: - return usb_bulk_urb_init(stream); - case USB_ISOC: - return usb_isoc_urb_init(stream); - default: - err("unkown URB-type for data transfer."); - return -EINVAL; - } -} - -int usb_urb_exit(struct usb_data_stream *stream) -{ - int i; - - usb_urb_kill(stream); - - for (i = 0; i < stream->urbs_initialized; i++) { - if (stream->urb_list[i] != NULL) { - deb_mem("freeing URB no. %d.\n",i); - /* free the URBs */ - usb_free_urb(stream->urb_list[i]); - } - } - stream->urbs_initialized = 0; - - usb_free_stream_buffers(stream); - return 0; -} diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c deleted file mode 100644 index ccc7e445266..00000000000 --- a/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ /dev/null @@ -1,349 +0,0 @@ -/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0 - * DVB-S receiver. - * - * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de> - * Metzler Brothers Systementwicklung GbR - * - * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> - * - * Thanks to Twinhan who kindly provided hardware and information. - * - * This file can be removed soon, after the DST-driver is rewritten to provice - * the frontend-controlling separately. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - * - */ -#include "vp702x.h" - -struct vp702x_fe_state { - struct dvb_frontend fe; - struct dvb_usb_device *d; - - struct dvb_frontend_ops ops; - - fe_sec_voltage_t voltage; - fe_sec_tone_mode_t tone_mode; - - u8 lnb_buf[8]; - - u8 lock; - u8 sig; - u8 snr; - - unsigned long next_status_check; - unsigned long status_check_interval; -}; - -static int vp702x_fe_refresh_state(struct vp702x_fe_state *st) -{ - u8 buf[10]; - if (time_after(jiffies,st->next_status_check)) { - vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10); - - st->lock = buf[4]; - vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1); - vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1); - - st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; - } - return 0; -} - -static u8 vp702x_chksum(u8 *buf,int f, int count) -{ - u8 s = 0; - int i; - for (i = f; i < f+count; i++) - s += buf[i]; - return ~s+1; -} - -static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); - deb_fe("%s\n",__func__); - - if (st->lock == 0) - *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; - else - *status = 0; - - if (*status & FE_HAS_LOCK) - st->status_check_interval = 1000; - else - st->status_check_interval = 250; - return 0; -} - -/* not supported by this Frontend */ -static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); - *ber = 0; - return 0; -} - -/* not supported by this Frontend */ -static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); - *unc = 0; - return 0; -} - -static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); - - *strength = (st->sig << 8) | st->sig; - return 0; -} - -static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - u8 _snr; - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); - - _snr = (st->snr & 0x1f) * 0xff / 0x1f; - *snr = (_snr << 8) | _snr; - return 0; -} - -static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - deb_fe("%s\n",__func__); - tune->min_delay_ms = 2000; - return 0; -} - -static int vp702x_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - u32 freq = fep->frequency/1000; - /*CalFrequency*/ -/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */ - u64 sr; - u8 cmd[8] = { 0 },ibuf[10]; - - cmd[0] = (freq >> 8) & 0x7f; - cmd[1] = freq & 0xff; - cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */ - - sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20; - do_div(sr,88000); - cmd[3] = (sr >> 12) & 0xff; - cmd[4] = (sr >> 4) & 0xff; - cmd[5] = (sr << 4) & 0xf0; - - deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %lu (%lx)\n", - fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, - (unsigned long) sr, (unsigned long) sr); - -/* if (fep->inversion == INVERSION_ON) - cmd[6] |= 0x80; */ - - if (st->voltage == SEC_VOLTAGE_18) - cmd[6] |= 0x40; - -/* if (fep->u.qpsk.symbol_rate > 8000000) - cmd[6] |= 0x20; - - if (fep->frequency < 1531000) - cmd[6] |= 0x04; - - if (st->tone_mode == SEC_TONE_ON) - cmd[6] |= 0x01;*/ - - cmd[7] = vp702x_chksum(cmd,0,7); - - st->status_check_interval = 250; - st->next_status_check = jiffies; - - vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); - - if (ibuf[2] == 0 && ibuf[3] == 0) - deb_fe("tuning failed.\n"); - else - deb_fe("tuning succeeded.\n"); - - return 0; -} - -static int vp702x_fe_init(struct dvb_frontend *fe) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - deb_fe("%s\n",__func__); - vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0); - return 0; -} - -static int vp702x_fe_sleep(struct dvb_frontend *fe) -{ - deb_fe("%s\n",__func__); - return 0; -} - -static int vp702x_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - deb_fe("%s\n",__func__); - return 0; -} - -static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - u8 cmd[8],ibuf[10]; - memset(cmd,0,8); - - deb_fe("%s\n",__func__); - - if (m->msg_len > 4) - return -EINVAL; - - cmd[1] = SET_DISEQC_CMD; - cmd[2] = m->msg_len; - memcpy(&cmd[3], m->msg, m->msg_len); - cmd[7] = vp702x_chksum(cmd,0,7); - - vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); - - if (ibuf[2] == 0 && ibuf[3] == 0) - deb_fe("diseqc cmd failed.\n"); - else - deb_fe("diseqc cmd succeeded.\n"); - - return 0; -} - -static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - deb_fe("%s\n",__func__); - return 0; -} - -static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - u8 ibuf[10]; - deb_fe("%s\n",__func__); - - st->tone_mode = tone; - - if (tone == SEC_TONE_ON) - st->lnb_buf[2] = 0x02; - else - st->lnb_buf[2] = 0x00; - - st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); - - vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); - if (ibuf[2] == 0 && ibuf[3] == 0) - deb_fe("set_tone cmd failed.\n"); - else - deb_fe("set_tone cmd succeeded.\n"); - - return 0; -} - -static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t - voltage) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - u8 ibuf[10]; - deb_fe("%s\n",__func__); - - st->voltage = voltage; - - if (voltage != SEC_VOLTAGE_OFF) - st->lnb_buf[4] = 0x01; - else - st->lnb_buf[4] = 0x00; - - st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); - - vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); - if (ibuf[2] == 0 && ibuf[3] == 0) - deb_fe("set_voltage cmd failed.\n"); - else - deb_fe("set_voltage cmd succeeded.\n"); - - return 0; -} - -static void vp702x_fe_release(struct dvb_frontend* fe) -{ - struct vp702x_fe_state *st = fe->demodulator_priv; - kfree(st); -} - -static struct dvb_frontend_ops vp702x_fe_ops; - -struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) -{ - struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL); - if (s == NULL) - goto error; - - s->d = d; - - memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; - - s->lnb_buf[1] = SET_LNB_POWER; - s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ - - return &s->fe; -error: - return NULL; -} - - -static struct dvb_frontend_ops vp702x_fe_ops = { - .info = { - .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1000, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO - }, - .release = vp702x_fe_release, - - .init = vp702x_fe_init, - .sleep = vp702x_fe_sleep, - - .set_frontend = vp702x_fe_set_frontend, - .get_frontend = vp702x_fe_get_frontend, - .get_tune_settings = vp702x_fe_get_tune_settings, - - .read_status = vp702x_fe_read_status, - .read_ber = vp702x_fe_read_ber, - .read_signal_strength = vp702x_fe_read_signal_strength, - .read_snr = vp702x_fe_read_snr, - .read_ucblocks = vp702x_fe_read_unc_blocks, - - .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg, - .diseqc_send_burst = vp702x_fe_send_diseqc_burst, - .set_tone = vp702x_fe_set_tone, - .set_voltage = vp702x_fe_set_voltage, -}; diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c deleted file mode 100644 index 986fff9a5ba..00000000000 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ /dev/null @@ -1,337 +0,0 @@ -/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S - * receiver. - * - * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de> - * Metzler Brothers Systementwicklung GbR - * - * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> - * - * Thanks to Twinhan who kindly provided hardware and information. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "vp702x.h" - -/* debug */ -int dvb_usb_vp702x_debug; -module_param_named(debug,dvb_usb_vp702x_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct vp702x_state { - int pid_filter_count; - int pid_filter_can_bypass; - u8 pid_filter_state; -}; - -struct vp702x_device_state { - u8 power_state; -}; - -/* check for mutex FIXME */ -int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) -{ - int ret = -1; - - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_IN, - value,index,b,blen, - 2000); - - if (ret < 0) { - warn("usb in operation failed. (%d)", ret); - ret = -EIO; - } else - ret = 0; - - - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); - - return ret; -} - -static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, - u16 index, u8 *b, int blen) -{ - int ret; - deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); - - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 2000)) != blen) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } else - return 0; -} - -int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec) -{ - int ret; - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen); - msleep(msec); - ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); - - mutex_unlock(&d->usb_mutex); - - return ret; -} - -static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, - int olen, u8 *i, int ilen, int msec) -{ - u8 bout[olen+2]; - u8 bin[ilen+1]; - int ret = 0; - - bout[0] = 0x00; - bout[1] = cmd; - memcpy(&bout[2],o,olen); - - ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec); - - if (ret == 0) - memcpy(i,&bin[1],ilen); - - return ret; -} - -static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass) -{ - u8 buf[16] = { 0 }; - return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16); -} - -static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state) -{ - u8 buf[16] = { 0 }; - return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16); -} - -static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff) -{ - struct vp702x_state *st = adap->priv; - u8 buf[16] = { 0 }; - - if (onoff) - st->pid_filter_state |= (1 << id); - else { - st->pid_filter_state &= ~(1 << id); - pid = 0xffff; - } - - id = 0x10 + id*2; - - vp702x_set_pld_state(adap, st->pid_filter_state); - vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16); - vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16); - return 0; -} - - -static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap) -{ - struct vp702x_state *st = adap->priv; - int i; - u8 b[10] = { 0 }; - - st->pid_filter_count = 8; - st->pid_filter_can_bypass = 1; - st->pid_filter_state = 0x00; - - vp702x_set_pld_mode(adap, 1); // bypass - - for (i = 0; i < st->pid_filter_count; i++) - vp702x_set_pid(adap, 0xffff, i, 1); - - vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10); - vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10); - vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10); - - //vp702x_set_pld_mode(d, 0); // filter - return 0; -} - -static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - return 0; -} - -/* keys for the enclosed remote control */ -static struct dvb_usb_rc_key vp702x_rc_keys[] = { - { 0x00, 0x01, KEY_1 }, - { 0x00, 0x02, KEY_2 }, -}; - -/* remote control stuff (does not work with my box) */ -static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key[10]; - int i; - -/* remove the following return to enabled remote querying */ - return 0; - - vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); - - deb_rc("remote query key: %x %d\n",key[1],key[1]); - - if (key[1] == 0x44) { - *state = REMOTE_NO_KEY_PRESSED; - return 0; - } - - for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++) - if (vp702x_rc_keys[i].custom == key[1]) { - *state = REMOTE_KEY_PRESSED; - *event = vp702x_rc_keys[i].event; - break; - } - return 0; -} - - -static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) -{ - u8 i; - for (i = 6; i < 12; i++) - vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1); - return 0; -} - -static int vp702x_frontend_attach(struct dvb_usb_adapter *adap) -{ - u8 buf[10] = { 0 }; - - vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0); - - if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10)) - return -EIO; - - buf[9] = '\0'; - info("system string: %s",&buf[1]); - - vp702x_init_pid_filter(adap); - - adap->fe = vp702x_fe_attach(adap->dev); - vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0); - - return 0; -} - -static struct dvb_usb_device_properties vp702x_properties; - -static int vp702x_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &vp702x_properties, - THIS_MODULE, NULL, adapter_nr); -} - -static struct usb_device_id vp702x_usb_table [] = { - { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) }, -// { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) }, -// { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) }, - { 0 }, -}; -MODULE_DEVICE_TABLE(usb, vp702x_usb_table); - -static struct dvb_usb_device_properties vp702x_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-vp702x-02.fw", - .no_reconnect = 1, - - .size_of_priv = sizeof(struct vp702x_device_state), - - .num_adapters = 1, - .adapter = { - { - .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, - - .streaming_ctrl = vp702x_streaming_ctrl, - .frontend_attach = vp702x_frontend_attach, - - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 10, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - .size_of_priv = sizeof(struct vp702x_state), - } - }, - .read_mac_address = vp702x_read_mac_addr, - - .rc_key_map = vp702x_rc_keys, - .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys), - .rc_interval = 400, - .rc_query = vp702x_rc_query, - - .num_device_descs = 1, - .devices = { - { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)", - .cold_ids = { &vp702x_usb_table[0], NULL }, - .warm_ids = { NULL }, - }, -/* { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)", - .cold_ids = { &vp702x_usb_table[2], NULL }, - .warm_ids = { &vp702x_usb_table[3], NULL }, - }, -*/ { NULL }, - } -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver vp702x_usb_driver = { - .name = "dvb_usb_vp702x", - .probe = vp702x_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = vp702x_usb_table, -}; - -/* module stuff */ -static int __init vp702x_usb_module_init(void) -{ - int result; - if ((result = usb_register(&vp702x_usb_driver))) { - err("usb_register failed. (%d)",result); - return result; - } - - return 0; -} - -static void __exit vp702x_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&vp702x_usb_driver); -} - -module_init(vp702x_usb_module_init); -module_exit(vp702x_usb_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h deleted file mode 100644 index c2f97f96c21..00000000000 --- a/drivers/media/dvb/dvb-usb/vp702x.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef _DVB_USB_VP7021_H_ -#define _DVB_USB_VP7021_H_ - -#define DVB_USB_LOG_PREFIX "vp702x" -#include "dvb-usb.h" - -extern int dvb_usb_vp702x_debug; -#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args) -#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args) - -/* commands are read and written with USB control messages */ - -/* consecutive read/write operation */ -#define REQUEST_OUT 0xB2 -#define REQUEST_IN 0xB3 - -/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 - * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer - * the returning buffer looks as follows - * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ - -#define GET_TUNER_STATUS 0x05 -/* additional in buffer: - * 0 1 2 3 4 5 6 7 8 - * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ - -#define GET_SYSTEM_STRING 0x06 -/* additional in buffer: - * 0 1 2 3 4 5 6 7 8 - * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ - -#define SET_DISEQC_CMD 0x08 -/* additional out buffer: - * 0 1 2 3 4 - * len X1 X2 X3 X4 - * additional in buffer: - * 0 1 2 - * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */ - -#define SET_LNB_POWER 0x09 -/* additional out buffer: - * 0 1 2 - * 0x00 0xff 1 = on, 0 = off - * additional in buffer: - * 0 1 2 - * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */ - -#define GET_MAC_ADDRESS 0x0A -/* #define GET_MAC_ADDRESS 0x0B */ -/* additional in buffer: - * 0 1 2 3 4 5 6 7 8 - * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ - -#define SET_PID_FILTER 0x11 -/* additional in buffer: - * 0 1 ... 14 15 16 - * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ - -/* request: 0xB2; i: 0; v: 0; - * b[0] != 0 -> tune and lock a channel - * 0 1 2 3 4 5 6 7 - * freq0 freq1 divstep srate0 srate1 srate2 flag chksum - */ - -/* one direction requests */ -#define READ_REMOTE_REQ 0xB4 -/* IN i: 0; v: 0; b[0] == request, b[1] == key */ - -#define READ_PID_NUMBER_REQ 0xB5 -/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ - -#define WRITE_EEPROM_REQ 0xB6 -/* OUT i: offset; v: value to write; no extra buffer */ - -#define READ_EEPROM_REQ 0xB7 -/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ - -#define READ_STATUS 0xB8 -/* IN i: 0; v: 0; bufferlen 10 */ - -#define READ_TUNER_REG_REQ 0xB9 -/* IN i: 0; v: register; b[0] = value */ - -#define READ_FX2_REG_REQ 0xBA -/* IN i: offset; v: 0; b[0] = value */ - -#define WRITE_FX2_REG_REQ 0xBB -/* OUT i: offset; v: value to write; 1 byte extra buffer */ - -#define SET_TUNER_POWER_REQ 0xBC -/* IN i: 0 = power off, 1 = power on */ - -#define WRITE_TUNER_REG_REQ 0xBD -/* IN i: register, v: value to write, no extra buffer */ - -#define RESET_TUNER 0xBE -/* IN i: 0, v: 0, no extra buffer */ - -extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); - -extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); -extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); - -#endif diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c deleted file mode 100644 index 8452eef9032..00000000000 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ /dev/null @@ -1,192 +0,0 @@ -/* DVB frontend part of the Linux driver for TwinhanDTV Alpha/MagicBoxII USB2.0 - * DVB-T receiver. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * Thanks to Twinhan who kindly provided hardware and information. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - * - */ -#include "vp7045.h" - -/* It is a Zarlink MT352 within a Samsung Tuner (DNOS404ZH102A) - 040929 - AAT - * - * Programming is hidden inside the firmware, so set_frontend is very easy. - * Even though there is a Firmware command that one can use to access the demod - * via its registers. This is used for status information. - */ - -struct vp7045_fe_state { - struct dvb_frontend fe; - struct dvb_usb_device *d; -}; - -static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - u8 s0 = vp7045_read_reg(state->d,0x00), - s1 = vp7045_read_reg(state->d,0x01), - s3 = vp7045_read_reg(state->d,0x03); - - *status = 0; - if (s0 & (1 << 4)) - *status |= FE_HAS_CARRIER; - if (s0 & (1 << 1)) - *status |= FE_HAS_VITERBI; - if (s0 & (1 << 5)) - *status |= FE_HAS_LOCK; - if (s1 & (1 << 1)) - *status |= FE_HAS_SYNC; - if (s3 & (1 << 6)) - *status |= FE_HAS_SIGNAL; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int vp7045_fe_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - *ber = (vp7045_read_reg(state->d, 0x0D) << 16) | - (vp7045_read_reg(state->d, 0x0E) << 8) | - vp7045_read_reg(state->d, 0x0F); - return 0; -} - -static int vp7045_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - *unc = (vp7045_read_reg(state->d, 0x10) << 8) | - vp7045_read_reg(state->d, 0x11); - return 0; -} - -static int vp7045_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - u16 signal = (vp7045_read_reg(state->d, 0x14) << 8) | - vp7045_read_reg(state->d, 0x15); - - *strength = ~signal; - return 0; -} - -static int vp7045_fe_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - u8 _snr = vp7045_read_reg(state->d, 0x09); - *snr = (_snr << 8) | _snr; - return 0; -} - -static int vp7045_fe_init(struct dvb_frontend* fe) -{ - return 0; -} - -static int vp7045_fe_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int vp7045_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 800; - return 0; -} - -static int vp7045_fe_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - u8 buf[5]; - u32 freq = fep->frequency / 1000; - - buf[0] = (freq >> 16) & 0xff; - buf[1] = (freq >> 8) & 0xff; - buf[2] = freq & 0xff; - buf[3] = 0; - - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: buf[4] = 8; break; - case BANDWIDTH_7_MHZ: buf[4] = 7; break; - case BANDWIDTH_6_MHZ: buf[4] = 6; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: - return -EINVAL; - } - - vp7045_usb_op(state->d,LOCK_TUNER_COMMAND,buf,5,NULL,0,200); - return 0; -} - -static int vp7045_fe_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - return 0; -} - -static void vp7045_fe_release(struct dvb_frontend* fe) -{ - struct vp7045_fe_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops vp7045_fe_ops; - -struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) -{ - struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL); - if (s == NULL) - goto error; - - s->d = d; - memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); - s->fe.demodulator_priv = s; - - return &s->fe; -error: - return NULL; -} - - -static struct dvb_frontend_ops vp7045_fe_ops = { - .info = { - .name = "Twinhan VP7045/46 USB DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 1000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = vp7045_fe_release, - - .init = vp7045_fe_init, - .sleep = vp7045_fe_sleep, - - .set_frontend = vp7045_fe_set_frontend, - .get_frontend = vp7045_fe_get_frontend, - .get_tune_settings = vp7045_fe_get_tune_settings, - - .read_status = vp7045_fe_read_status, - .read_ber = vp7045_fe_read_ber, - .read_signal_strength = vp7045_fe_read_signal_strength, - .read_snr = vp7045_fe_read_snr, - .read_ucblocks = vp7045_fe_read_unc_blocks, -}; diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c deleted file mode 100644 index acb345504e0..00000000000 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ /dev/null @@ -1,313 +0,0 @@ -/* DVB USB compliant Linux driver for the - * - TwinhanDTV Alpha/MagicBoxII USB2.0 DVB-T receiver - * - DigitalNow TinyUSB2 DVB-t receiver - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * Thanks to Twinhan who kindly provided hardware and information. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#include "vp7045.h" - -/* debug */ -static int dvb_usb_vp7045_debug; -module_param_named(debug,dvb_usb_vp7045_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define deb_info(args...) dprintk(dvb_usb_vp7045_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_vp7045_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_vp7045_debug,0x04,args) - -int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec) -{ - int ret = 0; - u8 inbuf[12] = { 0 }, outbuf[20] = { 0 }; - - outbuf[0] = cmd; - - if (outlen > 19) - outlen = 19; - - if (inlen > 11) - inlen = 11; - - if (out != NULL && outlen > 0) - memcpy(&outbuf[1], out, outlen); - - deb_xfer("out buffer: "); - debug_dump(outbuf,outlen+1,deb_xfer); - - if ((ret = mutex_lock_interruptible(&d->usb_mutex))) - return ret; - - if (usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, - outbuf, 20, 2000) != 20) { - err("USB control message 'out' went wrong."); - ret = -EIO; - goto unlock; - } - - msleep(msec); - - if (usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev,0), - TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, - inbuf, 12, 2000) != 12) { - err("USB control message 'in' went wrong."); - ret = -EIO; - goto unlock; - } - - deb_xfer("in buffer: "); - debug_dump(inbuf,12,deb_xfer); - - if (in != NULL && inlen > 0) - memcpy(in,&inbuf[1],inlen); - -unlock: - mutex_unlock(&d->usb_mutex); - - return ret; -} - -u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg) -{ - u8 obuf[2] = { 0 },v; - obuf[1] = reg; - - vp7045_usb_op(d,TUNER_REG_READ,obuf,2,&v,1,30); - - return v; -} - -static int vp7045_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 v = onoff; - return vp7045_usb_op(d,SET_TUNER_POWER,&v,1,NULL,0,150); -} - -/* remote control stuff */ - -/* The keymapping struct. Somehow this should be loaded to the driver, but - * currently it is hardcoded. */ -static struct dvb_usb_rc_key vp7045_rc_keys[] = { - { 0x00, 0x16, KEY_POWER }, - { 0x00, 0x10, KEY_MUTE }, - { 0x00, 0x03, KEY_1 }, - { 0x00, 0x01, KEY_2 }, - { 0x00, 0x06, KEY_3 }, - { 0x00, 0x09, KEY_4 }, - { 0x00, 0x1d, KEY_5 }, - { 0x00, 0x1f, KEY_6 }, - { 0x00, 0x0d, KEY_7 }, - { 0x00, 0x19, KEY_8 }, - { 0x00, 0x1b, KEY_9 }, - { 0x00, 0x15, KEY_0 }, - { 0x00, 0x05, KEY_CHANNELUP }, - { 0x00, 0x02, KEY_CHANNELDOWN }, - { 0x00, 0x1e, KEY_VOLUMEUP }, - { 0x00, 0x0a, KEY_VOLUMEDOWN }, - { 0x00, 0x11, KEY_RECORD }, - { 0x00, 0x17, KEY_FAVORITES }, /* Heart symbol - Channel list. */ - { 0x00, 0x14, KEY_PLAY }, - { 0x00, 0x1a, KEY_STOP }, - { 0x00, 0x40, KEY_REWIND }, - { 0x00, 0x12, KEY_FASTFORWARD }, - { 0x00, 0x0e, KEY_PREVIOUS }, /* Recall - Previous channel. */ - { 0x00, 0x4c, KEY_PAUSE }, - { 0x00, 0x4d, KEY_SCREEN }, /* Full screen mode. */ - { 0x00, 0x54, KEY_AUDIO }, /* MTS - Switch to secondary audio. */ - { 0x00, 0x0c, KEY_CANCEL }, /* Cancel */ - { 0x00, 0x1c, KEY_EPG }, /* EPG */ - { 0x00, 0x00, KEY_TAB }, /* Tab */ - { 0x00, 0x48, KEY_INFO }, /* Preview */ - { 0x00, 0x04, KEY_LIST }, /* RecordList */ - { 0x00, 0x0f, KEY_TEXT }, /* Teletext */ - { 0x00, 0x41, KEY_PREVIOUSSONG }, - { 0x00, 0x42, KEY_NEXTSONG }, - { 0x00, 0x4b, KEY_UP }, - { 0x00, 0x51, KEY_DOWN }, - { 0x00, 0x4e, KEY_LEFT }, - { 0x00, 0x52, KEY_RIGHT }, - { 0x00, 0x4f, KEY_ENTER }, - { 0x00, 0x13, KEY_CANCEL }, - { 0x00, 0x4a, KEY_CLEAR }, - { 0x00, 0x54, KEY_PRINT }, /* Capture */ - { 0x00, 0x43, KEY_SUBTITLE }, /* Subtitle/CC */ - { 0x00, 0x08, KEY_VIDEO }, /* A/V */ - { 0x00, 0x07, KEY_SLEEP }, /* Hibernate */ - { 0x00, 0x45, KEY_ZOOM }, /* Zoom+ */ - { 0x00, 0x18, KEY_RED}, - { 0x00, 0x53, KEY_GREEN}, - { 0x00, 0x5e, KEY_YELLOW}, - { 0x00, 0x5f, KEY_BLUE} -}; - -static int vp7045_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - u8 key; - int i; - vp7045_usb_op(d,RC_VAL_READ,NULL,0,&key,1,20); - - deb_rc("remote query key: %x %d\n",key,key); - - if (key == 0x44) { - *state = REMOTE_NO_KEY_PRESSED; - return 0; - } - - for (i = 0; i < ARRAY_SIZE(vp7045_rc_keys); i++) - if (vp7045_rc_keys[i].data == key) { - *state = REMOTE_KEY_PRESSED; - *event = vp7045_rc_keys[i].event; - break; - } - return 0; -} - -static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int offset) -{ - int i = 0; - u8 v,br[2]; - for (i=0; i < len; i++) { - v = offset + i; - vp7045_usb_op(d,GET_EE_VALUE,&v,1,br,2,5); - buf[i] = br[1]; - } - deb_info("VP7045 EEPROM read (offs: %d, len: %d) : ",offset, i); - debug_dump(buf,i,deb_info); - return 0; -} - -static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) -{ - return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR); -} - -static int vp7045_frontend_attach(struct dvb_usb_adapter *adap) -{ - u8 buf[255] = { 0 }; - - vp7045_usb_op(adap->dev,VENDOR_STRING_READ,NULL,0,buf,20,0); - buf[10] = '\0'; - deb_info("firmware says: %s ",buf); - - vp7045_usb_op(adap->dev,PRODUCT_STRING_READ,NULL,0,buf,20,0); - buf[10] = '\0'; - deb_info("%s ",buf); - - vp7045_usb_op(adap->dev,FW_VERSION_READ,NULL,0,buf,20,0); - buf[10] = '\0'; - deb_info("v%s\n",buf); - -/* Dump the EEPROM */ -/* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */ - - adap->fe = vp7045_fe_attach(adap->dev); - - return 0; -} - -static struct dvb_usb_device_properties vp7045_properties; - -static int vp7045_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - return dvb_usb_device_init(intf, &vp7045_properties, - THIS_MODULE, NULL, adapter_nr); -} - -static struct usb_device_id vp7045_usb_table [] = { - { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_COLD) }, - { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7045_WARM) }, - { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_COLD) }, - { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_DNTV_TINYUSB2_WARM) }, - { 0 }, -}; -MODULE_DEVICE_TABLE(usb, vp7045_usb_table); - -static struct dvb_usb_device_properties vp7045_properties = { - .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-vp7045-01.fw", - - .num_adapters = 1, - .adapter = { - { - .frontend_attach = vp7045_frontend_attach, - /* parameter for the MPEG2-data transfer */ - .stream = { - .type = USB_BULK, - .count = 7, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 4096, - } - } - }, - } - }, - .power_ctrl = vp7045_power_ctrl, - .read_mac_address = vp7045_read_mac_addr, - - .rc_interval = 400, - .rc_key_map = vp7045_rc_keys, - .rc_key_map_size = ARRAY_SIZE(vp7045_rc_keys), - .rc_query = vp7045_rc_query, - - .num_device_descs = 2, - .devices = { - { .name = "Twinhan USB2.0 DVB-T receiver (TwinhanDTV Alpha/MagicBox II)", - .cold_ids = { &vp7045_usb_table[0], NULL }, - .warm_ids = { &vp7045_usb_table[1], NULL }, - }, - { .name = "DigitalNow TinyUSB 2 DVB-t Receiver", - .cold_ids = { &vp7045_usb_table[2], NULL }, - .warm_ids = { &vp7045_usb_table[3], NULL }, - }, - { NULL }, - } -}; - -/* usb specific object needed to register this driver with the usb subsystem */ -static struct usb_driver vp7045_usb_driver = { - .name = "dvb_usb_vp7045", - .probe = vp7045_usb_probe, - .disconnect = dvb_usb_device_exit, - .id_table = vp7045_usb_table, -}; - -/* module stuff */ -static int __init vp7045_usb_module_init(void) -{ - int result; - if ((result = usb_register(&vp7045_usb_driver))) { - err("usb_register failed. (%d)",result); - return result; - } - - return 0; -} - -static void __exit vp7045_usb_module_exit(void) -{ - /* deregister this driver from the USB subsystem */ - usb_deregister(&vp7045_usb_driver); -} - -module_init(vp7045_usb_module_init); -module_exit(vp7045_usb_module_exit); - -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_DESCRIPTION("Driver for Twinhan MagicBox/Alpha and DNTV tinyUSB2 DVB-T USB2.0"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h deleted file mode 100644 index 969688f8526..00000000000 --- a/drivers/media/dvb/dvb-usb/vp7045.h +++ /dev/null @@ -1,73 +0,0 @@ -/* Common header-file of the Linux driver for the TwinhanDTV Alpha/MagicBoxII - * USB2.0 DVB-T receiver. - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * Thanks to Twinhan who kindly provided hardware and information. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 2. - * - * see Documentation/dvb/README.dvb-usb for more information - */ -#ifndef _DVB_USB_VP7045_H_ -#define _DVB_USB_VP7045_H_ - -#define DVB_USB_LOG_PREFIX "vp7045" -#include "dvb-usb.h" - -/* vp7045 commands */ - -/* Twinhan Vendor requests */ -#define TH_COMMAND_IN 0xC0 -#define TH_COMMAND_OUT 0xC1 - -/* command bytes */ -#define TUNER_REG_READ 0x03 -#define TUNER_REG_WRITE 0x04 - -#define RC_VAL_READ 0x05 - #define RC_NO_KEY 0x44 - -#define SET_TUNER_POWER 0x06 -#define CHECK_TUNER_POWER 0x12 - #define Tuner_Power_ON 1 - #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 - -#define TUNER_SIGNAL_READ 0x0A - -/* FX2 eeprom */ -#define SET_EE_VALUE 0x10 -#define GET_EE_VALUE 0x11 - #define FX2_ID_ADDR 0x00 - #define VID_MSB_ADDR 0x02 - #define VID_LSB_ADDR 0x01 - #define PID_MSB_ADDR 0x04 - #define PID_LSB_ADDR 0x03 - #define MAC_0_ADDR 0x07 - #define MAC_1_ADDR 0x08 - #define MAC_2_ADDR 0x09 - #define MAC_3_ADDR 0x0a - #define MAC_4_ADDR 0x0b - #define MAC_5_ADDR 0x0c - -#define RESET_FX2 0x13 - -#define FW_VERSION_READ 0x0B -#define VENDOR_STRING_READ 0x0C -#define PRODUCT_STRING_READ 0x0D -#define FW_BCD_VERSION_READ 0x14 - -extern struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d); -extern int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen,int msec); -extern u8 vp7045_read_reg(struct dvb_usb_device *d, u8 reg); - -#endif diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig deleted file mode 100644 index 00269560793..00000000000 --- a/drivers/media/dvb/frontends/Kconfig +++ /dev/null @@ -1,488 +0,0 @@ -menu "Customise DVB Frontends" - depends on DVB_CORE - -config DVB_FE_CUSTOMISE - bool "Customise the frontend modules to build" - default N - help - This allows the user to deselect frontend drivers unnecessary - for their hardware from the build. Use this option with care - as deselecting frontends which are in fact necessary will result - in DVB devices which cannot be tuned due to lack of driver support. - - If unsure say N. - -comment "Multistandard (satellite) frontends" - depends on DVB_CORE - -config DVB_STB0899 - tristate "STB0899 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want - to support this demodulator based frontends - -config DVB_STB6100 - tristate "STB6100 based tuners" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A Silicon tuner from ST used in conjunction with the STB0899 - demodulator. Say Y when you want to support this tuner. - -comment "DVB-S (satellite) frontends" - depends on DVB_CORE - -config DVB_CX24110 - tristate "Conexant CX24110 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_CX24123 - tristate "Conexant CX24123 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_MT312 - tristate "Zarlink VP310/MT312/ZL10313 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_S5H1420 - tristate "Samsung S5H1420 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_STV0288 - tristate "ST STV0288 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_STB6000 - tristate "ST STB6000 silicon tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S silicon tuner module. Say Y when you want to support this tuner. - -config DVB_STV0299 - tristate "ST STV0299 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TDA8083 - tristate "Philips TDA8083 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TDA10086 - tristate "Philips TDA10086 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TDA8261 - tristate "Philips TDA8261 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_VES1X93 - tristate "VLSI VES1893 or VES1993 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TUNER_ITD1000 - tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -config DVB_TUNER_CX24113 - tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - - -config DVB_TDA826X - tristate "Philips TDA826X silicon tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S silicon tuner module. Say Y when you want to support this tuner. - -config DVB_TUA6100 - tristate "Infineon TUA6100 PLL" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S PLL chip. - -config DVB_CX24116 - tristate "Conexant CX24116 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S/S2 tuner module. Say Y when you want to support this frontend. - -config DVB_SI21XX - tristate "Silicon Labs SI21XX based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - -comment "DVB-T (terrestrial) frontends" - depends on DVB_CORE - -config DVB_SP8870 - tristate "Spase sp8870 based" - 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. - - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_SP887X - tristate "Spase sp887x based" - 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. - - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_CX22700 - tristate "Conexant CX22700 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_CX22702 - tristate "Conexant cx22702 demodulator (OFDM)" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_DRX397XD - tristate "Micronas DRX3975D/DRX3977D based" - 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. - - TODO: - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_L64781 - tristate "LSI L64781" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_TDA1004X - tristate "Philips TDA10045H/TDA10046H based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", - "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_NXT6000 - tristate "NxtWave Communications NXT6000 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_MT352 - tristate "Zarlink MT352 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_ZL10353 - tristate "Zarlink ZL10353 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Say Y when you want to support this frontend. - -config DVB_DIB3000MB - tristate "DiBcom 3000M-B" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_DIB3000MC - tristate "DiBcom 3000P/M-C" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_DIB7000M - tristate "DiBcom 7000MA/MB/PA/PB/MC" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_DIB7000P - tristate "DiBcom 7000PC" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-T tuner module. Designed for mobile usage. Say Y when you want - to support this frontend. - -config DVB_TDA10048 - tristate "Philips TDA10048HN based" - 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 "DVB-C (cable) frontends" - depends on DVB_CORE - -config DVB_VES1820 - tristate "VLSI VES1820 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -config DVB_TDA10021 - tristate "Philips TDA10021 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -config DVB_TDA10023 - tristate "Philips TDA10023 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -config DVB_STV0297 - tristate "ST STV0297 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DVB-C tuner module. Say Y when you want to support this frontend. - -comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" - depends on DVB_CORE - -config DVB_NXT200X - tristate "NxtWave Communications NXT2002/NXT2004 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and - "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_OR51211 - tristate "Oren OR51211 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB tuner module. Say Y when you want to support this frontend. - - This driver needs external firmware. Please use the command - "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to - download it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - -config DVB_OR51132 - tristate "Oren OR51132 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or - "<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to - download firmwares for 8VSB and QAM64/256, respectively. Copy them to - /usr/lib/hotplug/firmware or /lib/firmware (depending on - configuration of firmware hotplug). - -config DVB_BCM3510 - tristate "Broadcom BCM3510" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to - support this frontend. - -config DVB_LGDT330X - tristate "LG Electronics LGDT3302/LGDT3303 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - -config DVB_LGDT3304 - tristate "LG Electronics LGDT3304" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - -config DVB_S5H1409 - tristate "Samsung S5H1409 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - -config DVB_AU8522 - tristate "Auvitek AU8522 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - -config DVB_S5H1411 - tristate "Samsung S5H1411 based" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want - to support this frontend. - -comment "ISDB-T (terrestrial) frontends" - depends on DVB_CORE - -config DVB_S921 - tristate "Sharp S921 tuner" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module. - Say Y when you want to support this frontend. - -comment "Digital terrestrial only tuners/PLL" - depends on DVB_CORE - -config DVB_PLL - tristate "Generic I2C PLL based tuners" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - This module drives a number of tuners based on PLL chips with a - common I2C interface. Say Y when you want to support these tuners. - -config DVB_TUNER_DIB0070 - tristate "DiBcom DiB0070 silicon base-band tuner" - depends on I2C - default m if DVB_FE_CUSTOMISE - help - A driver for the silicon baseband tuner DiB0070 from DiBcom. - This device is only used inside a SiP called togther with a - demodulator for now. - -comment "SEC control devices for DVB-S" - depends on DVB_CORE - -config DVB_LNBP21 - tristate "LNBP21 SEC controller" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An SEC control chip. - -config DVB_ISL6405 - tristate "ISL6405 SEC controller" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An SEC control chip. - -config DVB_ISL6421 - tristate "ISL6421 SEC controller" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - An SEC control chip. - -config DVB_LGS8GL5 - tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - A DMB-TH tuner module. Say Y when you want to support this frontend. - -comment "Tools to develop new frontends" - -config DVB_DUMMY_FE - tristate "Dummy frontend driver" - default n - -config DVB_AF9013 - tristate "Afatech AF9013 demodulator" - depends on DVB_CORE && I2C - default m if DVB_FE_CUSTOMISE - help - Say Y when you want to support this frontend. -endmenu diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile deleted file mode 100644 index af7bdf0ad4c..00000000000 --- a/drivers/media/dvb/frontends/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -# -# Makefile for the kernel DVB frontend device drivers. -# - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -EXTRA_CFLAGS += -Idrivers/media/common/tuners/ - -s921-objs := s921_module.o s921_core.o -stb0899-objs = stb0899_drv.o stb0899_algo.o - -obj-$(CONFIG_DVB_PLL) += dvb-pll.o -obj-$(CONFIG_DVB_STV0299) += stv0299.o -obj-$(CONFIG_DVB_STB0899) += stb0899.o -obj-$(CONFIG_DVB_STB6100) += stb6100.o -obj-$(CONFIG_DVB_SP8870) += sp8870.o -obj-$(CONFIG_DVB_CX22700) += cx22700.o -obj-$(CONFIG_DVB_CX24110) += cx24110.o -obj-$(CONFIG_DVB_TDA8083) += tda8083.o -obj-$(CONFIG_DVB_L64781) += l64781.o -obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o -obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o -obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o -obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o -obj-$(CONFIG_DVB_MT312) += mt312.o -obj-$(CONFIG_DVB_VES1820) += ves1820.o -obj-$(CONFIG_DVB_VES1X93) += ves1x93.o -obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o -obj-$(CONFIG_DVB_SP887X) += sp887x.o -obj-$(CONFIG_DVB_NXT6000) += nxt6000.o -obj-$(CONFIG_DVB_MT352) += mt352.o -obj-$(CONFIG_DVB_ZL10353) += zl10353.o -obj-$(CONFIG_DVB_CX22702) += cx22702.o -obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o -obj-$(CONFIG_DVB_TDA10021) += tda10021.o -obj-$(CONFIG_DVB_TDA10023) += tda10023.o -obj-$(CONFIG_DVB_STV0297) += stv0297.o -obj-$(CONFIG_DVB_NXT200X) += nxt200x.o -obj-$(CONFIG_DVB_OR51211) += or51211.o -obj-$(CONFIG_DVB_OR51132) += or51132.o -obj-$(CONFIG_DVB_BCM3510) += bcm3510.o -obj-$(CONFIG_DVB_S5H1420) += s5h1420.o -obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o -obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o -obj-$(CONFIG_DVB_CX24123) += cx24123.o -obj-$(CONFIG_DVB_LNBP21) += lnbp21.o -obj-$(CONFIG_DVB_ISL6405) += isl6405.o -obj-$(CONFIG_DVB_ISL6421) += isl6421.o -obj-$(CONFIG_DVB_TDA10086) += tda10086.o -obj-$(CONFIG_DVB_TDA826X) += tda826x.o -obj-$(CONFIG_DVB_TDA8261) += tda8261.o -obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o -obj-$(CONFIG_DVB_TUA6100) += tua6100.o -obj-$(CONFIG_DVB_S5H1409) += s5h1409.o -obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o -obj-$(CONFIG_DVB_AU8522) += au8522.o -obj-$(CONFIG_DVB_TDA10048) += tda10048.o -obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o -obj-$(CONFIG_DVB_S5H1411) += s5h1411.o -obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o -obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o -obj-$(CONFIG_DVB_AF9013) += af9013.o -obj-$(CONFIG_DVB_CX24116) += cx24116.o -obj-$(CONFIG_DVB_SI21XX) += si21xx.o -obj-$(CONFIG_DVB_STV0288) += stv0288.o -obj-$(CONFIG_DVB_STB6000) += stb6000.o -obj-$(CONFIG_DVB_S921) += s921.o - diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c deleted file mode 100644 index b2b50fb4cfd..00000000000 --- a/drivers/media/dvb/frontends/af9013.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/firmware.h> - -#include "dvb_frontend.h" -#include "af9013_priv.h" -#include "af9013.h" - -int af9013_debug; - -struct af9013_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - - struct af9013_config config; - - u16 signal_strength; - u32 ber; - u32 ucblocks; - u16 snr; - u32 frequency; - unsigned long next_statistics_check; -}; - -static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; - -static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg, - u8 *val, u8 len) -{ - u8 buf[3+len]; - struct i2c_msg msg = { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(buf), - .buf = buf }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = mbox; - memcpy(&buf[3], val, len); - - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - warn("I2C write failed reg:%04x len:%d", reg, len); - return -EREMOTEIO; - } - return 0; -} - -static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) -{ - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7); - return af9013_write_regs(state, mbox, reg, val, len); -} - -static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, - u8 len) -{ - u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7); - return af9013_write_regs(state, mbox, reg, val, len); -} - -/* write single register */ -static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val) -{ - return af9013_write_ofdm_regs(state, reg, &val, 1); -} - -/* read single register */ -static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val) -{ - u8 obuf[3] = { reg >> 8, reg & 0xff, 0 }; - u8 ibuf[1]; - struct i2c_msg msg[2] = { - { - .addr = state->config.demod_address, - .flags = 0, - .len = sizeof(obuf), - .buf = obuf - }, { - .addr = state->config.demod_address, - .flags = I2C_M_RD, - .len = sizeof(ibuf), - .buf = ibuf - } - }; - - if (i2c_transfer(state->i2c, msg, 2) != 2) { - warn("I2C read failed reg:%04x", reg); - return -EREMOTEIO; - } - *val = ibuf[0]; - return 0; -} - -static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 val) -{ - int ret; - u8 tmp, mask; - - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; - - mask = regmask[len - 1] << pos; - tmp = (tmp & ~mask) | ((val << pos) & mask); - - return af9013_write_reg(state, reg, tmp); -} - -static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos, - u8 len, u8 *val) -{ - int ret; - u8 tmp; - - ret = af9013_read_reg(state, reg, &tmp); - if (ret) - return ret; - *val = (tmp >> pos) & regmask[len - 1]; - return 0; -} - -static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) -{ - int ret; - u8 pos; - u16 addr; - deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval); - -/* GPIO0 & GPIO1 0xd735 - GPIO2 & GPIO3 0xd736 */ - - switch (gpio) { - case 0: - case 1: - addr = 0xd735; - break; - case 2: - case 3: - addr = 0xd736; - break; - - default: - err("invalid gpio:%d\n", gpio); - ret = -EINVAL; - goto error; - }; - - switch (gpio) { - case 0: - case 2: - pos = 0; - break; - case 1: - case 3: - default: - pos = 4; - break; - }; - - ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval); - -error: - return ret; -} - -static u32 af913_div(u32 a, u32 b, u32 x) -{ - u32 r = 0, c = 0, i; - deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x); - - if (a > b) { - c = a / b; - a = a - c * b; - } - - for (i = 0; i < x; i++) { - if (a >= b) { - r += 1; - a -= b; - } - a <<= 1; - r <<= 1; - } - r = (c << (u32)x) + r; - - deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r); - return r; -} - -static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) -{ - int ret = 0; - u8 i = 0; - u8 buf[24]; - u32 uninitialized_var(ns_coeff1_2048nu); - u32 uninitialized_var(ns_coeff1_8191nu); - u32 uninitialized_var(ns_coeff1_8192nu); - u32 uninitialized_var(ns_coeff1_8193nu); - u32 uninitialized_var(ns_coeff2_2k); - u32 uninitialized_var(ns_coeff2_8k); - - deb_info("%s: adc_clock:%d bw:%d\n", __func__, - state->config.adc_clock, bw); - - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01e79e7a; - ns_coeff1_8191nu = 0x0079eb6e; - ns_coeff1_8192nu = 0x0079e79e; - ns_coeff1_8193nu = 0x0079e3cf; - ns_coeff2_2k = 0x00f3cf3d; - ns_coeff2_8k = 0x003cf3cf; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x0238e38e; - ns_coeff1_8191nu = 0x008e3d55; - ns_coeff1_8192nu = 0x008e38e4; - ns_coeff1_8193nu = 0x008e3472; - ns_coeff2_2k = 0x011c71c7; - ns_coeff2_8k = 0x00471c72; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x028a28a3; - ns_coeff1_8191nu = 0x00a28f3d; - ns_coeff1_8192nu = 0x00a28a29; - ns_coeff1_8193nu = 0x00a28514; - ns_coeff2_2k = 0x01451451; - ns_coeff2_8k = 0x00514514; - break; - default: - ret = -EINVAL; - } - break; - case 20480: /* 20.480 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x02adb6dc; - ns_coeff1_8191nu = 0x00ab7313; - ns_coeff1_8192nu = 0x00ab6db7; - ns_coeff1_8193nu = 0x00ab685c; - ns_coeff2_2k = 0x0156db6e; - ns_coeff2_8k = 0x0055b6dc; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x03200001; - ns_coeff1_8191nu = 0x00c80640; - ns_coeff1_8192nu = 0x00c80000; - ns_coeff1_8193nu = 0x00c7f9c0; - ns_coeff2_2k = 0x01900000; - ns_coeff2_8k = 0x00640000; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x03924926; - ns_coeff1_8191nu = 0x00e4996e; - ns_coeff1_8192nu = 0x00e49249; - ns_coeff1_8193nu = 0x00e48b25; - ns_coeff2_2k = 0x01c92493; - ns_coeff2_8k = 0x00724925; - break; - default: - ret = -EINVAL; - } - break; - case 28000: /* 28.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x01f58d10; - ns_coeff1_8191nu = 0x007d672f; - ns_coeff1_8192nu = 0x007d6344; - ns_coeff1_8193nu = 0x007d5f59; - ns_coeff2_2k = 0x00fac688; - ns_coeff2_8k = 0x003eb1a2; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x02492492; - ns_coeff1_8191nu = 0x00924db7; - ns_coeff1_8192nu = 0x00924925; - ns_coeff1_8193nu = 0x00924492; - ns_coeff2_2k = 0x01249249; - ns_coeff2_8k = 0x00492492; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x029cbc15; - ns_coeff1_8191nu = 0x00a7343f; - ns_coeff1_8192nu = 0x00a72f05; - ns_coeff1_8193nu = 0x00a729cc; - ns_coeff2_2k = 0x014e5e0a; - ns_coeff2_8k = 0x00539783; - break; - default: - ret = -EINVAL; - } - break; - case 25000: /* 25.000 MHz */ - switch (bw) { - case BANDWIDTH_6_MHZ: - ns_coeff1_2048nu = 0x0231bcb5; - ns_coeff1_8191nu = 0x008c7391; - ns_coeff1_8192nu = 0x008c6f2d; - ns_coeff1_8193nu = 0x008c6aca; - ns_coeff2_2k = 0x0118de5b; - ns_coeff2_8k = 0x00463797; - break; - case BANDWIDTH_7_MHZ: - ns_coeff1_2048nu = 0x028f5c29; - ns_coeff1_8191nu = 0x00a3dc29; - ns_coeff1_8192nu = 0x00a3d70a; - ns_coeff1_8193nu = 0x00a3d1ec; - ns_coeff2_2k = 0x0147ae14; - ns_coeff2_8k = 0x0051eb85; - break; - case BANDWIDTH_8_MHZ: - ns_coeff1_2048nu = 0x02ecfb9d; - ns_coeff1_8191nu = 0x00bb44c1; - ns_coeff1_8192nu = 0x00bb3ee7; - ns_coeff1_8193nu = 0x00bb390d; - ns_coeff2_2k = 0x01767dce; - ns_coeff2_8k = 0x005d9f74; - break; - default: - ret = -EINVAL; - } - break; - default: - err("invalid xtal"); - return -EINVAL; - } - if (ret) { - err("invalid bandwidth"); - return ret; - } - - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); - buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); - buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); - buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); - buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); - buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); - - deb_info("%s: coeff:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xae00 + i, buf[i]); - if (ret) - break; - } - - return ret; -} - -static int af9013_set_adc_ctrl(struct af9013_state *state) -{ - int ret; - u8 buf[3], tmp, i; - u32 adc_cw; - - deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock); - - /* adc frequency type */ - switch (state->config.adc_clock) { - case 28800: /* 28.800 MHz */ - tmp = 0; - break; - case 20480: /* 20.480 MHz */ - tmp = 1; - break; - case 28000: /* 28.000 MHz */ - tmp = 2; - break; - case 25000: /* 25.000 MHz */ - tmp = 3; - break; - default: - err("invalid xtal"); - return -EINVAL; - } - - adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul); - - buf[0] = (u8) ((adc_cw & 0x000000ff)); - buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16); - - deb_info("%s: adc_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd180 + i, buf[i]); - if (ret) - goto error; - } - ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp); -error: - return ret; -} - -static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) -{ - int ret; - u16 addr; - u8 buf[3], i, j; - u32 adc_freq, freq_cw; - s8 bfs_spec_inv; - int if_sample_freq; - - for (j = 0; j < 3; j++) { - if (j == 0) { - addr = 0xd140; /* fcw normal */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else if (j == 1) { - addr = 0x9be7; /* fcw dummy ram */ - bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; - } else { - addr = 0x9bea; /* fcw inverted */ - bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; - } - - adc_freq = state->config.adc_clock * 1000; - if_sample_freq = state->config.tuner_if * 1000; - - /* TDA18271 uses different sampling freq for every bw */ - if (state->config.tuner == AF9013_TUNER_TDA18271) { - switch (bw) { - case BANDWIDTH_6_MHZ: - if_sample_freq = 3300000; /* 3.3 MHz */ - break; - case BANDWIDTH_7_MHZ: - if_sample_freq = 3800000; /* 3.8 MHz */ - break; - case BANDWIDTH_8_MHZ: - default: - if_sample_freq = 4300000; /* 4.3 MHz */ - break; - } - } - - while (if_sample_freq > (adc_freq / 2)) - if_sample_freq = if_sample_freq - adc_freq; - - if (if_sample_freq >= 0) - bfs_spec_inv = bfs_spec_inv * (-1); - else - if_sample_freq = if_sample_freq * (-1); - - freq_cw = af913_div(if_sample_freq, adc_freq, 23ul); - - if (bfs_spec_inv == -1) - freq_cw = 0x00800000 - freq_cw; - - buf[0] = (u8) ((freq_cw & 0x000000ff)); - buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8); - buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16); - - - deb_info("%s: freq_cw:", __func__); - debug_dump(buf, sizeof(buf), deb_info); - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, addr++, buf[i]); - if (ret) - goto error; - } - } -error: - return ret; -} - -static int af9013_set_ofdm_params(struct af9013_state *state, - struct dvb_ofdm_parameters *params, u8 *auto_mode) -{ - int ret; - u8 i, buf[3] = {0, 0, 0}; - *auto_mode = 0; /* set if parameters are requested to auto set */ - - switch (params->transmission_mode) { - case TRANSMISSION_MODE_AUTO: - *auto_mode = 1; - case TRANSMISSION_MODE_2K: - break; - case TRANSMISSION_MODE_8K: - buf[0] |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (params->guard_interval) { - case GUARD_INTERVAL_AUTO: - *auto_mode = 1; - case GUARD_INTERVAL_1_32: - break; - case GUARD_INTERVAL_1_16: - buf[0] |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - buf[0] |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - buf[0] |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (params->hierarchy_information) { - case HIERARCHY_AUTO: - *auto_mode = 1; - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - buf[0] |= (1 << 4); - break; - case HIERARCHY_2: - buf[0] |= (2 << 4); - break; - case HIERARCHY_4: - buf[0] |= (3 << 4); - break; - default: - return -EINVAL; - }; - - switch (params->constellation) { - case QAM_AUTO: - *auto_mode = 1; - case QPSK: - break; - case QAM_16: - buf[1] |= (1 << 6); - break; - case QAM_64: - buf[1] |= (2 << 6); - break; - default: - return -EINVAL; - } - - /* Use HP. How and which case we can switch to LP? */ - buf[1] |= (1 << 4); - - switch (params->code_rate_HP) { - case FEC_AUTO: - *auto_mode = 1; - case FEC_1_2: - break; - case FEC_2_3: - buf[2] |= (1 << 0); - break; - case FEC_3_4: - buf[2] |= (2 << 0); - break; - case FEC_5_6: - buf[2] |= (3 << 0); - break; - case FEC_7_8: - buf[2] |= (4 << 0); - break; - default: - return -EINVAL; - } - - switch (params->code_rate_LP) { - case FEC_AUTO: - /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO - by dvb_frontend.c for compatibility */ - if (params->hierarchy_information != HIERARCHY_NONE) - *auto_mode = 1; - case FEC_1_2: - break; - case FEC_2_3: - buf[2] |= (1 << 3); - break; - case FEC_3_4: - buf[2] |= (2 << 3); - break; - case FEC_5_6: - buf[2] |= (3 << 3); - break; - case FEC_7_8: - buf[2] |= (4 << 3); - break; - case FEC_NONE: - if (params->hierarchy_information == HIERARCHY_AUTO) - break; - default: - return -EINVAL; - } - - switch (params->bandwidth) { - case BANDWIDTH_6_MHZ: - break; - case BANDWIDTH_7_MHZ: - buf[1] |= (1 << 2); - break; - case BANDWIDTH_8_MHZ: - buf[1] |= (2 << 2); - break; - default: - return -EINVAL; - } - - /* program */ - for (i = 0; i < sizeof(buf); i++) { - ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]); - if (ret) - break; - } - - return ret; -} - -static int af9013_reset(struct af9013_state *state, u8 sleep) -{ - int ret; - u8 tmp, i; - deb_info("%s\n", __func__); - - /* enable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1); - if (ret) - goto error; - - /* start reset mechanism */ - ret = af9013_write_reg(state, 0xaeff, 1); - if (ret) - goto error; - - /* reset is done when bit 1 is set */ - for (i = 0; i < 150; i++) { - ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp); - if (ret) - goto error; - if (tmp) - break; /* reset done */ - msleep(10); - } - if (!tmp) - return -ETIMEDOUT; - - /* don't clear reset when going to sleep */ - if (!sleep) { - /* clear OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - - /* disable OFDM reset */ - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } -error: - return ret; -} - -static int af9013_power_ctrl(struct af9013_state *state, u8 onoff) -{ - int ret; - deb_info("%s: onoff:%d\n", __func__, onoff); - - if (onoff) { - /* power on */ - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); - } else { - /* power off */ - ret = af9013_reset(state, 1); - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1); - } -error: - return ret; -} - -static int af9013_lock_led(struct af9013_state *state, u8 onoff) -{ - deb_info("%s: onoff:%d\n", __func__, onoff); - - return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff); -} - -static int af9013_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 auto_mode; /* auto set TPS */ - - deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, - params->u.ofdm.bandwidth); - - state->frequency = params->frequency; - - /* program CFOE coefficients */ - ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* program frequency control */ - ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); - if (ret) - goto error; - - /* clear TPS lock flag (inverted flag) */ - ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1); - if (ret) - goto error; - - /* clear MPEG2 lock flag */ - ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0); - if (ret) - goto error; - - /* empty channel function */ - ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0); - if (ret) - goto error; - - /* empty DVB-T channel function */ - ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0); - if (ret) - goto error; - - /* program tuner */ - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, params); - - /* program TPS and bandwidth, check if auto mode needed */ - ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); - if (ret) - goto error; - - if (auto_mode) { - /* clear easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 0); - deb_info("%s: auto TPS\n", __func__); - } else { - /* set easy mode flag */ - ret = af9013_write_reg(state, 0xaefd, 1); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xaefe, 0); - deb_info("%s: manual TPS\n", __func__); - } - if (ret) - goto error; - - /* everything is set, lets try to receive channel - OFSM GO! */ - ret = af9013_write_reg(state, 0xffff, 0); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 i, buf[3]; - deb_info("%s\n", __func__); - - /* read TPS registers */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]); - if (ret) - goto error; - } - - switch ((buf[1] >> 6) & 3) { - case 0: - p->u.ofdm.constellation = QPSK; - break; - case 1: - p->u.ofdm.constellation = QAM_16; - break; - case 2: - p->u.ofdm.constellation = QAM_64; - break; - } - - switch ((buf[0] >> 0) & 3) { - case 0: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - } - - switch ((buf[0] >> 2) & 3) { - case 0: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - - switch ((buf[0] >> 4) & 7) { - case 0: - p->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - p->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - p->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - } - - switch ((buf[2] >> 0) & 7) { - case 0: - p->u.ofdm.code_rate_HP = FEC_1_2; - break; - case 1: - p->u.ofdm.code_rate_HP = FEC_2_3; - break; - case 2: - p->u.ofdm.code_rate_HP = FEC_3_4; - break; - case 3: - p->u.ofdm.code_rate_HP = FEC_5_6; - break; - case 4: - p->u.ofdm.code_rate_HP = FEC_7_8; - break; - } - - switch ((buf[2] >> 3) & 7) { - case 0: - p->u.ofdm.code_rate_LP = FEC_1_2; - break; - case 1: - p->u.ofdm.code_rate_LP = FEC_2_3; - break; - case 2: - p->u.ofdm.code_rate_LP = FEC_3_4; - break; - case 3: - p->u.ofdm.code_rate_LP = FEC_5_6; - break; - case 4: - p->u.ofdm.code_rate_LP = FEC_7_8; - break; - } - - switch ((buf[1] >> 2) & 3) { - case 0: - p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - case 1: - p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 2: - p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - } - - p->inversion = INVERSION_AUTO; - p->frequency = state->frequency; - -error: - return ret; -} - -static int af9013_update_ber_unc(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i; - u32 error_bit_count = 0; - u32 total_bit_count = 0; - u32 abort_packet_count = 0; - - state->ber = 0; - - /* check if error bit count is ready */ - ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]); - if (ret) - goto error; - if (!buf[0]) - goto exit; - - /* get RSD packet abort count */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd38a + i, &buf[i]); - if (ret) - goto error; - } - abort_packet_count = (buf[1] << 8) + buf[0]; - - /* get error bit count */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd387 + i, &buf[i]); - if (ret) - goto error; - } - error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - error_bit_count = error_bit_count - abort_packet_count * 8 * 8; - - /* get used RSD counting period (10000 RSD packets used) */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0xd385 + i, &buf[i]); - if (ret) - goto error; - } - total_bit_count = (buf[1] << 8) + buf[0]; - total_bit_count = total_bit_count - abort_packet_count; - total_bit_count = total_bit_count * 204 * 8; - - if (total_bit_count) - state->ber = error_bit_count * 1000000000 / total_bit_count; - - state->ucblocks += abort_packet_count; - - deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__, - error_bit_count, total_bit_count, abort_packet_count); - - /* set BER counting range */ - ret = af9013_write_reg(state, 0xd385, 10000 & 0xff); - if (ret) - goto error; - ret = af9013_write_reg(state, 0xd386, 10000 >> 8); - if (ret) - goto error; - /* reset and start BER counter */ - ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1); - if (ret) - goto error; - -exit: -error: - return ret; -} - -static int af9013_update_snr(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 buf[3], i, len; - u32 quant = 0; - struct snr_table *uninitialized_var(snr_table); - - /* check if quantizer ready (for snr) */ - ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); - if (ret) - goto error; - if (buf[0]) { - /* quantizer ready - read it */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]); - if (ret) - goto error; - } - quant = (buf[2] << 16) + (buf[1] << 8) + buf[0]; - - /* read current constellation */ - ret = af9013_read_reg(state, 0xd3c1, &buf[0]); - if (ret) - goto error; - - switch ((buf[0] >> 6) & 3) { - case 0: - len = ARRAY_SIZE(qpsk_snr_table); - snr_table = qpsk_snr_table; - break; - case 1: - len = ARRAY_SIZE(qam16_snr_table); - snr_table = qam16_snr_table; - break; - case 2: - len = ARRAY_SIZE(qam64_snr_table); - snr_table = qam64_snr_table; - break; - default: - len = 0; - break; - } - - if (len) { - for (i = 0; i < len; i++) { - if (quant < snr_table[i].val) { - state->snr = snr_table[i].snr * 10; - break; - } - } - } - - /* set quantizer super frame count */ - ret = af9013_write_reg(state, 0xd2e2, 1); - if (ret) - goto error; - - /* check quantizer availability */ - for (i = 0; i < 10; i++) { - msleep(10); - ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1, - &buf[0]); - if (ret) - goto error; - if (!buf[0]) - break; - } - - /* reset quantizer */ - ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1); - if (ret) - goto error; - } - -error: - return ret; -} - -static int af9013_update_signal_strength(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - u8 tmp0; - u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; - int signal_strength; - - deb_info("%s\n", __func__); - - state->signal_strength = 0; - - ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); - if (ret) - goto error; - if (tmp0) { - ret = af9013_read_reg(state, 0x9bbd, &rf_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9bd0, &rf_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be2, &if_50); - if (ret) - goto error; - ret = af9013_read_reg(state, 0x9be4, &if_80); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07c, &rf_gain); - if (ret) - goto error; - ret = af9013_read_reg(state, 0xd07d, &if_gain); - if (ret) - goto error; - signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ - 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ - 11 * (rf_80 + if_80)); - if (signal_strength < 0) - signal_strength = 0; - else if (signal_strength > 0xffff) - signal_strength = 0xffff; - - state->signal_strength = signal_strength; - } - -error: - return ret; -} - -static int af9013_update_statistics(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - - if (time_before(jiffies, state->next_statistics_check)) - return 0; - - /* set minimum statistic update interval */ - state->next_statistics_check = jiffies + msecs_to_jiffies(1200); - - ret = af9013_update_signal_strength(fe); - if (ret) - goto error; - ret = af9013_update_snr(fe); - if (ret) - goto error; - ret = af9013_update_ber_unc(fe); - if (ret) - goto error; - -error: - return ret; -} - -static int af9013_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 800; - fesettings->step_size = 0; - fesettings->max_drift = 0; - - return 0; -} - -static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret = 0; - u8 tmp; - *status = 0; - - /* TPS lock */ - ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - /* MPEG2 lock */ - ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - if (!(*status & FE_HAS_SIGNAL)) { - /* AGC lock */ - ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_SIGNAL; - } - - if (!(*status & FE_HAS_CARRIER)) { - /* CFO lock */ - ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_CARRIER; - } - - if (!(*status & FE_HAS_CARRIER)) { - /* SFOE lock */ - ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); - if (ret) - goto error; - if (tmp) - *status |= FE_HAS_CARRIER; - } - - ret = af9013_update_statistics(fe); - -error: - return ret; -} - - -static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ber = state->ber; - return ret; -} - -static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *strength = state->signal_strength; - return ret; -} - -static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *snr = state->snr; - return ret; -} - -static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - ret = af9013_update_statistics(fe); - *ucblocks = state->ucblocks; - return ret; -} - -static int af9013_sleep(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret; - deb_info("%s\n", __func__); - - ret = af9013_lock_led(state, 0); - if (ret) - goto error; - - ret = af9013_power_ctrl(state, 0); -error: - return ret; -} - -static int af9013_init(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - int ret, i, len; - u8 tmp0, tmp1; - struct regdesc *init; - deb_info("%s\n", __func__); - - /* reset OFDM */ - ret = af9013_reset(state, 0); - if (ret) - goto error; - - /* power on */ - ret = af9013_power_ctrl(state, 1); - if (ret) - goto error; - - /* enable ADC */ - ret = af9013_write_reg(state, 0xd73a, 0xa4); - if (ret) - goto error; - - /* write API version to firmware */ - for (i = 0; i < sizeof(state->config.api_version); i++) { - ret = af9013_write_reg(state, 0x9bf2 + i, - state->config.api_version[i]); - if (ret) - goto error; - } - - /* program ADC control */ - ret = af9013_set_adc_ctrl(state); - if (ret) - goto error; - - /* set I2C master clock */ - ret = af9013_write_reg(state, 0xd416, 0x14); - if (ret) - goto error; - - /* set 16 embx */ - ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1); - if (ret) - goto error; - - /* set no trigger */ - ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0); - if (ret) - goto error; - - /* set read-update bit for constellation */ - ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1); - if (ret) - goto error; - - /* enable FEC monitor */ - ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1); - if (ret) - goto error; - - /* load OFSM settings */ - deb_info("%s: load ofsm settings\n", __func__); - len = ARRAY_SIZE(ofsm_init); - init = ofsm_init; - for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, - init[i].len, init[i].val); - if (ret) - goto error; - } - - /* load tuner specific settings */ - deb_info("%s: load tuner specific settings\n", __func__); - switch (state->config.tuner) { - case AF9013_TUNER_MXL5003D: - len = ARRAY_SIZE(tuner_init_mxl5003d); - init = tuner_init_mxl5003d; - break; - case AF9013_TUNER_MXL5005D: - case AF9013_TUNER_MXL5005R: - len = ARRAY_SIZE(tuner_init_mxl5005); - init = tuner_init_mxl5005; - break; - case AF9013_TUNER_ENV77H11D5: - len = ARRAY_SIZE(tuner_init_env77h11d5); - init = tuner_init_env77h11d5; - break; - case AF9013_TUNER_MT2060: - len = ARRAY_SIZE(tuner_init_mt2060); - init = tuner_init_mt2060; - break; - case AF9013_TUNER_MC44S803: - len = ARRAY_SIZE(tuner_init_mc44s803); - init = tuner_init_mc44s803; - break; - case AF9013_TUNER_QT1010: - case AF9013_TUNER_QT1010A: - len = ARRAY_SIZE(tuner_init_qt1010); - init = tuner_init_qt1010; - break; - case AF9013_TUNER_MT2060_2: - len = ARRAY_SIZE(tuner_init_mt2060_2); - init = tuner_init_mt2060_2; - break; - case AF9013_TUNER_TDA18271: - len = ARRAY_SIZE(tuner_init_tda18271); - init = tuner_init_tda18271; - break; - case AF9013_TUNER_UNKNOWN: - default: - len = ARRAY_SIZE(tuner_init_unknown); - init = tuner_init_unknown; - break; - } - - for (i = 0; i < len; i++) { - ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, - init[i].len, init[i].val); - if (ret) - goto error; - } - - /* set TS mode */ - deb_info("%s: setting ts mode\n", __func__); - tmp0 = 0; /* parallel mode */ - tmp1 = 0; /* serial mode */ - switch (state->config.output_mode) { - case AF9013_OUTPUT_MODE_PARALLEL: - tmp0 = 1; - break; - case AF9013_OUTPUT_MODE_SERIAL: - tmp1 = 1; - break; - case AF9013_OUTPUT_MODE_USB: - /* usb mode for AF9015 */ - default: - break; - } - ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */ - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */ - if (ret) - goto error; - - /* enable lock led */ - ret = af9013_lock_led(state, 1); - if (ret) - goto error; - -error: - return ret; -} - -static struct dvb_frontend_ops af9013_ops; - -static int af9013_download_firmware(struct af9013_state *state) -{ - int i, len, packets, remainder, ret; - const struct firmware *fw; - u16 addr = 0x5100; /* firmware start address */ - u16 checksum = 0; - u8 val; - u8 fw_params[4]; - u8 *data; - u8 *fw_file = AF9013_DEFAULT_FIRMWARE; - - msleep(100); - /* check whether firmware is already running */ - ret = af9013_read_reg(state, 0x98be, &val); - if (ret) - goto error; - else - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c) /* fw is running, no need for download */ - goto exit; - - info("found a '%s' in cold state, will try to load a firmware", - af9013_ops.info.name); - - /* request the firmware, this will block and timeout */ - ret = request_firmware(&fw, fw_file, &state->i2c->dev); - if (ret) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details" \ - " on firmware-problems. (%d)", - fw_file, ret); - goto error; - } - - info("downloading firmware from file '%s'", fw_file); - - /* calc checksum */ - for (i = 0; i < fw->size; i++) - checksum += fw->data[i]; - - fw_params[0] = checksum >> 8; - fw_params[1] = checksum & 0xff; - fw_params[2] = fw->size >> 8; - fw_params[3] = fw->size & 0xff; - - /* write fw checksum & size */ - ret = af9013_write_ofsm_regs(state, 0x50fc, - fw_params, sizeof(fw_params)); - if (ret) - goto error_release; - - #define FW_PACKET_MAX_DATA 16 - - packets = fw->size / FW_PACKET_MAX_DATA; - remainder = fw->size % FW_PACKET_MAX_DATA; - len = FW_PACKET_MAX_DATA; - for (i = 0; i <= packets; i++) { - if (i == packets) /* set size of the last packet */ - len = remainder; - - data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); - ret = af9013_write_ofsm_regs(state, addr, data, len); - addr += FW_PACKET_MAX_DATA; - - if (ret) { - err("firmware download failed at %d with %d", i, ret); - goto error_release; - } - } - - /* request boot firmware */ - ret = af9013_write_reg(state, 0xe205, 1); - if (ret) - goto error_release; - - for (i = 0; i < 15; i++) { - msleep(100); - - /* check firmware status */ - ret = af9013_read_reg(state, 0x98be, &val); - if (ret) - goto error_release; - - deb_info("%s: firmware status:%02x\n", __func__, val); - - if (val == 0x0c || val == 0x04) /* success or fail */ - break; - } - - if (val == 0x04) { - err("firmware did not run"); - ret = -1; - } else if (val != 0x0c) { - err("firmware boot timeout"); - ret = -1; - } - -error_release: - release_firmware(fw); -error: -exit: - if (!ret) - info("found a '%s' in warm state.", af9013_ops.info.name); - return ret; -} - -static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int ret; - struct af9013_state *state = fe->demodulator_priv; - deb_info("%s: enable:%d\n", __func__, enable); - - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) - ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable); - else - ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable); - - return ret; -} - -static void af9013_release(struct dvb_frontend *fe) -{ - struct af9013_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops af9013_ops; - -struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c) -{ - int ret; - struct af9013_state *state = NULL; - u8 buf[3], i; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct af9013_config)); - - /* chip version */ - ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); - if (ret) - goto error; - - /* ROM version */ - for (i = 0; i < 2; i++) { - ret = af9013_read_reg(state, 0x116b + i, &buf[i]); - if (ret) - goto error; - } - deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, - buf[2], buf[0], buf[1]); - - /* download firmware */ - if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { - ret = af9013_download_firmware(state); - if (ret) - goto error; - } - - /* firmware version */ - for (i = 0; i < 3; i++) { - ret = af9013_read_reg(state, 0x5103 + i, &buf[i]); - if (ret) - goto error; - } - info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]); - - /* settings for mp2if */ - if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { - /* AF9015 split PSB to 1.5k + 0.5k */ - ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1); - } else { - /* AF9013 change the output bit to data7 */ - ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1); - if (ret) - goto error; - /* AF9013 set mpeg to full speed */ - ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1); - } - if (ret) - goto error; - ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1); - if (ret) - goto error; - - /* set GPIOs */ - for (i = 0; i < sizeof(state->config.gpio); i++) { - ret = af9013_set_gpio(state, i, state->config.gpio[i]); - if (ret) - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &af9013_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(af9013_attach); - -static struct dvb_frontend_ops af9013_ops = { - .info = { - .name = "Afatech AF9013 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 250000, - .frequency_tolerance = 0, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = af9013_release, - .init = af9013_init, - .sleep = af9013_sleep, - .i2c_gate_ctrl = af9013_i2c_gate_ctrl, - - .set_frontend = af9013_set_frontend, - .get_frontend = af9013_get_frontend, - - .get_tune_settings = af9013_get_tune_settings, - - .read_status = af9013_read_status, - .read_ber = af9013_read_ber, - .read_signal_strength = af9013_read_signal_strength, - .read_snr = af9013_read_snr, - .read_ucblocks = af9013_read_ucblocks, -}; - -module_param_named(debug, af9013_debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); -MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h deleted file mode 100644 index 28b90c91c76..00000000000 --- a/drivers/media/dvb/frontends/af9013.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _AF9013_H_ -#define _AF9013_H_ - -#include <linux/dvb/frontend.h> - -enum af9013_ts_mode { - AF9013_OUTPUT_MODE_PARALLEL, - AF9013_OUTPUT_MODE_SERIAL, - AF9013_OUTPUT_MODE_USB, /* only for AF9015 */ -}; - -enum af9013_tuner { - AF9013_TUNER_MXL5003D = 3, /* MaxLinear */ - AF9013_TUNER_MXL5005D = 13, /* MaxLinear */ - AF9013_TUNER_MXL5005R = 30, /* MaxLinear */ - AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */ - AF9013_TUNER_MT2060 = 130, /* Microtune */ - AF9013_TUNER_MC44S803 = 133, /* Freescale */ - AF9013_TUNER_QT1010 = 134, /* Quantek */ - AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */ - AF9013_TUNER_MT2060_2 = 147, /* Microtune */ - AF9013_TUNER_TDA18271 = 156, /* NXP */ - AF9013_TUNER_QT1010A = 162, /* Quantek */ -}; - -/* AF9013/5 GPIOs (mostly guessed) - demod#1-gpio#0 - set demod#2 i2c-addr for dual devices - demod#1-gpio#1 - xtal setting (?) - demod#1-gpio#3 - tuner#1 - demod#2-gpio#0 - tuner#2 - demod#2-gpio#1 - xtal setting (?) -*/ -#define AF9013_GPIO_ON (1 << 0) -#define AF9013_GPIO_EN (1 << 1) -#define AF9013_GPIO_O (1 << 2) -#define AF9013_GPIO_I (1 << 3) - -#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN) -#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN) -#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O) - -struct af9013_config { - /* demodulator's I2C address */ - u8 demod_address; - - /* frequencies in kHz */ - u32 adc_clock; - - /* tuner ID */ - u8 tuner; - - /* tuner IF */ - u16 tuner_if; - - /* TS data output mode */ - u8 output_mode:2; - - /* RF spectrum inversion */ - u8 rf_spec_inv:1; - - /* API version */ - u8 api_version[4]; - - /* GPIOs */ - u8 gpio[4]; -}; - - -#if defined(CONFIG_DVB_AF9013) || \ - (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE)) -extern struct dvb_frontend *af9013_attach(const struct af9013_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *af9013_attach( -const struct af9013_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_AF9013 */ - -#endif /* _AF9013_H_ */ diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h deleted file mode 100644 index 163e251d0b7..00000000000 --- a/drivers/media/dvb/frontends/af9013_priv.h +++ /dev/null @@ -1,869 +0,0 @@ -/* - * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver - * - * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> - * - * Thanks to Afatech who kindly provided information. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _AF9013_PRIV_ -#define _AF9013_PRIV_ - -#define LOG_PREFIX "af9013" -extern int af9013_debug; - -#define dprintk(var, level, args...) \ - do { if ((var & level)) printk(args); } while (0) - -#define debug_dump(b, l, func) {\ - int loop_; \ - for (loop_ = 0; loop_ < l; loop_++) \ - func("%02x ", b[loop_]); \ - func("\n");\ -} - -#define deb_info(args...) dprintk(af9013_debug, 0x01, args) - -#undef err -#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg) -#undef info -#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg) -#undef warn -#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg) - -#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw" - -struct regdesc { - u16 addr; - u8 pos:4; - u8 len:4; - u8 val; -}; - -struct snr_table { - u32 val; - u8 snr; -}; - -/* QPSK SNR lookup table */ -static struct snr_table qpsk_snr_table[] = { - { 0x0b4771, 0 }, - { 0x0c1aed, 1 }, - { 0x0d0d27, 2 }, - { 0x0e4d19, 3 }, - { 0x0e5da8, 4 }, - { 0x107097, 5 }, - { 0x116975, 6 }, - { 0x1252d9, 7 }, - { 0x131fa4, 8 }, - { 0x13d5e1, 9 }, - { 0x148e53, 10 }, - { 0x15358b, 11 }, - { 0x15dd29, 12 }, - { 0x168112, 13 }, - { 0x170b61, 14 }, - { 0xffffff, 15 }, -}; - -/* QAM16 SNR lookup table */ -static struct snr_table qam16_snr_table[] = { - { 0x05eb62, 5 }, - { 0x05fecf, 6 }, - { 0x060b80, 7 }, - { 0x062501, 8 }, - { 0x064865, 9 }, - { 0x069604, 10 }, - { 0x06f356, 11 }, - { 0x07706a, 12 }, - { 0x0804d3, 13 }, - { 0x089d1a, 14 }, - { 0x093e3d, 15 }, - { 0x09e35d, 16 }, - { 0x0a7c3c, 17 }, - { 0x0afaf8, 18 }, - { 0x0b719d, 19 }, - { 0xffffff, 20 }, -}; - -/* QAM64 SNR lookup table */ -static struct snr_table qam64_snr_table[] = { - { 0x03109b, 12 }, - { 0x0310d4, 13 }, - { 0x031920, 14 }, - { 0x0322d0, 15 }, - { 0x0339fc, 16 }, - { 0x0364a1, 17 }, - { 0x038bcc, 18 }, - { 0x03c7d3, 19 }, - { 0x0408cc, 20 }, - { 0x043bed, 21 }, - { 0x048061, 22 }, - { 0x04be95, 23 }, - { 0x04fa7d, 24 }, - { 0x052405, 25 }, - { 0x05570d, 26 }, - { 0xffffff, 27 }, -}; - -static struct regdesc ofsm_init[] = { - { 0xd73a, 0, 8, 0xa1 }, - { 0xd73b, 0, 8, 0x1f }, - { 0xd73c, 4, 4, 0x0a }, - { 0xd732, 3, 1, 0x00 }, - { 0xd731, 4, 2, 0x03 }, - { 0xd73d, 7, 1, 0x01 }, - { 0xd740, 0, 1, 0x00 }, - { 0xd740, 1, 1, 0x00 }, - { 0xd740, 2, 1, 0x00 }, - { 0xd740, 3, 1, 0x01 }, - { 0xd3c1, 4, 1, 0x01 }, - { 0xd3a2, 0, 8, 0x00 }, - { 0xd3a3, 0, 8, 0x04 }, - { 0xd305, 0, 8, 0x32 }, - { 0xd306, 0, 8, 0x10 }, - { 0xd304, 0, 8, 0x04 }, - { 0x9112, 0, 1, 0x01 }, - { 0x911d, 0, 1, 0x01 }, - { 0x911a, 0, 1, 0x01 }, - { 0x911b, 0, 1, 0x01 }, - { 0x9bce, 0, 4, 0x02 }, - { 0x9116, 0, 1, 0x01 }, - { 0x9bd1, 0, 1, 0x01 }, - { 0xd2e0, 0, 8, 0xd0 }, - { 0xd2e9, 0, 4, 0x0d }, - { 0xd38c, 0, 8, 0xfc }, - { 0xd38d, 0, 8, 0x00 }, - { 0xd38e, 0, 8, 0x7e }, - { 0xd38f, 0, 8, 0x00 }, - { 0xd390, 0, 8, 0x2f }, - { 0xd145, 4, 1, 0x01 }, - { 0xd1a9, 4, 1, 0x01 }, - { 0xd158, 5, 3, 0x01 }, - { 0xd159, 0, 6, 0x06 }, - { 0xd167, 0, 8, 0x00 }, - { 0xd168, 0, 4, 0x07 }, - { 0xd1c3, 5, 3, 0x00 }, - { 0xd1c4, 0, 6, 0x00 }, - { 0xd1c5, 0, 7, 0x10 }, - { 0xd1c6, 0, 3, 0x02 }, - { 0xd080, 2, 5, 0x03 }, - { 0xd081, 4, 4, 0x09 }, - { 0xd098, 4, 4, 0x0f }, - { 0xd098, 0, 4, 0x03 }, - { 0xdbc0, 3, 1, 0x01 }, - { 0xdbc0, 4, 1, 0x01 }, - { 0xdbc7, 0, 8, 0x08 }, - { 0xdbc8, 4, 4, 0x00 }, - { 0xdbc9, 0, 5, 0x01 }, - { 0xd280, 0, 8, 0xe0 }, - { 0xd281, 0, 8, 0xff }, - { 0xd282, 0, 8, 0xff }, - { 0xd283, 0, 8, 0xc3 }, - { 0xd284, 0, 8, 0xff }, - { 0xd285, 0, 4, 0x01 }, - { 0xd0f0, 0, 7, 0x1a }, - { 0xd0f1, 4, 1, 0x01 }, - { 0xd0f2, 0, 8, 0x0c }, - { 0xd103, 0, 4, 0x08 }, - { 0xd0f8, 0, 7, 0x20 }, - { 0xd111, 5, 1, 0x00 }, - { 0xd111, 6, 1, 0x00 }, - { 0x910b, 0, 8, 0x0a }, - { 0x9115, 0, 8, 0x02 }, - { 0x910c, 0, 8, 0x02 }, - { 0x910d, 0, 8, 0x08 }, - { 0x910e, 0, 8, 0x0a }, - { 0x9bf6, 0, 8, 0x06 }, - { 0x9bf8, 0, 8, 0x02 }, - { 0x9bf7, 0, 8, 0x05 }, - { 0x9bf9, 0, 8, 0x0f }, - { 0x9bfc, 0, 8, 0x13 }, - { 0x9bd3, 0, 8, 0xff }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, -}; - -/* Panasonic ENV77H11D5 tuner init - AF9013_TUNER_ENV77H11D5 = 129 */ -static struct regdesc tuner_init_env77h11d5[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x03 }, - { 0x9bbe, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0xd015, 0, 8, 0x50 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0xeb }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf4 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0xeb }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0x52 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* Microtune MT2060 tuner init - AF9013_TUNER_MT2060 = 130 */ -static struct regdesc tuner_init_mt2060[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x07 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bbe, 0, 1, 0x00 }, - { 0x9bcc, 0, 1, 0x00 }, - { 0x9bb9, 0, 8, 0x75 }, - { 0x9bcd, 0, 8, 0x24 }, - { 0x9bff, 0, 8, 0x30 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x32 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x36 }, - { 0xd00d, 0, 2, 0x03 }, - { 0xd00a, 0, 8, 0x35 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x90 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x36 }, - { 0x9bc6, 0, 8, 0x03 }, - { 0x9bba, 0, 8, 0xc9 }, - { 0x9bc9, 0, 8, 0x79 }, - { 0xd011, 0, 8, 0x10 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0x45 }, - { 0xd014, 0, 2, 0x03 }, - { 0xd040, 0, 8, 0x98 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0xcf }, - { 0xd043, 0, 2, 0x03 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xcc }, - { 0x9be4, 0, 8, 0xa0 }, - { 0x9bbd, 0, 8, 0x8e }, - { 0x9be2, 0, 8, 0x4d }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Microtune MT2060 tuner init - AF9013_TUNER_MT2060_2 = 147 */ -static struct regdesc tuner_init_mt2060_2[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x06 }, - { 0x9bbe, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x32 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x36 }, - { 0xd00d, 0, 2, 0x03 }, - { 0xd00a, 0, 8, 0x35 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x90 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x36 }, - { 0x9bc6, 0, 8, 0x03 }, - { 0x9bba, 0, 8, 0xc9 }, - { 0x9bc9, 0, 8, 0x79 }, - { 0xd011, 0, 8, 0x10 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0x45 }, - { 0xd014, 0, 2, 0x03 }, - { 0xd040, 0, 8, 0x98 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0xcf }, - { 0xd043, 0, 2, 0x03 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 8, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x96 }, - { 0xd054, 0, 8, 0x46 }, - { 0xd045, 7, 1, 0x00 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* MaxLinear MXL5003 tuner init - AF9013_TUNER_MXL5003D = 3 */ -static struct regdesc tuner_init_mxl5003d[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x09 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bfc, 0, 8, 0x0f }, - { 0x9bf6, 0, 8, 0x01 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0xd015, 0, 8, 0x33 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x40 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x6c }, - { 0xd007, 0, 2, 0x00 }, - { 0xd00c, 0, 8, 0x3d }, - { 0xd00d, 0, 2, 0x00 }, - { 0xd00a, 0, 8, 0x45 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x07 }, - { 0x9bc8, 0, 8, 0x52 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x3d }, - { 0x9bc6, 0, 8, 0x00 }, - { 0x9bba, 0, 8, 0xa2 }, - { 0x9bc9, 0, 8, 0xa0 }, - { 0xd011, 0, 8, 0x56 }, - { 0xd012, 0, 2, 0x00 }, - { 0xd013, 0, 8, 0x50 }, - { 0xd014, 0, 2, 0x00 }, - { 0xd040, 0, 8, 0x56 }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0x50 }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 8, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* MaxLinear MXL5005 tuner init - AF9013_TUNER_MXL5005D = 13 - AF9013_TUNER_MXL5005R = 30 */ -static struct regdesc tuner_init_mxl5005[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x07 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x28 }, - { 0x9bff, 0, 8, 0x24 }, - { 0xd015, 0, 8, 0x40 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x40 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x73 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0xfa }, - { 0xd00d, 0, 2, 0x01 }, - { 0xd00a, 0, 8, 0xff }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x23 }, - { 0x9bc8, 0, 8, 0x55 }, - { 0x9bc3, 0, 8, 0x01 }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0xfa }, - { 0x9bc6, 0, 8, 0x01 }, - { 0x9bba, 0, 8, 0xff }, - { 0x9bc9, 0, 8, 0xff }, - { 0x9bd3, 0, 8, 0x95 }, - { 0xd011, 0, 8, 0x70 }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xfb }, - { 0xd014, 0, 2, 0x01 }, - { 0xd040, 0, 8, 0x70 }, - { 0xd041, 0, 2, 0x01 }, - { 0xd042, 0, 8, 0xfb }, - { 0xd043, 0, 2, 0x01 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0x93 }, - { 0x9be4, 0, 8, 0xfe }, - { 0x9bbd, 0, 8, 0x63 }, - { 0x9be2, 0, 8, 0xfe }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Quantek QT1010 tuner init - AF9013_TUNER_QT1010 = 134 - AF9013_TUNER_QT1010A = 162 */ -static struct regdesc tuner_init_qt1010[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x09 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x28 }, - { 0x9bff, 0, 8, 0x20 }, - { 0xd008, 0, 8, 0x0f }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x99 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x0f }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0x50 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x00 }, - { 0x9bc8, 0, 8, 0x00 }, - { 0x9bc3, 0, 8, 0x0f }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x0f }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bba, 0, 8, 0xc5 }, - { 0x9bc9, 0, 8, 0xff }, - { 0xd011, 0, 8, 0x58 }, - { 0xd012, 0, 2, 0x02 }, - { 0xd013, 0, 8, 0x89 }, - { 0xd014, 0, 2, 0x01 }, - { 0xd040, 0, 8, 0x58 }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x89 }, - { 0xd043, 0, 2, 0x01 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xcd }, - { 0x9be4, 0, 8, 0xbb }, - { 0x9bbd, 0, 8, 0x93 }, - { 0x9be2, 0, 8, 0x80 }, - { 0x9bee, 0, 1, 0x01 }, -}; - -/* Freescale MC44S803 tuner init - AF9013_TUNER_MC44S803 = 133 */ -static struct regdesc tuner_init_mc44s803[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x06 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x00 }, - { 0x9be3, 0, 8, 0x00 }, - { 0x9bf6, 0, 8, 0x01 }, - { 0x9bf8, 0, 8, 0x02 }, - { 0x9bf9, 0, 8, 0x02 }, - { 0x9bfc, 0, 8, 0x1f }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x24 }, - { 0x9bff, 0, 8, 0x24 }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0x01 }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x7b }, - { 0xd007, 0, 2, 0x00 }, - { 0xd00c, 0, 8, 0x7c }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xfe }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bc7, 0, 8, 0x08 }, - { 0x9bc8, 0, 8, 0x9a }, - { 0x9bc3, 0, 8, 0x01 }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x7c }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bba, 0, 8, 0xfc }, - { 0x9bc9, 0, 8, 0xaa }, - { 0xd011, 0, 8, 0x6b }, - { 0xd012, 0, 2, 0x00 }, - { 0xd013, 0, 8, 0x88 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x6b }, - { 0xd041, 0, 2, 0x00 }, - { 0xd042, 0, 8, 0x7c }, - { 0xd043, 0, 2, 0x02 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0x9e }, - { 0x9be4, 0, 8, 0xff }, - { 0x9bbd, 0, 8, 0x9e }, - { 0x9be2, 0, 8, 0x25 }, - { 0x9bee, 0, 1, 0x01 }, - { 0xd73b, 3, 1, 0x00 }, -}; - -/* unknown, probably for tin can tuner, tuner init - AF9013_TUNER_UNKNOWN = 140 */ -static struct regdesc tuner_init_unknown[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x02 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x18 }, - { 0x9bff, 0, 8, 0x2c }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x00 }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf6 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc8, 0, 8, 0xaa }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x00 }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0xf0 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, -}; - -/* NXP TDA18271 tuner init - AF9013_TUNER_TDA18271 = 156 */ -static struct regdesc tuner_init_tda18271[] = { - { 0x9bd5, 0, 8, 0x01 }, - { 0x9bd6, 0, 8, 0x04 }, - { 0xd1a0, 1, 1, 0x01 }, - { 0xd000, 0, 1, 0x01 }, - { 0xd000, 1, 1, 0x00 }, - { 0xd001, 1, 1, 0x01 }, - { 0xd001, 0, 1, 0x00 }, - { 0xd001, 5, 1, 0x00 }, - { 0xd002, 0, 5, 0x19 }, - { 0xd003, 0, 5, 0x1a }, - { 0xd004, 0, 5, 0x19 }, - { 0xd005, 0, 5, 0x1a }, - { 0xd00e, 0, 5, 0x10 }, - { 0xd00f, 0, 3, 0x04 }, - { 0xd00f, 3, 3, 0x05 }, - { 0xd010, 0, 3, 0x04 }, - { 0xd010, 3, 3, 0x05 }, - { 0xd016, 4, 4, 0x03 }, - { 0xd01f, 0, 6, 0x0a }, - { 0xd020, 0, 6, 0x0a }, - { 0x9bda, 0, 8, 0x01 }, - { 0x9be3, 0, 8, 0x01 }, - { 0xd1a0, 1, 1, 0x00 }, - { 0x9bbe, 0, 1, 0x01 }, - { 0x9bcc, 0, 1, 0x01 }, - { 0x9bb9, 0, 8, 0x00 }, - { 0x9bcd, 0, 8, 0x18 }, - { 0x9bff, 0, 8, 0x2c }, - { 0xd015, 0, 8, 0x46 }, - { 0xd016, 0, 1, 0x00 }, - { 0xd044, 0, 8, 0x46 }, - { 0xd045, 0, 1, 0x00 }, - { 0xd008, 0, 8, 0xdf }, - { 0xd009, 0, 2, 0x02 }, - { 0xd006, 0, 8, 0x44 }, - { 0xd007, 0, 2, 0x01 }, - { 0xd00c, 0, 8, 0x00 }, - { 0xd00d, 0, 2, 0x02 }, - { 0xd00a, 0, 8, 0xf6 }, - { 0xd00b, 0, 2, 0x01 }, - { 0x9bba, 0, 8, 0xf9 }, - { 0x9bc8, 0, 8, 0xaa }, - { 0x9bc3, 0, 8, 0xdf }, - { 0x9bc4, 0, 8, 0x02 }, - { 0x9bc5, 0, 8, 0x00 }, - { 0x9bc6, 0, 8, 0x02 }, - { 0x9bc9, 0, 8, 0xf0 }, - { 0xd011, 0, 8, 0x3c }, - { 0xd012, 0, 2, 0x01 }, - { 0xd013, 0, 8, 0xf7 }, - { 0xd014, 0, 2, 0x02 }, - { 0xd040, 0, 8, 0x0b }, - { 0xd041, 0, 2, 0x02 }, - { 0xd042, 0, 8, 0x4d }, - { 0xd043, 0, 2, 0x00 }, - { 0xd045, 1, 1, 0x00 }, - { 0x9bcf, 0, 1, 0x01 }, - { 0xd045, 2, 1, 0x01 }, - { 0xd04f, 0, 8, 0x9a }, - { 0xd050, 0, 1, 0x01 }, - { 0xd051, 0, 8, 0x5a }, - { 0xd052, 0, 1, 0x01 }, - { 0xd053, 0, 8, 0x50 }, - { 0xd054, 0, 8, 0x46 }, - { 0x9bd7, 0, 8, 0x0a }, - { 0x9bd8, 0, 8, 0x14 }, - { 0x9bd9, 0, 8, 0x08 }, - { 0x9bd0, 0, 8, 0xa8 }, - { 0x9be4, 0, 8, 0x7f }, - { 0x9bbd, 0, 8, 0xa8 }, - { 0x9be2, 0, 8, 0x20 }, - { 0x9bee, 0, 1, 0x01 }, -}; - -#endif /* _AF9013_PRIV_ */ diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c deleted file mode 100644 index eabf9a68e7e..00000000000 --- a/drivers/media/dvb/frontends/au8522.c +++ /dev/null @@ -1,874 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "au8522.h" - -struct au8522_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct au8522_config *config; - - struct dvb_frontend frontend; - - u32 current_frequency; - fe_modulation_t current_modulation; - - u32 fe_status; - unsigned int led_state; -}; - -static int debug; - -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ - } while (0) - -/* 16 bit registers, 8 bit values */ -static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) -{ - int ret; - u8 buf [] = { reg >> 8, reg & 0xff, data }; - - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 3 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 au8522_readreg(struct au8522_state *state, u16 reg) -{ - int ret; - u8 b0 [] = { reg >> 8, reg & 0xff }; - u8 b1 [] = { 0 }; - - struct i2c_msg msg [] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - return b1[0]; -} - -static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct au8522_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return au8522_writereg(state, 0x106, 1); - else - return au8522_writereg(state, 0x106, 0); -} - -struct mse2snr_tab { - u16 val; - u16 data; -}; - -/* VSB SNR lookup table */ -static struct mse2snr_tab vsb_mse2snr_tab[] = { - { 0, 270 }, - { 2, 250 }, - { 3, 240 }, - { 5, 230 }, - { 7, 220 }, - { 9, 210 }, - { 12, 200 }, - { 13, 195 }, - { 15, 190 }, - { 17, 185 }, - { 19, 180 }, - { 21, 175 }, - { 24, 170 }, - { 27, 165 }, - { 31, 160 }, - { 32, 158 }, - { 33, 156 }, - { 36, 152 }, - { 37, 150 }, - { 39, 148 }, - { 40, 146 }, - { 41, 144 }, - { 43, 142 }, - { 44, 140 }, - { 48, 135 }, - { 50, 130 }, - { 43, 142 }, - { 53, 125 }, - { 56, 120 }, - { 256, 115 }, -}; - -/* QAM64 SNR lookup table */ -static struct mse2snr_tab qam64_mse2snr_tab[] = { - { 15, 0 }, - { 16, 290 }, - { 17, 288 }, - { 18, 286 }, - { 19, 284 }, - { 20, 282 }, - { 21, 281 }, - { 22, 279 }, - { 23, 277 }, - { 24, 275 }, - { 25, 273 }, - { 26, 271 }, - { 27, 269 }, - { 28, 268 }, - { 29, 266 }, - { 30, 264 }, - { 31, 262 }, - { 32, 260 }, - { 33, 259 }, - { 34, 258 }, - { 35, 256 }, - { 36, 255 }, - { 37, 254 }, - { 38, 252 }, - { 39, 251 }, - { 40, 250 }, - { 41, 249 }, - { 42, 248 }, - { 43, 246 }, - { 44, 245 }, - { 45, 244 }, - { 46, 242 }, - { 47, 241 }, - { 48, 240 }, - { 50, 239 }, - { 51, 238 }, - { 53, 237 }, - { 54, 236 }, - { 56, 235 }, - { 57, 234 }, - { 59, 233 }, - { 60, 232 }, - { 62, 231 }, - { 63, 230 }, - { 65, 229 }, - { 67, 228 }, - { 68, 227 }, - { 70, 226 }, - { 71, 225 }, - { 73, 224 }, - { 74, 223 }, - { 76, 222 }, - { 78, 221 }, - { 80, 220 }, - { 82, 219 }, - { 85, 218 }, - { 88, 217 }, - { 90, 216 }, - { 92, 215 }, - { 93, 214 }, - { 94, 212 }, - { 95, 211 }, - { 97, 210 }, - { 99, 209 }, - { 101, 208 }, - { 102, 207 }, - { 104, 206 }, - { 107, 205 }, - { 111, 204 }, - { 114, 203 }, - { 118, 202 }, - { 122, 201 }, - { 125, 200 }, - { 128, 199 }, - { 130, 198 }, - { 132, 197 }, - { 256, 190 }, -}; - -/* QAM256 SNR lookup table */ -static struct mse2snr_tab qam256_mse2snr_tab[] = { - { 16, 0 }, - { 17, 400 }, - { 18, 398 }, - { 19, 396 }, - { 20, 394 }, - { 21, 392 }, - { 22, 390 }, - { 23, 388 }, - { 24, 386 }, - { 25, 384 }, - { 26, 382 }, - { 27, 380 }, - { 28, 379 }, - { 29, 378 }, - { 30, 377 }, - { 31, 376 }, - { 32, 375 }, - { 33, 374 }, - { 34, 373 }, - { 35, 372 }, - { 36, 371 }, - { 37, 370 }, - { 38, 362 }, - { 39, 354 }, - { 40, 346 }, - { 41, 338 }, - { 42, 330 }, - { 43, 328 }, - { 44, 326 }, - { 45, 324 }, - { 46, 322 }, - { 47, 320 }, - { 48, 319 }, - { 49, 318 }, - { 50, 317 }, - { 51, 316 }, - { 52, 315 }, - { 53, 314 }, - { 54, 313 }, - { 55, 312 }, - { 56, 311 }, - { 57, 310 }, - { 58, 308 }, - { 59, 306 }, - { 60, 304 }, - { 61, 302 }, - { 62, 300 }, - { 63, 298 }, - { 65, 295 }, - { 68, 294 }, - { 70, 293 }, - { 73, 292 }, - { 76, 291 }, - { 78, 290 }, - { 79, 289 }, - { 81, 288 }, - { 82, 287 }, - { 83, 286 }, - { 84, 285 }, - { 85, 284 }, - { 86, 283 }, - { 88, 282 }, - { 89, 281 }, - { 256, 280 }, -}; - -static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse, - u16 *snr) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < sz; i++) { - if (mse < tab[i].val) { - *snr = tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int au8522_set_if(struct dvb_frontend *fe, enum au8522_if_freq if_freq) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 r0b5, r0b6, r0b7; - char *ifmhz; - - switch (if_freq) { - case AU8522_IF_3_25MHZ: - ifmhz = "3.25"; - r0b5 = 0x00; - r0b6 = 0x3d; - r0b7 = 0xa0; - break; - case AU8522_IF_4MHZ: - ifmhz = "4.00"; - r0b5 = 0x00; - r0b6 = 0x4b; - r0b7 = 0xd9; - break; - case AU8522_IF_6MHZ: - ifmhz = "6.00"; - r0b5 = 0xfb; - r0b6 = 0x8e; - r0b7 = 0x39; - break; - default: - dprintk("%s() IF Frequency not supported\n", __func__); - return -EINVAL; - } - dprintk("%s() %s MHz\n", __func__, ifmhz); - au8522_writereg(state, 0x80b5, r0b5); - au8522_writereg(state, 0x80b6, r0b6); - au8522_writereg(state, 0x80b7, r0b7); - - return 0; -} - -/* VSB Modulation table */ -static struct { - u16 reg; - u16 data; -} VSB_mod_tab[] = { - { 0x8090, 0x84 }, - { 0x4092, 0x11 }, - { 0x2005, 0x00 }, - { 0x8091, 0x80 }, - { 0x80a3, 0x0c }, - { 0x80a4, 0xe8 }, - { 0x8081, 0xc4 }, - { 0x80a5, 0x40 }, - { 0x80a7, 0x40 }, - { 0x80a6, 0x67 }, - { 0x8262, 0x20 }, - { 0x821c, 0x30 }, - { 0x80d8, 0x1a }, - { 0x8227, 0xa0 }, - { 0x8121, 0xff }, - { 0x80a8, 0xf0 }, - { 0x80a9, 0x05 }, - { 0x80aa, 0x77 }, - { 0x80ab, 0xf0 }, - { 0x80ac, 0x05 }, - { 0x80ad, 0x77 }, - { 0x80ae, 0x41 }, - { 0x80af, 0x66 }, - { 0x821b, 0xcc }, - { 0x821d, 0x80 }, - { 0x80a4, 0xe8 }, - { 0x8231, 0x13 }, -}; - -/* QAM Modulation table */ -static struct { - u16 reg; - u16 data; -} QAM_mod_tab[] = { - { 0x80a3, 0x09 }, - { 0x80a4, 0x00 }, - { 0x8081, 0xc4 }, - { 0x80a5, 0x40 }, - { 0x80aa, 0x77 }, - { 0x80ad, 0x77 }, - { 0x80a6, 0x67 }, - { 0x8262, 0x20 }, - { 0x821c, 0x30 }, - { 0x80b8, 0x3e }, - { 0x80b9, 0xf0 }, - { 0x80ba, 0x01 }, - { 0x80bb, 0x18 }, - { 0x80bc, 0x50 }, - { 0x80bd, 0x00 }, - { 0x80be, 0xea }, - { 0x80bf, 0xef }, - { 0x80c0, 0xfc }, - { 0x80c1, 0xbd }, - { 0x80c2, 0x1f }, - { 0x80c3, 0xfc }, - { 0x80c4, 0xdd }, - { 0x80c5, 0xaf }, - { 0x80c6, 0x00 }, - { 0x80c7, 0x38 }, - { 0x80c8, 0x30 }, - { 0x80c9, 0x05 }, - { 0x80ca, 0x4a }, - { 0x80cb, 0xd0 }, - { 0x80cc, 0x01 }, - { 0x80cd, 0xd9 }, - { 0x80ce, 0x6f }, - { 0x80cf, 0xf9 }, - { 0x80d0, 0x70 }, - { 0x80d1, 0xdf }, - { 0x80d2, 0xf7 }, - { 0x80d3, 0xc2 }, - { 0x80d4, 0xdf }, - { 0x80d5, 0x02 }, - { 0x80d6, 0x9a }, - { 0x80d7, 0xd0 }, - { 0x8250, 0x0d }, - { 0x8251, 0xcd }, - { 0x8252, 0xe0 }, - { 0x8253, 0x05 }, - { 0x8254, 0xa7 }, - { 0x8255, 0xff }, - { 0x8256, 0xed }, - { 0x8257, 0x5b }, - { 0x8258, 0xae }, - { 0x8259, 0xe6 }, - { 0x825a, 0x3d }, - { 0x825b, 0x0f }, - { 0x825c, 0x0d }, - { 0x825d, 0xea }, - { 0x825e, 0xf2 }, - { 0x825f, 0x51 }, - { 0x8260, 0xf5 }, - { 0x8261, 0x06 }, - { 0x821a, 0x00 }, - { 0x8546, 0x40 }, - { 0x8210, 0x26 }, - { 0x8211, 0xf6 }, - { 0x8212, 0x84 }, - { 0x8213, 0x02 }, - { 0x8502, 0x01 }, - { 0x8121, 0x04 }, - { 0x8122, 0x04 }, - { 0x852e, 0x10 }, - { 0x80a4, 0xca }, - { 0x80a7, 0x40 }, - { 0x8526, 0x01 }, -}; - -static int au8522_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct au8522_state *state = fe->demodulator_priv; - int i; - - dprintk("%s(0x%08x)\n", __func__, m); - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++) - au8522_writereg(state, - VSB_mod_tab[i].reg, - VSB_mod_tab[i].data); - au8522_set_if(fe, state->config->vsb_if); - break; - case QAM_64: - case QAM_256: - dprintk("%s() QAM 64/256\n", __func__); - for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++) - au8522_writereg(state, - QAM_mod_tab[i].reg, - QAM_mod_tab[i].data); - au8522_set_if(fe, state->config->qam_if); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - - return 0; -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int au8522_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - if ((state->current_frequency == p->frequency) && - (state->current_modulation == p->u.vsb.modulation)) - return 0; - - au8522_enable_modulation(fe, p->u.vsb.modulation); - - /* Allow the demod to settle */ - msleep(100); - - if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - if (ret < 0) - return ret; - - state->current_frequency = p->frequency; - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int au8522_init(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - au8522_writereg(state, 0xa4, 1 << 5); - - au8522_i2c_gate_ctrl(fe, 1); - - return 0; -} - -static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - u8 val; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_output || - !led_config->gpio_output_enable || !led_config->gpio_output_disable) - return 0; - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_output & ~0xc000)); - if (onoff) { - /* enable GPIO output */ - val &= ~((led_config->gpio_output_enable >> 8) & 0xff); - val |= (led_config->gpio_output_enable & 0xff); - } else { - /* disable GPIO output */ - val &= ~((led_config->gpio_output_disable >> 8) & 0xff); - val |= (led_config->gpio_output_disable & 0xff); - } - return au8522_writereg(state, 0x8000 | - (led_config->gpio_output & ~0xc000), val); -} - -/* led = 0 | off - * led = 1 | signal ok - * led = 2 | signal strong - * led < 0 | only light led if leds are currently off - */ -static int au8522_led_ctrl(struct au8522_state *state, int led) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int i, ret = 0; - - /* bail out if we cant control an LED */ - if (!led_config || !led_config->gpio_leds || - !led_config->num_led_states || !led_config->led_states) - return 0; - - if (led < 0) { - /* if LED is already lit, then leave it as-is */ - if (state->led_state) - return 0; - else - led *= -1; - } - - /* toggle LED if changing state */ - if (state->led_state != led) { - u8 val; - - dprintk("%s: %d\n", __func__, led); - - au8522_led_gpio_enable(state, 1); - - val = au8522_readreg(state, 0x4000 | - (led_config->gpio_leds & ~0xc000)); - - /* start with all leds off */ - for (i = 0; i < led_config->num_led_states; i++) - val &= ~led_config->led_states[i]; - - /* set selected LED state */ - if (led < led_config->num_led_states) - val |= led_config->led_states[led]; - else if (led_config->num_led_states) - val |= - led_config->led_states[led_config->num_led_states - 1]; - - ret = au8522_writereg(state, 0x8000 | - (led_config->gpio_leds & ~0xc000), val); - if (ret < 0) - return ret; - - state->led_state = led; - - if (led == 0) - au8522_led_gpio_enable(state, 0); - } - - return 0; -} - -static int au8522_sleep(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - /* turn off led */ - au8522_led_ctrl(state, 0); - - state->current_frequency = 0; - - return 0; -} - -static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct au8522_state *state = fe->demodulator_priv; - u8 reg; - u32 tuner_status = 0; - - *status = 0; - - if (state->current_modulation == VSB_8) { - dprintk("%s() Checking VSB_8\n", __func__); - reg = au8522_readreg(state, 0x4088); - if ((reg & 0x03) == 0x03) - *status |= FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; - } else { - dprintk("%s() Checking QAM\n", __func__); - reg = au8522_readreg(state, 0x4541); - if (reg & 0x80) - *status |= FE_HAS_VITERBI; - if (reg & 0x20) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - } - - switch (state->config->status_mode) { - case AU8522_DEMODLOCKING: - dprintk("%s() DEMODLOCKING\n", __func__); - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case AU8522_TUNERLOCKING: - /* Get the tuner status */ - dprintk("%s() TUNERLOCKING\n", __func__); - if (fe->ops.tuner_ops.get_status) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.get_status(fe, &tuner_status); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (tuner_status) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - } - state->fe_status = *status; - - if (*status & FE_HAS_LOCK) - /* turn on LED, if it isn't on already */ - au8522_led_ctrl(state, -1); - else - /* turn off LED */ - au8522_led_ctrl(state, 0); - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int au8522_led_status(struct au8522_state *state, const u16 *snr) -{ - struct au8522_led_config *led_config = state->config->led_cfg; - int led; - u16 strong; - - /* bail out if we cant control an LED */ - if (!led_config) - return 0; - - if (0 == (state->fe_status & FE_HAS_LOCK)) - return au8522_led_ctrl(state, 0); - else if (state->current_modulation == QAM_256) - strong = led_config->qam256_strong; - else if (state->current_modulation == QAM_64) - strong = led_config->qam64_strong; - else /* (state->current_modulation == VSB_8) */ - strong = led_config->vsb8_strong; - - if (*snr >= strong) - led = 2; - else - led = 1; - - if ((state->led_state) && - (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10)) - /* snr didn't change enough to bother - * changing the color of the led */ - return 0; - - return au8522_led_ctrl(state, led); -} - -static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct au8522_state *state = fe->demodulator_priv; - int ret = -EINVAL; - - dprintk("%s()\n", __func__); - - if (state->current_modulation == QAM_256) - ret = au8522_mse2snr_lookup(qam256_mse2snr_tab, - ARRAY_SIZE(qam256_mse2snr_tab), - au8522_readreg(state, 0x4522), - snr); - else if (state->current_modulation == QAM_64) - ret = au8522_mse2snr_lookup(qam64_mse2snr_tab, - ARRAY_SIZE(qam64_mse2snr_tab), - au8522_readreg(state, 0x4522), - snr); - else /* VSB_8 */ - ret = au8522_mse2snr_lookup(vsb_mse2snr_tab, - ARRAY_SIZE(vsb_mse2snr_tab), - au8522_readreg(state, 0x4311), - snr); - - if (state->config->led_cfg) - au8522_led_status(state, snr); - - return ret; -} - -static int au8522_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return au8522_read_snr(fe, signal_strength); -} - -static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct au8522_state *state = fe->demodulator_priv; - - if (state->current_modulation == VSB_8) - *ucblocks = au8522_readreg(state, 0x4087); - else - *ucblocks = au8522_readreg(state, 0x4543); - - return 0; -} - -static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return au8522_read_ucblocks(fe, ber); -} - -static int au8522_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct au8522_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int au8522_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void au8522_release(struct dvb_frontend *fe) -{ - struct au8522_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops au8522_ops; - -struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c) -{ - struct au8522_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &au8522_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - if (au8522_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - au8522_i2c_gate_ctrl(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(au8522_attach); - -static struct dvb_frontend_ops au8522_ops = { - - .info = { - .name = "Auvitek AU8522 QAM/8VSB Frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .init = au8522_init, - .sleep = au8522_sleep, - .i2c_gate_ctrl = au8522_i2c_gate_ctrl, - .set_frontend = au8522_set_frontend, - .get_frontend = au8522_get_frontend, - .get_tune_settings = au8522_get_tune_settings, - .read_status = au8522_read_status, - .read_ber = au8522_read_ber, - .read_signal_strength = au8522_read_signal_strength, - .read_snr = au8522_read_snr, - .read_ucblocks = au8522_read_ucblocks, - .release = au8522_release, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h deleted file mode 100644 index 7b94f554a09..00000000000 --- a/drivers/media/dvb/frontends/au8522.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - Auvitek AU8522 QAM/8VSB demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __AU8522_H__ -#define __AU8522_H__ - -#include <linux/dvb/frontend.h> - -enum au8522_if_freq { - AU8522_IF_6MHZ = 0, - AU8522_IF_4MHZ, - AU8522_IF_3_25MHZ, -}; - -struct au8522_led_config { - u16 vsb8_strong; - u16 qam64_strong; - u16 qam256_strong; - - u16 gpio_output; - /* unset hi bits, set low bits */ - u16 gpio_output_enable; - u16 gpio_output_disable; - - u16 gpio_leds; - u8 *led_states; - unsigned int num_led_states; -}; - -struct au8522_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* Return lock status based on tuner lock, or demod lock */ -#define AU8522_TUNERLOCKING 0 -#define AU8522_DEMODLOCKING 1 - u8 status_mode; - - struct au8522_led_config *led_cfg; - - enum au8522_if_freq vsb_if; - enum au8522_if_freq qam_if; -}; - -#if defined(CONFIG_DVB_AU8522) || \ - (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE)) -extern struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c); -#else -static inline -struct dvb_frontend *au8522_attach(const struct au8522_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_AU8522 */ - -#endif /* __AU8522_H__ */ - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/bcm3510.c b/drivers/media/dvb/frontends/bcm3510.c deleted file mode 100644 index cf5e576dfdc..00000000000 --- a/drivers/media/dvb/frontends/bcm3510.c +++ /dev/null @@ -1,854 +0,0 @@ -/* - * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) - * - * Copyright (C) 2001-5, B2C2 inc. - * - * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de> - * - * This driver is "hard-coded" to be used with the 1st generation of - * Technisat/B2C2's Air2PC ATSC PCI/USB cards/boxes. The pll-programming - * (Panasonic CT10S) is located here, which is actually wrong. Unless there is - * another device with a BCM3510, this is no problem. - * - * The driver works also with QAM64 DVB-C, but had an unreasonable high - * UNC. (Tested with the Air2PC ATSC 1st generation) - * - * You'll need a firmware for this driver in order to get it running. It is - * called "dvb-fe-bcm3510-01.fw". - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 Mass - * Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -#include "dvb_frontend.h" -#include "bcm3510.h" -#include "bcm3510_priv.h" - -struct bcm3510_state { - - struct i2c_adapter* i2c; - const struct bcm3510_config* config; - struct dvb_frontend frontend; - - /* demodulator private data */ - struct mutex hab_mutex; - u8 firmware_loaded:1; - - unsigned long next_status_check; - unsigned long status_check_interval; - struct bcm3510_hab_cmd_status1 status1; - struct bcm3510_hab_cmd_status2 status2; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c (|-able))."); - -#define dprintk(level,x...) if (level & debug) printk(x) -#define dbufout(b,l,m) {\ - int i; \ - for (i = 0; i < l; i++) \ - m("%02x ",b[i]); \ -} -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_hab(args...) dprintk(0x04,args) - -/* transfer functions */ -static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len) -{ - u8 b[256]; - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = len + 1 }; - - b[0] = reg; - memcpy(&b[1],buf,len); - - deb_i2c("i2c wr %02x: ",reg); - dbufout(buf,len,deb_i2c); - deb_i2c("\n"); - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - - deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n", - __func__, state->config->demod_address, reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 len) -{ - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } - }; - int err; - - memset(buf,0,len); - - if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { - deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n", - __func__, state->config->demod_address, reg, err); - return -EREMOTEIO; - } - deb_i2c("i2c rd %02x: ",reg); - dbufout(buf,len,deb_i2c); - deb_i2c("\n"); - - return 0; -} - -static int bcm3510_writeB(struct bcm3510_state *state, u8 reg, bcm3510_register_value v) -{ - return bcm3510_writebytes(state,reg,&v.raw,1); -} - -static int bcm3510_readB(struct bcm3510_state *state, u8 reg, bcm3510_register_value *v) -{ - return bcm3510_readbytes(state,reg,&v->raw,1); -} - -/* Host Access Buffer transfers */ -static int bcm3510_hab_get_response(struct bcm3510_state *st, u8 *buf, int len) -{ - bcm3510_register_value v; - int ret,i; - - v.HABADR_a6.HABADR = 0; - if ((ret = bcm3510_writeB(st,0xa6,v)) < 0) - return ret; - - for (i = 0; i < len; i++) { - if ((ret = bcm3510_readB(st,0xa7,&v)) < 0) - return ret; - buf[i] = v.HABDATA_a7; - } - return 0; -} - -static int bcm3510_hab_send_request(struct bcm3510_state *st, u8 *buf, int len) -{ - bcm3510_register_value v,hab; - int ret,i; - unsigned long t; - -/* Check if any previous HAB request still needs to be serviced by the - * Aquisition Processor before sending new request */ - if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) - return ret; - if (v.HABSTAT_a8.HABR) { - deb_info("HAB is running already - clearing it.\n"); - v.HABSTAT_a8.HABR = 0; - bcm3510_writeB(st,0xa8,v); -// return -EBUSY; - } - -/* Send the start HAB Address (automatically incremented after write of - * HABDATA) and write the HAB Data */ - hab.HABADR_a6.HABADR = 0; - if ((ret = bcm3510_writeB(st,0xa6,hab)) < 0) - return ret; - - for (i = 0; i < len; i++) { - hab.HABDATA_a7 = buf[i]; - if ((ret = bcm3510_writeB(st,0xa7,hab)) < 0) - return ret; - } - -/* Set the HABR bit to indicate AP request in progress (LBHABR allows HABR to - * be written) */ - v.raw = 0; v.HABSTAT_a8.HABR = 1; v.HABSTAT_a8.LDHABR = 1; - if ((ret = bcm3510_writeB(st,0xa8,v)) < 0) - return ret; - -/* Polling method: Wait until the AP finishes processing the HAB request */ - t = jiffies + 1*HZ; - while (time_before(jiffies, t)) { - deb_info("waiting for HAB to complete\n"); - msleep(10); - if ((ret = bcm3510_readB(st,0xa8,&v)) < 0) - return ret; - - if (!v.HABSTAT_a8.HABR) - return 0; - } - - deb_info("send_request execution timed out.\n"); - return -ETIMEDOUT; -} - -static int bcm3510_do_hab_cmd(struct bcm3510_state *st, u8 cmd, u8 msgid, u8 *obuf, u8 olen, u8 *ibuf, u8 ilen) -{ - u8 ob[olen+2],ib[ilen+2]; - int ret = 0; - - ob[0] = cmd; - ob[1] = msgid; - memcpy(&ob[2],obuf,olen); - - deb_hab("hab snd: "); - dbufout(ob,olen+2,deb_hab); - deb_hab("\n"); - - if (mutex_lock_interruptible(&st->hab_mutex) < 0) - return -EAGAIN; - - if ((ret = bcm3510_hab_send_request(st, ob, olen+2)) < 0 || - (ret = bcm3510_hab_get_response(st, ib, ilen+2)) < 0) - goto error; - - deb_hab("hab get: "); - dbufout(ib,ilen+2,deb_hab); - deb_hab("\n"); - - memcpy(ibuf,&ib[2],ilen); -error: - mutex_unlock(&st->hab_mutex); - return ret; -} - -#if 0 -/* not needed, we use a semaphore to prevent HAB races */ -static int bcm3510_is_ap_ready(struct bcm3510_state *st) -{ - bcm3510_register_value ap,hab; - int ret; - - if ((ret = bcm3510_readB(st,0xa8,&hab)) < 0 || - (ret = bcm3510_readB(st,0xa2,&ap) < 0)) - return ret; - - if (ap.APSTAT1_a2.RESET || ap.APSTAT1_a2.IDLE || ap.APSTAT1_a2.STOP || hab.HABSTAT_a8.HABR) { - deb_info("AP is busy\n"); - return -EBUSY; - } - - return 0; -} -#endif - -static int bcm3510_bert_reset(struct bcm3510_state *st) -{ - bcm3510_register_value b; - int ret; - - if ((ret = bcm3510_readB(st,0xfa,&b)) < 0) - return ret; - - b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); - b.BERCTL_fa.RESYNC = 1; bcm3510_writeB(st,0xfa,b); - b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); - b.BERCTL_fa.CNTCTL = 1; b.BERCTL_fa.BITCNT = 1; bcm3510_writeB(st,0xfa,b); - - /* clear residual bit counter TODO */ - return 0; -} - -static int bcm3510_refresh_state(struct bcm3510_state *st) -{ - if (time_after(jiffies,st->next_status_check)) { - bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS1, NULL,0, (u8 *)&st->status1, sizeof(st->status1)); - bcm3510_do_hab_cmd(st, CMD_STATUS, MSGID_STATUS2, NULL,0, (u8 *)&st->status2, sizeof(st->status2)); - st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; - } - return 0; -} - -static int bcm3510_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - - *status = 0; - if (st->status1.STATUS1.RECEIVER_LOCK) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - - if (st->status1.STATUS1.FEC_LOCK) - *status |= FE_HAS_VITERBI; - - if (st->status1.STATUS1.OUT_PLL_LOCK) - *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; - - if (*status & FE_HAS_LOCK) - st->status_check_interval = 1500; - else /* more frequently checks if no lock has been achieved yet */ - st->status_check_interval = 500; - - deb_info("real_status: %02x\n",*status); - return 0; -} - -static int bcm3510_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - - *ber = (st->status2.LDBER0 << 16) | (st->status2.LDBER1 << 8) | st->status2.LDBER2; - return 0; -} - -static int bcm3510_read_unc(struct dvb_frontend* fe, u32* unc) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - *unc = (st->status2.LDUERC0 << 8) | st->status2.LDUERC1; - return 0; -} - -static int bcm3510_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct bcm3510_state* st = fe->demodulator_priv; - s32 t; - - bcm3510_refresh_state(st); - t = st->status2.SIGNAL; - - if (t > 190) - t = 190; - if (t < 90) - t = 90; - - t -= 90; - t = t * 0xff / 100; - /* normalize if necessary */ - *strength = (t << 8) | t; - return 0; -} - -static int bcm3510_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_refresh_state(st); - - *snr = st->status1.SNR_EST0*1000 + ((st->status1.SNR_EST1*1000) >> 8); - return 0; -} - -/* tuner frontend programming */ -static int bcm3510_tuner_cmd(struct bcm3510_state* st,u8 bc, u16 n, u8 a) -{ - struct bcm3510_hab_cmd_tune c; - memset(&c,0,sizeof(struct bcm3510_hab_cmd_tune)); - -/* I2C Mode disabled, set 16 control / Data pairs */ - c.length = 0x10; - c.clock_width = 0; -/* CS1, CS0, DATA, CLK bits control the tuner RF_AGC_SEL pin is set to - * logic high (as Configuration) */ - c.misc = 0x10; -/* Set duration of the initial state of TUNCTL = 3.34 micro Sec */ - c.TUNCTL_state = 0x40; - -/* PRESCALER DEVIDE RATIO | BC1_2_3_4; (band switch), 1stosc REFERENCE COUNTER REF_S12 and REF_S11 */ - c.ctl_dat[0].ctrl.size = BITS_8; - c.ctl_dat[0].data = 0x80 | bc; - -/* Control DATA pin, 1stosc REFERENCE COUNTER REF_S10 to REF_S3 */ - c.ctl_dat[1].ctrl.size = BITS_8; - c.ctl_dat[1].data = 4; - -/* set CONTROL BIT 1 to 1, 1stosc REFERENCE COUNTER REF_S2 to REF_S1 */ - c.ctl_dat[2].ctrl.size = BITS_3; - c.ctl_dat[2].data = 0x20; - -/* control CS0 pin, pulse byte ? */ - c.ctl_dat[3].ctrl.size = BITS_3; - c.ctl_dat[3].ctrl.clk_off = 1; - c.ctl_dat[3].ctrl.cs0 = 1; - c.ctl_dat[3].data = 0x40; - -/* PGM_S18 to PGM_S11 */ - c.ctl_dat[4].ctrl.size = BITS_8; - c.ctl_dat[4].data = n >> 3; - -/* PGM_S10 to PGM_S8, SWL_S7 to SWL_S3 */ - c.ctl_dat[5].ctrl.size = BITS_8; - c.ctl_dat[5].data = ((n & 0x7) << 5) | (a >> 2); - -/* SWL_S2 and SWL_S1, set CONTROL BIT 2 to 0 */ - c.ctl_dat[6].ctrl.size = BITS_3; - c.ctl_dat[6].data = (a << 6) & 0xdf; - -/* control CS0 pin, pulse byte ? */ - c.ctl_dat[7].ctrl.size = BITS_3; - c.ctl_dat[7].ctrl.clk_off = 1; - c.ctl_dat[7].ctrl.cs0 = 1; - c.ctl_dat[7].data = 0x40; - -/* PRESCALER DEVIDE RATIO, 2ndosc REFERENCE COUNTER REF_S12 and REF_S11 */ - c.ctl_dat[8].ctrl.size = BITS_8; - c.ctl_dat[8].data = 0x80; - -/* 2ndosc REFERENCE COUNTER REF_S10 to REF_S3 */ - c.ctl_dat[9].ctrl.size = BITS_8; - c.ctl_dat[9].data = 0x10; - -/* set CONTROL BIT 1 to 1, 2ndosc REFERENCE COUNTER REF_S2 to REF_S1 */ - c.ctl_dat[10].ctrl.size = BITS_3; - c.ctl_dat[10].data = 0x20; - -/* pulse byte */ - c.ctl_dat[11].ctrl.size = BITS_3; - c.ctl_dat[11].ctrl.clk_off = 1; - c.ctl_dat[11].ctrl.cs1 = 1; - c.ctl_dat[11].data = 0x40; - -/* PGM_S18 to PGM_S11 */ - c.ctl_dat[12].ctrl.size = BITS_8; - c.ctl_dat[12].data = 0x2a; - -/* PGM_S10 to PGM_S8 and SWL_S7 to SWL_S3 */ - c.ctl_dat[13].ctrl.size = BITS_8; - c.ctl_dat[13].data = 0x8e; - -/* SWL_S2 and SWL_S1 and set CONTROL BIT 2 to 0 */ - c.ctl_dat[14].ctrl.size = BITS_3; - c.ctl_dat[14].data = 0; - -/* Pulse Byte */ - c.ctl_dat[15].ctrl.size = BITS_3; - c.ctl_dat[15].ctrl.clk_off = 1; - c.ctl_dat[15].ctrl.cs1 = 1; - c.ctl_dat[15].data = 0x40; - - return bcm3510_do_hab_cmd(st,CMD_TUNE, MSGID_TUNE,(u8 *) &c,sizeof(c), NULL, 0); -} - -static int bcm3510_set_freq(struct bcm3510_state* st,u32 freq) -{ - u8 bc,a; - u16 n; - s32 YIntercept,Tfvco1; - - freq /= 1000; - - deb_info("%dkHz:",freq); - /* set Band Switch */ - if (freq <= 168000) - bc = 0x1c; - else if (freq <= 378000) - bc = 0x2c; - else - bc = 0x30; - - if (freq >= 470000) { - freq -= 470001; - YIntercept = 18805; - } else if (freq >= 90000) { - freq -= 90001; - YIntercept = 15005; - } else if (freq >= 76000){ - freq -= 76001; - YIntercept = 14865; - } else { - freq -= 54001; - YIntercept = 14645; - } - - Tfvco1 = (((freq/6000)*60 + YIntercept)*4)/10; - - n = Tfvco1 >> 6; - a = Tfvco1 & 0x3f; - - deb_info(" BC1_2_3_4: %x, N: %x A: %x\n", bc, n, a); - if (n >= 16 && n <= 2047) - return bcm3510_tuner_cmd(st,bc,n,a); - - return -EINVAL; -} - -static int bcm3510_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct bcm3510_state* st = fe->demodulator_priv; - struct bcm3510_hab_cmd_ext_acquire cmd; - struct bcm3510_hab_cmd_bert_control bert; - int ret; - - memset(&cmd,0,sizeof(cmd)); - switch (p->u.vsb.modulation) { - case QAM_256: - cmd.ACQUIRE0.MODE = 0x1; - cmd.ACQUIRE1.SYM_RATE = 0x1; - cmd.ACQUIRE1.IF_FREQ = 0x1; - break; - case QAM_64: - cmd.ACQUIRE0.MODE = 0x2; - cmd.ACQUIRE1.SYM_RATE = 0x2; - cmd.ACQUIRE1.IF_FREQ = 0x1; - break; -/* case QAM_256: - cmd.ACQUIRE0.MODE = 0x3; - break; - case QAM_128: - cmd.ACQUIRE0.MODE = 0x4; - break; - case QAM_64: - cmd.ACQUIRE0.MODE = 0x5; - break; - case QAM_32: - cmd.ACQUIRE0.MODE = 0x6; - break; - case QAM_16: - cmd.ACQUIRE0.MODE = 0x7; - break;*/ - case VSB_8: - cmd.ACQUIRE0.MODE = 0x8; - cmd.ACQUIRE1.SYM_RATE = 0x0; - cmd.ACQUIRE1.IF_FREQ = 0x0; - break; - case VSB_16: - cmd.ACQUIRE0.MODE = 0x9; - cmd.ACQUIRE1.SYM_RATE = 0x0; - cmd.ACQUIRE1.IF_FREQ = 0x0; - default: - return -EINVAL; - }; - cmd.ACQUIRE0.OFFSET = 0; - cmd.ACQUIRE0.NTSCSWEEP = 1; - cmd.ACQUIRE0.FA = 1; - cmd.ACQUIRE0.BW = 0; - -/* if (enableOffset) { - cmd.IF_OFFSET0 = xx; - cmd.IF_OFFSET1 = xx; - - cmd.SYM_OFFSET0 = xx; - cmd.SYM_OFFSET1 = xx; - if (enableNtscSweep) { - cmd.NTSC_OFFSET0; - cmd.NTSC_OFFSET1; - } - } */ - bcm3510_do_hab_cmd(st, CMD_ACQUIRE, MSGID_EXT_TUNER_ACQUIRE, (u8 *) &cmd, sizeof(cmd), NULL, 0); - -/* doing it with different MSGIDs, data book and source differs */ - bert.BE = 0; - bert.unused = 0; - bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_CONTROL, (u8 *) &bert, sizeof(bert), NULL, 0); - bcm3510_do_hab_cmd(st, CMD_STATE_CONTROL, MSGID_BERT_SET, (u8 *) &bert, sizeof(bert), NULL, 0); - - bcm3510_bert_reset(st); - - if ((ret = bcm3510_set_freq(st,p->frequency)) < 0) - return ret; - - memset(&st->status1,0,sizeof(st->status1)); - memset(&st->status2,0,sizeof(st->status2)); - st->status_check_interval = 500; - -/* Give the AP some time */ - msleep(200); - - return 0; -} - -static int bcm3510_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int bcm3510_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *s) -{ - s->min_delay_ms = 1000; - s->step_size = 0; - s->max_drift = 0; - return 0; -} - -static void bcm3510_release(struct dvb_frontend* fe) -{ - struct bcm3510_state* state = fe->demodulator_priv; - kfree(state); -} - -/* firmware download: - * firmware file is build up like this: - * 16bit addr, 16bit length, 8byte of length - */ -#define BCM3510_DEFAULT_FIRMWARE "dvb-fe-bcm3510-01.fw" - -static int bcm3510_write_ram(struct bcm3510_state *st, u16 addr, const u8 *b, - u16 len) -{ - int ret = 0,i; - bcm3510_register_value vH, vL,vD; - - vH.MADRH_a9 = addr >> 8; - vL.MADRL_aa = addr; - if ((ret = bcm3510_writeB(st,0xa9,vH)) < 0) return ret; - if ((ret = bcm3510_writeB(st,0xaa,vL)) < 0) return ret; - - for (i = 0; i < len; i++) { - vD.MDATA_ab = b[i]; - if ((ret = bcm3510_writeB(st,0xab,vD)) < 0) - return ret; - } - - return 0; -} - -static int bcm3510_download_firmware(struct dvb_frontend* fe) -{ - struct bcm3510_state* st = fe->demodulator_priv; - const struct firmware *fw; - u16 addr,len; - const u8 *b; - int ret,i; - - deb_info("requesting firmware\n"); - if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) { - err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); - return ret; - } - deb_info("got firmware: %zd\n",fw->size); - - b = fw->data; - for (i = 0; i < fw->size;) { - addr = le16_to_cpu( *( (u16 *)&b[i] ) ); - len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); - deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); - if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { - err("firmware download failed: %d\n",ret); - return ret; - } - i += 4 + len; - } - release_firmware(fw); - deb_info("firmware download successfully completed\n"); - return 0; -} - -static int bcm3510_check_firmware_version(struct bcm3510_state *st) -{ - struct bcm3510_hab_cmd_get_version_info ver; - bcm3510_do_hab_cmd(st,CMD_GET_VERSION_INFO,MSGID_GET_VERSION_INFO,NULL,0,(u8*)&ver,sizeof(ver)); - - deb_info("Version information: 0x%02x 0x%02x 0x%02x 0x%02x\n", - ver.microcode_version, ver.script_version, ver.config_version, ver.demod_version); - - if (ver.script_version == BCM3510_DEF_SCRIPT_VERSION && - ver.config_version == BCM3510_DEF_CONFIG_VERSION && - ver.demod_version == BCM3510_DEF_DEMOD_VERSION) - return 0; - - deb_info("version check failed\n"); - return -ENODEV; -} - -/* (un)resetting the AP */ -static int bcm3510_reset(struct bcm3510_state *st) -{ - int ret; - unsigned long t; - bcm3510_register_value v; - - bcm3510_readB(st,0xa0,&v); v.HCTL1_a0.RESET = 1; - if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) - return ret; - - t = jiffies + 3*HZ; - while (time_before(jiffies, t)) { - msleep(10); - if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) - return ret; - - if (v.APSTAT1_a2.RESET) - return 0; - } - deb_info("reset timed out\n"); - return -ETIMEDOUT; -} - -static int bcm3510_clear_reset(struct bcm3510_state *st) -{ - bcm3510_register_value v; - int ret; - unsigned long t; - - v.raw = 0; - if ((ret = bcm3510_writeB(st,0xa0,v)) < 0) - return ret; - - t = jiffies + 3*HZ; - while (time_before(jiffies, t)) { - msleep(10); - if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) - return ret; - - /* verify that reset is cleared */ - if (!v.APSTAT1_a2.RESET) - return 0; - } - deb_info("reset clear timed out\n"); - return -ETIMEDOUT; -} - -static int bcm3510_init_cold(struct bcm3510_state *st) -{ - int ret; - bcm3510_register_value v; - - /* read Acquisation Processor status register and check it is not in RUN mode */ - if ((ret = bcm3510_readB(st,0xa2,&v)) < 0) - return ret; - if (v.APSTAT1_a2.RUN) { - deb_info("AP is already running - firmware already loaded.\n"); - return 0; - } - - deb_info("reset?\n"); - if ((ret = bcm3510_reset(st)) < 0) - return ret; - - deb_info("tristate?\n"); - /* tri-state */ - v.TSTCTL_2e.CTL = 0; - if ((ret = bcm3510_writeB(st,0x2e,v)) < 0) - return ret; - - deb_info("firmware?\n"); - if ((ret = bcm3510_download_firmware(&st->frontend)) < 0 || - (ret = bcm3510_clear_reset(st)) < 0) - return ret; - - /* anything left here to Let the acquisition processor begin execution at program counter 0000 ??? */ - - return 0; -} - -static int bcm3510_init(struct dvb_frontend* fe) -{ - struct bcm3510_state* st = fe->demodulator_priv; - bcm3510_register_value j; - struct bcm3510_hab_cmd_set_agc c; - int ret; - - if ((ret = bcm3510_readB(st,0xca,&j)) < 0) - return ret; - - deb_info("JDEC: %02x\n",j.raw); - - switch (j.JDEC_ca.JDEC) { - case JDEC_WAIT_AT_RAM: - deb_info("attempting to download firmware\n"); - if ((ret = bcm3510_init_cold(st)) < 0) - return ret; - case JDEC_EEPROM_LOAD_WAIT: /* fall-through is wanted */ - deb_info("firmware is loaded\n"); - bcm3510_check_firmware_version(st); - break; - default: - return -ENODEV; - } - - memset(&c,0,1); - c.SEL = 1; - bcm3510_do_hab_cmd(st,CMD_AUTO_PARAM,MSGID_SET_RF_AGC_SEL,(u8 *)&c,sizeof(c),NULL,0); - - return 0; -} - - -static struct dvb_frontend_ops bcm3510_ops; - -struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, - struct i2c_adapter *i2c) -{ - struct bcm3510_state* state = NULL; - int ret; - bcm3510_register_value v; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - - state->config = config; - state->i2c = i2c; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &bcm3510_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - mutex_init(&state->hab_mutex); - - if ((ret = bcm3510_readB(state,0xe0,&v)) < 0) - goto error; - - deb_info("Revision: 0x%1x, Layer: 0x%1x.\n",v.REVID_e0.REV,v.REVID_e0.LAYER); - - if ((v.REVID_e0.REV != 0x1 && v.REVID_e0.LAYER != 0xb) && /* cold */ - (v.REVID_e0.REV != 0x8 && v.REVID_e0.LAYER != 0x0)) /* warm */ - goto error; - - info("Revision: 0x%1x, Layer: 0x%1x.",v.REVID_e0.REV,v.REVID_e0.LAYER); - - bcm3510_reset(state); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(bcm3510_attach); - -static struct dvb_frontend_ops bcm3510_ops = { - - .info = { - .name = "Broadcom BCM3510 VSB/QAM frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 803000000, - /* stepsize is just a guess */ - .frequency_stepsize = 0, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_8VSB | FE_CAN_16VSB | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 - }, - - .release = bcm3510_release, - - .init = bcm3510_init, - .sleep = bcm3510_sleep, - - .set_frontend = bcm3510_set_frontend, - .get_tune_settings = bcm3510_get_tune_settings, - - .read_status = bcm3510_read_status, - .read_ber = bcm3510_read_ber, - .read_signal_strength = bcm3510_read_signal_strength, - .read_snr = bcm3510_read_snr, - .read_ucblocks = bcm3510_read_unc, -}; - -MODULE_DESCRIPTION("Broadcom BCM3510 ATSC (8VSB/16VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver"); -MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h deleted file mode 100644 index f4575c0cc44..00000000000 --- a/drivers/media/dvb/frontends/bcm3510.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) - * - * Copyright (C) 2001-5, B2C2 inc. - * - * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef BCM3510_H -#define BCM3510_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct bcm3510_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -#if defined(CONFIG_DVB_BCM3510) || (defined(CONFIG_DVB_BCM3510_MODULE) && defined(MODULE)) -extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_BCM3510 - -#endif diff --git a/drivers/media/dvb/frontends/bcm3510_priv.h b/drivers/media/dvb/frontends/bcm3510_priv.h deleted file mode 100644 index 3bb1bc2a04f..00000000000 --- a/drivers/media/dvb/frontends/bcm3510_priv.h +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Support for the Broadcom BCM3510 ATSC demodulator (1st generation Air2PC) - * - * Copyright (C) 2001-5, B2C2 inc. - * - * GPL/Linux driver written by Patrick Boettcher <patrick.boettcher@desy.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __BCM3510_PRIV_H__ -#define __BCM3510_PRIV_H__ - -#define PACKED __attribute__((packed)) - -#undef err -#define err(format, arg...) printk(KERN_ERR "bcm3510: " format "\n" , ## arg) -#undef info -#define info(format, arg...) printk(KERN_INFO "bcm3510: " format "\n" , ## arg) -#undef warn -#define warn(format, arg...) printk(KERN_WARNING "bcm3510: " format "\n" , ## arg) - - -#define PANASONIC_FIRST_IF_BASE_IN_KHz 1407500 -#define BCM3510_SYMBOL_RATE 5381000 - -typedef union { - u8 raw; - - struct { - u8 CTL :8; - } TSTCTL_2e; - - u8 LDCERC_4e; - u8 LDUERC_4f; - u8 LD_BER0_65; - u8 LD_BER1_66; - u8 LD_BER2_67; - u8 LD_BER3_68; - - struct { - u8 RESET :1; - u8 IDLE :1; - u8 STOP :1; - u8 HIRQ0 :1; - u8 HIRQ1 :1; - u8 na0 :1; - u8 HABAV :1; - u8 na1 :1; - } HCTL1_a0; - - struct { - u8 na0 :1; - u8 IDLMSK :1; - u8 STMSK :1; - u8 I0MSK :1; - u8 I1MSK :1; - u8 na1 :1; - u8 HABMSK :1; - u8 na2 :1; - } HCTLMSK_a1; - - struct { - u8 RESET :1; - u8 IDLE :1; - u8 STOP :1; - u8 RUN :1; - u8 HABAV :1; - u8 MEMAV :1; - u8 ALDONE :1; - u8 REIRQ :1; - } APSTAT1_a2; - - struct { - u8 RSTMSK :1; - u8 IMSK :1; - u8 SMSK :1; - u8 RMSK :1; - u8 HABMSK :1; - u8 MAVMSK :1; - u8 ALDMSK :1; - u8 REMSK :1; - } APMSK1_a3; - - u8 APSTAT2_a4; - u8 APMSK2_a5; - - struct { - u8 HABADR :7; - u8 na :1; - } HABADR_a6; - - u8 HABDATA_a7; - - struct { - u8 HABR :1; - u8 LDHABR :1; - u8 APMSK :1; - u8 HMSK :1; - u8 LDMSK :1; - u8 na :3; - } HABSTAT_a8; - - u8 MADRH_a9; - u8 MADRL_aa; - u8 MDATA_ab; - - struct { -#define JDEC_WAIT_AT_RAM 0x7 -#define JDEC_EEPROM_LOAD_WAIT 0x4 - u8 JDEC :3; - u8 na :5; - } JDEC_ca; - - struct { - u8 REV :4; - u8 LAYER :4; - } REVID_e0; - - struct { - u8 unk0 :1; - u8 CNTCTL :1; - u8 BITCNT :1; - u8 unk1 :1; - u8 RESYNC :1; - u8 unk2 :3; - } BERCTL_fa; - - struct { - u8 CSEL0 :1; - u8 CLKED0 :1; - u8 CSEL1 :1; - u8 CLKED1 :1; - u8 CLKLEV :1; - u8 SPIVAR :1; - u8 na :2; - } TUNSET_fc; - - struct { - u8 CLK :1; - u8 DATA :1; - u8 CS0 :1; - u8 CS1 :1; - u8 AGCSEL :1; - u8 na0 :1; - u8 TUNSEL :1; - u8 na1 :1; - } TUNCTL_fd; - - u8 TUNSEL0_fe; - u8 TUNSEL1_ff; - -} bcm3510_register_value; - -/* HAB commands */ - -/* version */ -#define CMD_GET_VERSION_INFO 0x3D -#define MSGID_GET_VERSION_INFO 0x15 -struct bcm3510_hab_cmd_get_version_info { - u8 microcode_version; - u8 script_version; - u8 config_version; - u8 demod_version; -} PACKED; - -#define BCM3510_DEF_MICROCODE_VERSION 0x0E -#define BCM3510_DEF_SCRIPT_VERSION 0x06 -#define BCM3510_DEF_CONFIG_VERSION 0x01 -#define BCM3510_DEF_DEMOD_VERSION 0xB1 - -/* acquire */ -#define CMD_ACQUIRE 0x38 - -#define MSGID_EXT_TUNER_ACQUIRE 0x0A -struct bcm3510_hab_cmd_ext_acquire { - struct { - u8 MODE :4; - u8 BW :1; - u8 FA :1; - u8 NTSCSWEEP :1; - u8 OFFSET :1; - } PACKED ACQUIRE0; /* control_byte */ - - struct { - u8 IF_FREQ :3; - u8 zero0 :1; - u8 SYM_RATE :3; - u8 zero1 :1; - } PACKED ACQUIRE1; /* sym_if */ - - u8 IF_OFFSET0; /* IF_Offset_10hz */ - u8 IF_OFFSET1; - u8 SYM_OFFSET0; /* SymbolRateOffset */ - u8 SYM_OFFSET1; - u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */ - u8 NTSC_OFFSET1; -} PACKED; - -#define MSGID_INT_TUNER_ACQUIRE 0x0B -struct bcm3510_hab_cmd_int_acquire { - struct { - u8 MODE :4; - u8 BW :1; - u8 FA :1; - u8 NTSCSWEEP :1; - u8 OFFSET :1; - } PACKED ACQUIRE0; /* control_byte */ - - struct { - u8 IF_FREQ :3; - u8 zero0 :1; - u8 SYM_RATE :3; - u8 zero1 :1; - } PACKED ACQUIRE1; /* sym_if */ - - u8 TUNER_FREQ0; - u8 TUNER_FREQ1; - u8 TUNER_FREQ2; - u8 TUNER_FREQ3; - u8 IF_OFFSET0; /* IF_Offset_10hz */ - u8 IF_OFFSET1; - u8 SYM_OFFSET0; /* SymbolRateOffset */ - u8 SYM_OFFSET1; - u8 NTSC_OFFSET0; /* NTSC_Offset_10hz */ - u8 NTSC_OFFSET1; -} PACKED; - -/* modes */ -#define BCM3510_QAM16 = 0x01 -#define BCM3510_QAM32 = 0x02 -#define BCM3510_QAM64 = 0x03 -#define BCM3510_QAM128 = 0x04 -#define BCM3510_QAM256 = 0x05 -#define BCM3510_8VSB = 0x0B -#define BCM3510_16VSB = 0x0D - -/* IF_FREQS */ -#define BCM3510_IF_TERRESTRIAL 0x0 -#define BCM3510_IF_CABLE 0x1 -#define BCM3510_IF_USE_CMD 0x7 - -/* SYM_RATE */ -#define BCM3510_SR_8VSB 0x0 /* 5381119 s/sec */ -#define BCM3510_SR_256QAM 0x1 /* 5360537 s/sec */ -#define BCM3510_SR_16QAM 0x2 /* 5056971 s/sec */ -#define BCM3510_SR_MISC 0x3 /* 5000000 s/sec */ -#define BCM3510_SR_USE_CMD 0x7 - -/* special symbol rate */ -#define CMD_SET_VALUE_NOT_LISTED 0x2d -#define MSGID_SET_SYMBOL_RATE_NOT_LISTED 0x0c -struct bcm3510_hab_cmd_set_sr_not_listed { - u8 HOST_SYM_RATE0; - u8 HOST_SYM_RATE1; - u8 HOST_SYM_RATE2; - u8 HOST_SYM_RATE3; -} PACKED; - -/* special IF */ -#define MSGID_SET_IF_FREQ_NOT_LISTED 0x0d -struct bcm3510_hab_cmd_set_if_freq_not_listed { - u8 HOST_IF_FREQ0; - u8 HOST_IF_FREQ1; - u8 HOST_IF_FREQ2; - u8 HOST_IF_FREQ3; -} PACKED; - -/* auto reacquire */ -#define CMD_AUTO_PARAM 0x2a -#define MSGID_AUTO_REACQUIRE 0x0e -struct bcm3510_hab_cmd_auto_reacquire { - u8 ACQ :1; /* on/off*/ - u8 unused :7; -} PACKED; - -#define MSGID_SET_RF_AGC_SEL 0x12 -struct bcm3510_hab_cmd_set_agc { - u8 LVL :1; - u8 unused :6; - u8 SEL :1; -} PACKED; - -#define MSGID_SET_AUTO_INVERSION 0x14 -struct bcm3510_hab_cmd_auto_inversion { - u8 AI :1; - u8 unused :7; -} PACKED; - - -/* bert control */ -#define CMD_STATE_CONTROL 0x12 -#define MSGID_BERT_CONTROL 0x0e -#define MSGID_BERT_SET 0xfa -struct bcm3510_hab_cmd_bert_control { - u8 BE :1; - u8 unused :7; -} PACKED; - -#define MSGID_TRI_STATE 0x2e -struct bcm3510_hab_cmd_tri_state { - u8 RE :1; /* a/d ram port pins */ - u8 PE :1; /* baud clock pin */ - u8 AC :1; /* a/d clock pin */ - u8 BE :1; /* baud clock pin */ - u8 unused :4; -} PACKED; - - -/* tune */ -#define CMD_TUNE 0x38 -#define MSGID_TUNE 0x16 -struct bcm3510_hab_cmd_tune_ctrl_data_pair { - struct { -#define BITS_8 0x07 -#define BITS_7 0x06 -#define BITS_6 0x05 -#define BITS_5 0x04 -#define BITS_4 0x03 -#define BITS_3 0x02 -#define BITS_2 0x01 -#define BITS_1 0x00 - u8 size :3; - u8 unk :2; - u8 clk_off :1; - u8 cs0 :1; - u8 cs1 :1; - - } PACKED ctrl; - - u8 data; -} PACKED; - -struct bcm3510_hab_cmd_tune { - u8 length; - u8 clock_width; - u8 misc; - u8 TUNCTL_state; - - struct bcm3510_hab_cmd_tune_ctrl_data_pair ctl_dat[16]; -} PACKED; - -#define CMD_STATUS 0x38 -#define MSGID_STATUS1 0x08 -struct bcm3510_hab_cmd_status1 { - struct { - u8 EQ_MODE :4; - u8 reserved :2; - u8 QRE :1; /* if QSE and the spectrum is inversed */ - u8 QSE :1; /* automatic spectral inversion */ - } PACKED STATUS0; - - struct { - u8 RECEIVER_LOCK :1; - u8 FEC_LOCK :1; - u8 OUT_PLL_LOCK :1; - u8 reserved :5; - } PACKED STATUS1; - - struct { - u8 reserved :2; - u8 BW :1; - u8 NTE :1; /* NTSC filter sweep enabled */ - u8 AQI :1; /* currently acquiring */ - u8 FA :1; /* fast acquisition */ - u8 ARI :1; /* auto reacquire */ - u8 TI :1; /* programming the tuner */ - } PACKED STATUS2; - u8 STATUS3; - u8 SNR_EST0; - u8 SNR_EST1; - u8 TUNER_FREQ0; - u8 TUNER_FREQ1; - u8 TUNER_FREQ2; - u8 TUNER_FREQ3; - u8 SYM_RATE0; - u8 SYM_RATE1; - u8 SYM_RATE2; - u8 SYM_RATE3; - u8 SYM_OFFSET0; - u8 SYM_OFFSET1; - u8 SYM_ERROR0; - u8 SYM_ERROR1; - u8 IF_FREQ0; - u8 IF_FREQ1; - u8 IF_FREQ2; - u8 IF_FREQ3; - u8 IF_OFFSET0; - u8 IF_OFFSET1; - u8 IF_ERROR0; - u8 IF_ERROR1; - u8 NTSC_FILTER0; - u8 NTSC_FILTER1; - u8 NTSC_FILTER2; - u8 NTSC_FILTER3; - u8 NTSC_OFFSET0; - u8 NTSC_OFFSET1; - u8 NTSC_ERROR0; - u8 NTSC_ERROR1; - u8 INT_AGC_LEVEL0; - u8 INT_AGC_LEVEL1; - u8 EXT_AGC_LEVEL0; - u8 EXT_AGC_LEVEL1; -} PACKED; - -#define MSGID_STATUS2 0x14 -struct bcm3510_hab_cmd_status2 { - struct { - u8 EQ_MODE :4; - u8 reserved :2; - u8 QRE :1; - u8 QSR :1; - } PACKED STATUS0; - struct { - u8 RL :1; - u8 FL :1; - u8 OL :1; - u8 reserved :5; - } PACKED STATUS1; - u8 SYMBOL_RATE0; - u8 SYMBOL_RATE1; - u8 SYMBOL_RATE2; - u8 SYMBOL_RATE3; - u8 LDCERC0; - u8 LDCERC1; - u8 LDCERC2; - u8 LDCERC3; - u8 LDUERC0; - u8 LDUERC1; - u8 LDUERC2; - u8 LDUERC3; - u8 LDBER0; - u8 LDBER1; - u8 LDBER2; - u8 LDBER3; - struct { - u8 MODE_TYPE :4; /* acquire mode 0 */ - u8 reservd :4; - } MODE_TYPE; - u8 SNR_EST0; - u8 SNR_EST1; - u8 SIGNAL; -} PACKED; - -#define CMD_SET_RF_BW_NOT_LISTED 0x3f -#define MSGID_SET_RF_BW_NOT_LISTED 0x11 -/* TODO */ - -#endif diff --git a/drivers/media/dvb/frontends/bsbe1.h b/drivers/media/dvb/frontends/bsbe1.h deleted file mode 100644 index 5e431ebd089..00000000000 --- a/drivers/media/dvb/frontends/bsbe1.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * bsbe1.h - ALPS BSBE1 tuner support - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef BSBE1_H -#define BSBE1_H - -static u8 alps_bsbe1_inittab[] = { - 0x01, 0x15, /* XTAL = 4MHz, VCO = 352 MHz */ - 0x02, 0x30, /* MCLK = 88 MHz */ - 0x03, 0x00, /* ACR output 0 */ - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x05, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x00, /* DAC output 0 */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1/OP0 normal, val = 1 (LNB power on) */ - 0x0d, 0x82, /* DC offset compensation = on, beta_agc1 = 2 */ - 0x0f, 0x92, /* AGC1R */ - 0x10, 0x34, /* AGC2O */ - 0x11, 0x84, /* TLSR */ - 0x12, 0xb9, /* CFD */ - 0x15, 0xc9, /* lock detector threshold */ - 0x28, 0x00, /* out imp: normal, type: parallel, FEC mode: QPSK */ - 0x33, 0xfc, /* RS control */ - 0x34, 0x93, /* count viterbi bit errors per 2E18 bytes */ - 0xff, 0xff -}; - - -static int alps_bsbe1_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio ) & 0xf0); - - return 0; -} - -static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - int ret; - u8 data[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - struct i2c_adapter *i2c = fe->tuner_priv; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = params->frequency / 1000; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1; - data[3] = 0xe0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer(i2c, &msg, 1); - return (ret != 1) ? -EIO : 0; -} - -static struct stv0299_config alps_bsbe1_config = { - .demod_address = 0x68, - .inittab = alps_bsbe1_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsbe1_set_symbol_rate, -}; - -#endif diff --git a/drivers/media/dvb/frontends/bsru6.h b/drivers/media/dvb/frontends/bsru6.h deleted file mode 100644 index 45a6dfd8ebb..00000000000 --- a/drivers/media/dvb/frontends/bsru6.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * bsru6.h - ALPS BSRU6 tuner support (moved from budget-ci.c) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef BSRU6_H -#define BSRU6_H - -static u8 alps_bsru6_inittab[] = { - 0x01, 0x15, - 0x02, 0x00, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x52, - 0xff, 0xff -}; - -static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { - aclk = 0xb7; - bclk = 0x47; - } else if (srate < 3000000) { - aclk = 0xb7; - bclk = 0x4b; - } else if (srate < 7000000) { - aclk = 0xb7; - bclk = 0x4f; - } else if (srate < 14000000) { - aclk = 0xb7; - bclk = 0x53; - } else if (srate < 30000000) { - aclk = 0xb6; - bclk = 0x53; - } else if (srate < 45000000) { - aclk = 0xb4; - bclk = 0x51; - } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, ratio & 0xf0); - - return 0; -} - -static int alps_bsru6_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - u8 buf[4]; - u32 div; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - struct i2c_adapter *i2c = fe->tuner_priv; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - buf[3] = 0xC4; - - if (params->frequency > 1530000) - buf[3] = 0xc0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct stv0299_config alps_bsru6_config = { - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsru6_set_symbol_rate, -}; - -#endif diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c deleted file mode 100644 index ace5cb17165..00000000000 --- a/drivers/media/dvb/frontends/cx22700.c +++ /dev/null @@ -1,440 +0,0 @@ -/* - Conexant cx22700 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "dvb_frontend.h" -#include "cx22700.h" - - -struct cx22700_state { - - struct i2c_adapter* i2c; - - const struct cx22700_config* config; - - struct dvb_frontend frontend; -}; - - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "cx22700: " args); \ - } while (0) - -static u8 init_tab [] = { - 0x04, 0x10, - 0x05, 0x09, - 0x06, 0x00, - 0x08, 0x04, - 0x09, 0x00, - 0x0a, 0x01, - 0x15, 0x40, - 0x16, 0x10, - 0x17, 0x87, - 0x18, 0x17, - 0x1a, 0x10, - 0x25, 0x04, - 0x2e, 0x00, - 0x39, 0x00, - 0x3a, 0x04, - 0x45, 0x08, - 0x46, 0x02, - 0x47, 0x05, -}; - - -static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - dprintk ("%s\n", __func__); - - ret = i2c_transfer (state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static int cx22700_readreg (struct cx22700_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - dprintk ("%s\n", __func__); - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) return -EIO; - - return b1[0]; -} - -static int cx22700_set_inversion (struct cx22700_state* state, int inversion) -{ - u8 val; - - dprintk ("%s\n", __func__); - - switch (inversion) { - case INVERSION_AUTO: - return -EOPNOTSUPP; - case INVERSION_ON: - val = cx22700_readreg (state, 0x09); - return cx22700_writereg (state, 0x09, val | 0x01); - case INVERSION_OFF: - val = cx22700_readreg (state, 0x09); - return cx22700_writereg (state, 0x09, val & 0xfe); - default: - return -EINVAL; - } -} - -static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_parameters *p) -{ - static const u8 qam_tab [4] = { 0, 1, 0, 2 }; - static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 }; - u8 val; - - dprintk ("%s\n", __func__); - - if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8) - return -EINVAL; - - if (p->code_rate_LP < FEC_1_2 || p->code_rate_LP > FEC_7_8) - return -EINVAL; - - if (p->code_rate_HP == FEC_4_5 || p->code_rate_LP == FEC_4_5) - return -EINVAL; - - if (p->guard_interval < GUARD_INTERVAL_1_32 || - p->guard_interval > GUARD_INTERVAL_1_4) - return -EINVAL; - - if (p->transmission_mode != TRANSMISSION_MODE_2K && - p->transmission_mode != TRANSMISSION_MODE_8K) - return -EINVAL; - - if (p->constellation != QPSK && - p->constellation != QAM_16 && - p->constellation != QAM_64) - return -EINVAL; - - if (p->hierarchy_information < HIERARCHY_NONE || - p->hierarchy_information > HIERARCHY_4) - return -EINVAL; - - if (p->bandwidth < BANDWIDTH_8_MHZ && p->bandwidth > BANDWIDTH_6_MHZ) - return -EINVAL; - - if (p->bandwidth == BANDWIDTH_7_MHZ) - cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 | 0x10)); - else - cx22700_writereg (state, 0x09, cx22700_readreg (state, 0x09 & ~0x10)); - - val = qam_tab[p->constellation - QPSK]; - val |= p->hierarchy_information - HIERARCHY_NONE; - - cx22700_writereg (state, 0x04, val); - - val = fec_tab[p->code_rate_HP - FEC_1_2] << 3; - val |= fec_tab[p->code_rate_LP - FEC_1_2]; - - cx22700_writereg (state, 0x05, val); - - val = (p->guard_interval - GUARD_INTERVAL_1_32) << 2; - val |= p->transmission_mode - TRANSMISSION_MODE_2K; - - cx22700_writereg (state, 0x06, val); - - cx22700_writereg (state, 0x08, 0x04 | 0x02); /* use user tps parameters */ - cx22700_writereg (state, 0x08, 0x04); /* restart aquisition */ - - return 0; -} - -static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_parameters *p) -{ - static const fe_modulation_t qam_tab [3] = { QPSK, QAM_16, QAM_64 }; - static const fe_code_rate_t fec_tab [5] = { FEC_1_2, FEC_2_3, FEC_3_4, - FEC_5_6, FEC_7_8 }; - u8 val; - - dprintk ("%s\n", __func__); - - if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */ - return -EAGAIN; - - val = cx22700_readreg (state, 0x01); - - if ((val & 0x7) > 4) - p->hierarchy_information = HIERARCHY_AUTO; - else - p->hierarchy_information = HIERARCHY_NONE + (val & 0x7); - - if (((val >> 3) & 0x3) > 2) - p->constellation = QAM_AUTO; - else - p->constellation = qam_tab[(val >> 3) & 0x3]; - - val = cx22700_readreg (state, 0x02); - - if (((val >> 3) & 0x07) > 4) - p->code_rate_HP = FEC_AUTO; - else - p->code_rate_HP = fec_tab[(val >> 3) & 0x07]; - - if ((val & 0x07) > 4) - p->code_rate_LP = FEC_AUTO; - else - p->code_rate_LP = fec_tab[val & 0x07]; - - val = cx22700_readreg (state, 0x03); - - p->guard_interval = GUARD_INTERVAL_1_32 + ((val >> 6) & 0x3); - p->transmission_mode = TRANSMISSION_MODE_2K + ((val >> 5) & 0x1); - - return 0; -} - -static int cx22700_init (struct dvb_frontend* fe) - -{ struct cx22700_state* state = fe->demodulator_priv; - int i; - - dprintk("cx22700_init: init chip\n"); - - cx22700_writereg (state, 0x00, 0x02); /* soft reset */ - cx22700_writereg (state, 0x00, 0x00); - - msleep(10); - - for (i=0; i<sizeof(init_tab); i+=2) - cx22700_writereg (state, init_tab[i], init_tab[i+1]); - - cx22700_writereg (state, 0x00, 0x01); - - return 0; -} - -static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct cx22700_state* state = fe->demodulator_priv; - - u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) - | (cx22700_readreg (state, 0x0e) << 1); - u8 sync = cx22700_readreg (state, 0x07); - - *status = 0; - - if (rs_ber < 0xff00) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x20) - *status |= FE_HAS_CARRIER; - - if (sync & 0x10) - *status |= FE_HAS_VITERBI; - - if (sync & 0x10) - *status |= FE_HAS_SYNC; - - if (*status == 0x0f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct cx22700_state* state = fe->demodulator_priv; - - *ber = cx22700_readreg (state, 0x0c) & 0x7f; - cx22700_writereg (state, 0x0c, 0x00); - - return 0; -} - -static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx22700_state* state = fe->demodulator_priv; - - u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) - | (cx22700_readreg (state, 0x0e) << 1); - *signal_strength = ~rs_ber; - - return 0; -} - -static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct cx22700_state* state = fe->demodulator_priv; - - u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) - | (cx22700_readreg (state, 0x0e) << 1); - *snr = ~rs_ber; - - return 0; -} - -static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx22700_state* state = fe->demodulator_priv; - - *ucblocks = cx22700_readreg (state, 0x0f); - cx22700_writereg (state, 0x0f, 0x00); - - return 0; -} - -static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx22700_state* state = fe->demodulator_priv; - - cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ - cx22700_writereg (state, 0x00, 0x00); - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - cx22700_set_inversion (state, p->inversion); - cx22700_set_tps (state, &p->u.ofdm); - cx22700_writereg (state, 0x37, 0x01); /* PAL loop filter off */ - cx22700_writereg (state, 0x00, 0x01); /* restart acquire */ - - return 0; -} - -static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx22700_state* state = fe->demodulator_priv; - u8 reg09 = cx22700_readreg (state, 0x09); - - p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22700_get_tps (state, &p->u.ofdm); -} - -static int cx22700_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct cx22700_state* state = fe->demodulator_priv; - - if (enable) { - return cx22700_writereg(state, 0x0a, 0x00); - } else { - return cx22700_writereg(state, 0x0a, 0x01); - } -} - -static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 150; - fesettings->step_size = 166667; - fesettings->max_drift = 166667*2; - return 0; -} - -static void cx22700_release(struct dvb_frontend* fe) -{ - struct cx22700_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops cx22700_ops; - -struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c) -{ - struct cx22700_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx22700_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (cx22700_readreg(state, 0x07) < 0) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22700_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops cx22700_ops = { - - .info = { - .name = "Conexant CX22700 DVB-T", - .type = FE_OFDM, - .frequency_min = 470000000, - .frequency_max = 860000000, - .frequency_stepsize = 166667, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_RECOVER - }, - - .release = cx22700_release, - - .init = cx22700_init, - .i2c_gate_ctrl = cx22700_i2c_gate_ctrl, - - .set_frontend = cx22700_set_frontend, - .get_frontend = cx22700_get_frontend, - .get_tune_settings = cx22700_get_tune_settings, - - .read_status = cx22700_read_status, - .read_ber = cx22700_read_ber, - .read_signal_strength = cx22700_read_signal_strength, - .read_snr = cx22700_read_snr, - .read_ucblocks = cx22700_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Conexant CX22700 DVB-T Demodulator driver"); -MODULE_AUTHOR("Holger Waechtler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx22700_attach); diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h deleted file mode 100644 index 4757a930ca0..00000000000 --- a/drivers/media/dvb/frontends/cx22700.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - Conexant CX22700 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef CX22700_H -#define CX22700_H - -#include <linux/dvb/frontend.h> - -struct cx22700_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_CX22700) || (defined(CONFIG_DVB_CX22700_MODULE) && defined(MODULE)) -extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_CX22700 - -#endif // CX22700_H diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c deleted file mode 100644 index 5d1abe34bdd..00000000000 --- a/drivers/media/dvb/frontends/cx22702.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - Conexant 22702 DVB OFDM demodulator driver - - based on: - Alps TDMB7 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - Copyright (C) 2004 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "cx22702.h" - -struct cx22702_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct cx22702_config *config; - - struct dvb_frontend frontend; - - /* previous uncorrected block counter */ - u8 prevUCBlocks; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -#define dprintk if (debug) printk - -/* Register values to initialise the demod */ -static u8 init_tab[] = { - 0x00, 0x00, /* Stop aquisition */ - 0x0B, 0x06, - 0x09, 0x01, - 0x0D, 0x41, - 0x16, 0x32, - 0x20, 0x0A, - 0x21, 0x17, - 0x24, 0x3e, - 0x26, 0xff, - 0x27, 0x10, - 0x28, 0x00, - 0x29, 0x00, - 0x2a, 0x10, - 0x2b, 0x00, - 0x2c, 0x10, - 0x2d, 0x00, - 0x48, 0xd4, - 0x49, 0x56, - 0x6b, 0x1e, - 0xc8, 0x02, - 0xf9, 0x00, - 0xfa, 0x00, - 0xfb, 0x00, - 0xfc, 0x00, - 0xfd, 0x00, -}; - -static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, .flags = 0, - .buf = buf, .len = 2 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR - "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n", - __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 cx22702_readreg(struct cx22702_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - - return b1[0]; -} - -static int cx22702_set_inversion(struct cx22702_state *state, int inversion) -{ - u8 val; - - switch (inversion) { - case INVERSION_AUTO: - return -EOPNOTSUPP; - case INVERSION_ON: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val | 0x01); - case INVERSION_OFF: - val = cx22702_readreg(state, 0x0C); - return cx22702_writereg(state, 0x0C, val & 0xfe); - default: - return -EINVAL; - } - -} - -/* Retrieve the demod settings */ -static int cx22702_get_tps(struct cx22702_state *state, - struct dvb_ofdm_parameters *p) -{ - u8 val; - - /* Make sure the TPS regs are valid */ - if (!(cx22702_readreg(state, 0x0A) & 0x20)) - return -EAGAIN; - - val = cx22702_readreg(state, 0x01); - switch ((val & 0x18) >> 3) { - case 0: - p->constellation = QPSK; - break; - case 1: - p->constellation = QAM_16; - break; - case 2: - p->constellation = QAM_64; - break; - } - switch (val & 0x07) { - case 0: - p->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->hierarchy_information = HIERARCHY_1; - break; - case 2: - p->hierarchy_information = HIERARCHY_2; - break; - case 3: - p->hierarchy_information = HIERARCHY_4; - break; - } - - - val = cx22702_readreg(state, 0x02); - switch ((val & 0x38) >> 3) { - case 0: - p->code_rate_HP = FEC_1_2; - break; - case 1: - p->code_rate_HP = FEC_2_3; - break; - case 2: - p->code_rate_HP = FEC_3_4; - break; - case 3: - p->code_rate_HP = FEC_5_6; - break; - case 4: - p->code_rate_HP = FEC_7_8; - break; - } - switch (val & 0x07) { - case 0: - p->code_rate_LP = FEC_1_2; - break; - case 1: - p->code_rate_LP = FEC_2_3; - break; - case 2: - p->code_rate_LP = FEC_3_4; - break; - case 3: - p->code_rate_LP = FEC_5_6; - break; - case 4: - p->code_rate_LP = FEC_7_8; - break; - } - - val = cx22702_readreg(state, 0x03); - switch ((val & 0x0c) >> 2) { - case 0: - p->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->guard_interval = GUARD_INTERVAL_1_4; - break; - } - switch (val & 0x03) { - case 0: - p->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->transmission_mode = TRANSMISSION_MODE_8K; - break; - } - - return 0; -} - -static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct cx22702_state *state = fe->demodulator_priv; - dprintk("%s(%d)\n", __func__, enable); - if (enable) - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) & 0xfe); - else - return cx22702_writereg(state, 0x0D, - cx22702_readreg(state, 0x0D) | 1); -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int cx22702_set_tps(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - u8 val; - struct cx22702_state *state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* set inversion */ - cx22702_set_inversion(state, p->inversion); - - /* set bandwidth */ - switch (p->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20); - break; - case BANDWIDTH_7_MHZ: - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10); - break; - case BANDWIDTH_8_MHZ: - cx22702_writereg(state, 0x0C, - cx22702_readreg(state, 0x0C) & 0xcf); - break; - default: - dprintk("%s: invalid bandwidth\n", __func__); - return -EINVAL; - } - - p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */ - - /* use auto configuration? */ - if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) || - (p->u.ofdm.constellation == QAM_AUTO) || - (p->u.ofdm.code_rate_HP == FEC_AUTO) || - (p->u.ofdm.code_rate_LP == FEC_AUTO) || - (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) || - (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) { - - /* TPS Source - use hardware driven values */ - cx22702_writereg(state, 0x06, 0x10); - cx22702_writereg(state, 0x07, 0x9); - cx22702_writereg(state, 0x08, 0xC1); - cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) - & 0xfc); - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); - cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */ - dprintk("%s: Autodetecting\n", __func__); - return 0; - } - - /* manually programmed values */ - val = 0; - switch (p->u.ofdm.constellation) { - case QPSK: - val = (val & 0xe7); - break; - case QAM_16: - val = (val & 0xe7) | 0x08; - break; - case QAM_64: - val = (val & 0xe7) | 0x10; - break; - default: - dprintk("%s: invalid constellation\n", __func__); - return -EINVAL; - } - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - val = (val & 0xf8); - break; - case HIERARCHY_1: - val = (val & 0xf8) | 1; - break; - case HIERARCHY_2: - val = (val & 0xf8) | 2; - break; - case HIERARCHY_4: - val = (val & 0xf8) | 3; - break; - default: - dprintk("%s: invalid hierarchy\n", __func__); - return -EINVAL; - } - cx22702_writereg(state, 0x06, val); - - val = 0; - switch (p->u.ofdm.code_rate_HP) { - case FEC_NONE: - case FEC_1_2: - val = (val & 0xc7); - break; - case FEC_2_3: - val = (val & 0xc7) | 0x08; - break; - case FEC_3_4: - val = (val & 0xc7) | 0x10; - break; - case FEC_5_6: - val = (val & 0xc7) | 0x18; - break; - case FEC_7_8: - val = (val & 0xc7) | 0x20; - break; - default: - dprintk("%s: invalid code_rate_HP\n", __func__); - return -EINVAL; - } - switch (p->u.ofdm.code_rate_LP) { - case FEC_NONE: - case FEC_1_2: - val = (val & 0xf8); - break; - case FEC_2_3: - val = (val & 0xf8) | 1; - break; - case FEC_3_4: - val = (val & 0xf8) | 2; - break; - case FEC_5_6: - val = (val & 0xf8) | 3; - break; - case FEC_7_8: - val = (val & 0xf8) | 4; - break; - default: - dprintk("%s: invalid code_rate_LP\n", __func__); - return -EINVAL; - } - cx22702_writereg(state, 0x07, val); - - val = 0; - switch (p->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: - val = (val & 0xf3); - break; - case GUARD_INTERVAL_1_16: - val = (val & 0xf3) | 0x04; - break; - case GUARD_INTERVAL_1_8: - val = (val & 0xf3) | 0x08; - break; - case GUARD_INTERVAL_1_4: - val = (val & 0xf3) | 0x0c; - break; - default: - dprintk("%s: invalid guard_interval\n", __func__); - return -EINVAL; - } - switch (p->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: - val = (val & 0xfc); - break; - case TRANSMISSION_MODE_8K: - val = (val & 0xfc) | 1; - break; - default: - dprintk("%s: invalid transmission_mode\n", __func__); - return -EINVAL; - } - cx22702_writereg(state, 0x08, val); - cx22702_writereg(state, 0x0B, - (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02); - cx22702_writereg(state, 0x0C, - (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40); - - /* Begin channel aquisition */ - cx22702_writereg(state, 0x00, 0x01); - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int cx22702_init(struct dvb_frontend *fe) -{ - int i; - struct cx22702_state *state = fe->demodulator_priv; - - cx22702_writereg(state, 0x00, 0x02); - - msleep(10); - - for (i = 0; i < ARRAY_SIZE(init_tab); i += 2) - cx22702_writereg(state, init_tab[i], init_tab[i + 1]); - - cx22702_writereg(state, 0xf8, (state->config->output_mode << 1) - & 0x02); - - cx22702_i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct cx22702_state *state = fe->demodulator_priv; - u8 reg0A; - u8 reg23; - - *status = 0; - - reg0A = cx22702_readreg(state, 0x0A); - reg23 = cx22702_readreg(state, 0x23); - - dprintk("%s: status demod=0x%02x agc=0x%02x\n" - , __func__, reg0A, reg23); - - if (reg0A & 0x10) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - } - - if (reg0A & 0x20) - *status |= FE_HAS_CARRIER; - - if (reg23 < 0xf0) - *status |= FE_HAS_SIGNAL; - - return 0; -} - -static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cx22702_state *state = fe->demodulator_priv; - - if (cx22702_readreg(state, 0xE4) & 0x02) { - /* Realtime statistics */ - *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | (cx22702_readreg(state, 0xDF) & 0x7F); - } else { - /* Averagtine statistics */ - *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | cx22702_readreg(state, 0xDF); - } - - return 0; -} - -static int cx22702_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u16 rs_ber = 0; - rs_ber = cx22702_readreg(state, 0x23); - *signal_strength = (rs_ber << 8) | rs_ber; - - return 0; -} - -static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u16 rs_ber = 0; - if (cx22702_readreg(state, 0xE4) & 0x02) { - /* Realtime statistics */ - rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7 - | (cx22702_readreg(state, 0xDF) & 0x7F); - } else { - /* Averagine statistics */ - rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8 - | cx22702_readreg(state, 0xDF); - } - *snr = ~rs_ber; - - return 0; -} - -static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u8 _ucblocks; - - /* RS Uncorrectable Packet Count then reset */ - _ucblocks = cx22702_readreg(state, 0xE3); - if (state->prevUCBlocks < _ucblocks) - *ucblocks = (_ucblocks - state->prevUCBlocks); - else - *ucblocks = state->prevUCBlocks - _ucblocks; - state->prevUCBlocks = _ucblocks; - - return 0; -} - -static int cx22702_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx22702_state *state = fe->demodulator_priv; - - u8 reg0C = cx22702_readreg(state, 0x0C); - - p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF; - return cx22702_get_tps(state, &p->u.ofdm); -} - -static int cx22702_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void cx22702_release(struct dvb_frontend *fe) -{ - struct cx22702_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops cx22702_ops; - -struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, - struct i2c_adapter *i2c) -{ - struct cx22702_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->prevUCBlocks = 0; - - /* check if the demod is there */ - if (cx22702_readreg(state, 0x1f) != 0x3) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx22702_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(cx22702_attach); - -static struct dvb_frontend_ops cx22702_ops = { - - .info = { - .name = "Conexant CX22702 DVB-T", - .type = FE_OFDM, - .frequency_min = 177000000, - .frequency_max = 858000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER - }, - - .release = cx22702_release, - - .init = cx22702_init, - .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, - - .set_frontend = cx22702_set_tps, - .get_frontend = cx22702_get_frontend, - .get_tune_settings = cx22702_get_tune_settings, - - .read_status = cx22702_read_status, - .read_ber = cx22702_read_ber, - .read_signal_strength = cx22702_read_signal_strength, - .read_snr = cx22702_read_snr, - .read_ucblocks = cx22702_read_ucblocks, -}; - -MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h deleted file mode 100644 index f154e1f428e..00000000000 --- a/drivers/media/dvb/frontends/cx22702.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - Conexant 22702 DVB OFDM demodulator driver - - based on: - Alps TDMB7 DVB OFDM demodulator driver - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - Holger Waechtler <holger@convergence.de> - - Copyright (C) 2004 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef CX22702_H -#define CX22702_H - -#include <linux/dvb/frontend.h> - -struct cx22702_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* serial/parallel output */ -#define CX22702_PARALLEL_OUTPUT 0 -#define CX22702_SERIAL_OUTPUT 1 - u8 output_mode; -}; - -#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *cx22702_attach( - const struct cx22702_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *cx22702_attach( - const struct cx22702_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c deleted file mode 100644 index 87ae29db024..00000000000 --- a/drivers/media/dvb/frontends/cx24110.c +++ /dev/null @@ -1,667 +0,0 @@ - /* - cx24110 - Single Chip Satellite Channel Receiver driver module - - Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on - work - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "dvb_frontend.h" -#include "cx24110.h" - - -struct cx24110_state { - - struct i2c_adapter* i2c; - - const struct cx24110_config* config; - - struct dvb_frontend frontend; - - u32 lastber; - u32 lastbler; - u32 lastesn0; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "cx24110: " args); \ - } while (0) - -static struct {u8 reg; u8 data;} cx24110_regdata[]= - /* Comments beginning with @ denote this value should - be the default */ - {{0x09,0x01}, /* SoftResetAll */ - {0x09,0x00}, /* release reset */ - {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ - {0x02,0x17}, /* middle byte " */ - {0x03,0x29}, /* LSB " */ - {0x05,0x03}, /* @ DVB mode, standard code rate 3/4 */ - {0x06,0xa5}, /* @ PLL 60MHz */ - {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ - {0x0a,0x00}, /* @ partial chip disables, do not set */ - {0x0b,0x01}, /* set output clock in gapped mode, start signal low - active for first byte */ - {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ - {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ - {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 - to avoid starting the BER counter. Reset the - CRC test bit. Finite counting selected */ - {0x15,0xff}, /* @ size of the limited time window for RS BER - estimation. It is <value>*256 RS blocks, this - gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ - {0x16,0x00}, /* @ enable all RS output ports */ - {0x17,0x04}, /* @ time window allowed for the RS to sync */ - {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned - for automatically */ - /* leave the current code rate and normalization - registers as they are after reset... */ - {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting - only once */ - {0x23,0x18}, /* @ size of the limited time window for Viterbi BER - estimation. It is <value>*65536 channel bits, i.e. - approx. 38ms at 27.5MS/s, rate 3/4 */ - {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ - /* leave front-end AGC parameters at default values */ - /* leave decimation AGC parameters at default values */ - {0x35,0x40}, /* disable all interrupts. They are not connected anyway */ - {0x36,0xff}, /* clear all interrupt pending flags */ - {0x37,0x00}, /* @ fully enable AutoAcqq state machine */ - {0x38,0x07}, /* @ enable fade recovery, but not autostart AutoAcq */ - /* leave the equalizer parameters on their default values */ - /* leave the final AGC parameters on their default values */ - {0x41,0x00}, /* @ MSB of front-end derotator frequency */ - {0x42,0x00}, /* @ middle bytes " */ - {0x43,0x00}, /* @ LSB " */ - /* leave the carrier tracking loop parameters on default */ - /* leave the bit timing loop parameters at gefault */ - {0x56,0x4d}, /* set the filtune voltage to 2.7V, as recommended by */ - /* the cx24108 data sheet for symbol rates above 15MS/s */ - {0x57,0x00}, /* @ Filter sigma delta enabled, positive */ - {0x61,0x95}, /* GPIO pins 1-4 have special function */ - {0x62,0x05}, /* GPIO pin 5 has special function, pin 6 is GPIO */ - {0x63,0x00}, /* All GPIO pins use CMOS output characteristics */ - {0x64,0x20}, /* GPIO 6 is input, all others are outputs */ - {0x6d,0x30}, /* tuner auto mode clock freq 62kHz */ - {0x70,0x15}, /* use auto mode, tuner word is 21 bits long */ - {0x73,0x00}, /* @ disable several demod bypasses */ - {0x74,0x00}, /* @ " */ - {0x75,0x00} /* @ " */ - /* the remaining registers are for SEC */ - }; - - -static int cx24110_writereg (struct cx24110_state* state, int reg, int data) -{ - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int err; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static int cx24110_readreg (struct cx24110_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) return ret; - - return b1[0]; -} - -static int cx24110_set_inversion (struct cx24110_state* state, fe_spectral_inversion_t inversion) -{ -/* fixme (low): error handling */ - - switch (inversion) { - case INVERSION_OFF: - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); - /* AcqSpectrInvDis on. No idea why someone should want this */ - cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)&0xf7); - /* Initial value 0 at start of acq */ - cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)&0xef); - /* current value 0 */ - /* The cx24110 manual tells us this reg is read-only. - But what the heck... set it ayways */ - break; - case INVERSION_ON: - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x1); - /* AcqSpectrInvDis on. No idea why someone should want this */ - cx24110_writereg(state,0x5,cx24110_readreg(state,0x5)|0x08); - /* Initial value 1 at start of acq */ - cx24110_writereg(state,0x22,cx24110_readreg(state,0x22)|0x10); - /* current value 1 */ - break; - case INVERSION_AUTO: - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xfe); - /* AcqSpectrInvDis off. Leave initial & current states as is */ - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec) -{ -/* fixme (low): error handling */ - - static const int rate[]={-1,1,2,3,5,7,-1}; - static const int g1[]={-1,0x01,0x02,0x05,0x15,0x45,-1}; - static const int g2[]={-1,0x01,0x03,0x06,0x1a,0x7a,-1}; - - /* Well, the AutoAcq engine of the cx24106 and 24110 automatically - searches all enabled viterbi rates, and can handle non-standard - rates as well. */ - - if (fec>FEC_AUTO) - fec=FEC_AUTO; - - if (fec==FEC_AUTO) { /* (re-)establish AutoAcq behaviour */ - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)&0xdf); - /* clear AcqVitDis bit */ - cx24110_writereg(state,0x18,0xae); - /* allow all DVB standard code rates */ - cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|0x3); - /* set nominal Viterbi rate 3/4 */ - cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|0x3); - /* set current Viterbi rate 3/4 */ - cx24110_writereg(state,0x1a,0x05); cx24110_writereg(state,0x1b,0x06); - /* set the puncture registers for code rate 3/4 */ - return 0; - } else { - cx24110_writereg(state,0x37,cx24110_readreg(state,0x37)|0x20); - /* set AcqVitDis bit */ - if(rate[fec]>0) { - cx24110_writereg(state,0x05,(cx24110_readreg(state,0x05)&0xf0)|rate[fec]); - /* set nominal Viterbi rate */ - cx24110_writereg(state,0x22,(cx24110_readreg(state,0x22)&0xf0)|rate[fec]); - /* set current Viterbi rate */ - cx24110_writereg(state,0x1a,g1[fec]); - cx24110_writereg(state,0x1b,g2[fec]); - /* not sure if this is the right way: I always used AutoAcq mode */ - } else - return -EOPNOTSUPP; -/* fixme (low): which is the correct return code? */ - }; - return 0; -} - -static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state) -{ - int i; - - i=cx24110_readreg(state,0x22)&0x0f; - if(!(i&0x08)) { - return FEC_1_2 + i - 1; - } else { -/* fixme (low): a special code rate has been selected. In theory, we need to - return a denominator value, a numerator value, and a pair of puncture - maps to correctly describe this mode. But this should never happen in - practice, because it cannot be set by cx24110_get_fec. */ - return FEC_NONE; - } -} - -static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) -{ -/* fixme (low): add error handling */ - u32 ratio; - u32 tmp, fclk, BDRI; - - static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; - int i; - - dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate); - if (srate>90999000UL/2) - srate=90999000UL/2; - if (srate<500000) - srate=500000; - - for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++) - ; - /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, - and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, - R06[3:0] PLLphaseDetGain */ - tmp=cx24110_readreg(state,0x07)&0xfc; - if(srate<90999000UL/4) { /* sample rate 45MHz*/ - cx24110_writereg(state,0x07,tmp); - cx24110_writereg(state,0x06,0x78); - fclk=90999000UL/2; - } else if(srate<60666000UL/2) { /* sample rate 60MHz */ - cx24110_writereg(state,0x07,tmp|0x1); - cx24110_writereg(state,0x06,0xa5); - fclk=60666000UL; - } else if(srate<80888000UL/2) { /* sample rate 80MHz */ - cx24110_writereg(state,0x07,tmp|0x2); - cx24110_writereg(state,0x06,0x87); - fclk=80888000UL; - } else { /* sample rate 90MHz */ - cx24110_writereg(state,0x07,tmp|0x3); - cx24110_writereg(state,0x06,0x78); - fclk=90999000UL; - }; - dprintk("cx24110 debug: fclk %d Hz\n",fclk); - /* we need to divide two integers with approx. 27 bits in 32 bit - arithmetic giving a 25 bit result */ - /* the maximum dividend is 90999000/2, 0x02b6446c, this number is - also the most complex divisor. Hence, the dividend has, - assuming 32bit unsigned arithmetic, 6 clear bits on top, the - divisor 2 unused bits at the bottom. Also, the quotient is - always less than 1/2. Borrowed from VES1893.c, of course */ - - tmp=srate<<6; - BDRI=fclk>>2; - ratio=(tmp/BDRI); - - tmp=(tmp%BDRI)<<8; - ratio=(ratio<<8)+(tmp/BDRI); - - tmp=(tmp%BDRI)<<8; - ratio=(ratio<<8)+(tmp/BDRI); - - tmp=(tmp%BDRI)<<1; - ratio=(ratio<<1)+(tmp/BDRI); - - dprintk("srate= %d (range %d, up to %d)\n", srate,i,bands[i]); - dprintk("fclk = %d\n", fclk); - dprintk("ratio= %08x\n", ratio); - - cx24110_writereg(state, 0x1, (ratio>>16)&0xff); - cx24110_writereg(state, 0x2, (ratio>>8)&0xff); - cx24110_writereg(state, 0x3, (ratio)&0xff); - - return 0; - -} - -static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len) -{ - struct cx24110_state *state = fe->demodulator_priv; - - if (len != 3) - return -EINVAL; - -/* tuner data is 21 bits long, must be left-aligned in data */ -/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ -/* FIXME (low): add error handling, avoid infinite loops if HW fails... */ - - cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */ - cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */ - - /* if the auto tuner writer is still busy, clear it out */ - while (cx24110_readreg(state,0x6d)&0x80) - cx24110_writereg(state,0x72,0); - - /* write the topmost 8 bits */ - cx24110_writereg(state,0x72,buf[0]); - - /* wait for the send to be completed */ - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* send another 8 bytes */ - cx24110_writereg(state,0x72,buf[1]); - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* and the topmost 5 bits of this byte */ - cx24110_writereg(state,0x72,buf[2]); - while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) - ; - - /* now strobe the enable line once */ - cx24110_writereg(state,0x6d,0x32); - cx24110_writereg(state,0x6d,0x30); - - return 0; -} - -static int cx24110_initfe(struct dvb_frontend* fe) -{ - struct cx24110_state *state = fe->demodulator_priv; -/* fixme (low): error handling */ - int i; - - dprintk("%s: init chip\n", __func__); - - for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) { - cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); - }; - - return 0; -} - -static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct cx24110_state *state = fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0xc0); - case SEC_VOLTAGE_18: - return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&0x3b)|0x40); - default: - return -EINVAL; - }; -} - -static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - int rv, bit; - struct cx24110_state *state = fe->demodulator_priv; - unsigned long timeout; - - if (burst == SEC_MINI_A) - bit = 0x00; - else if (burst == SEC_MINI_B) - bit = 0x08; - else - return -EINVAL; - - rv = cx24110_readreg(state, 0x77); - if (!(rv & 0x04)) - cx24110_writereg(state, 0x77, rv | 0x04); - - rv = cx24110_readreg(state, 0x76); - cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit)); - timeout = jiffies + msecs_to_jiffies(100); - while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40)) - ; /* wait for LNB ready */ - - return 0; -} - -static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *cmd) -{ - int i, rv; - struct cx24110_state *state = fe->demodulator_priv; - unsigned long timeout; - - if (cmd->msg_len < 3 || cmd->msg_len > 6) - return -EINVAL; /* not implemented */ - - for (i = 0; i < cmd->msg_len; i++) - cx24110_writereg(state, 0x79 + i, cmd->msg[i]); - - rv = cx24110_readreg(state, 0x77); - if (rv & 0x04) { - cx24110_writereg(state, 0x77, rv & ~0x04); - msleep(30); /* reportedly fixes switching problems */ - } - - rv = cx24110_readreg(state, 0x76); - - cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3)); - timeout = jiffies + msecs_to_jiffies(100); - while (!time_after(jiffies, timeout) && !(cx24110_readreg(state, 0x76) & 0x40)) - ; /* wait for LNB ready */ - - return 0; -} - -static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct cx24110_state *state = fe->demodulator_priv; - - int sync = cx24110_readreg (state, 0x55); - - *status = 0; - - if (sync & 0x10) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x08) - *status |= FE_HAS_CARRIER; - - sync = cx24110_readreg (state, 0x08); - - if (sync & 0x40) - *status |= FE_HAS_VITERBI; - - if (sync & 0x20) - *status |= FE_HAS_SYNC; - - if ((sync & 0x60) == 0x60) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct cx24110_state *state = fe->demodulator_priv; - - /* fixme (maybe): value range is 16 bit. Scale? */ - if(cx24110_readreg(state,0x24)&0x10) { - /* the Viterbi error counter has finished one counting window */ - cx24110_writereg(state,0x24,0x04); /* select the ber reg */ - state->lastber=cx24110_readreg(state,0x25)| - (cx24110_readreg(state,0x26)<<8); - cx24110_writereg(state,0x24,0x04); /* start new count window */ - cx24110_writereg(state,0x24,0x14); - } - *ber = state->lastber; - - return 0; -} - -static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx24110_state *state = fe->demodulator_priv; - -/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */ - u8 signal = cx24110_readreg (state, 0x27)+128; - *signal_strength = (signal << 8) | signal; - - return 0; -} - -static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct cx24110_state *state = fe->demodulator_priv; - - /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */ - if(cx24110_readreg(state,0x6a)&0x80) { - /* the Es/N0 error counter has finished one counting window */ - state->lastesn0=cx24110_readreg(state,0x69)| - (cx24110_readreg(state,0x68)<<8); - cx24110_writereg(state,0x6a,0x84); /* start new count window */ - } - *snr = state->lastesn0; - - return 0; -} - -static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx24110_state *state = fe->demodulator_priv; - u32 lastbyer; - - if(cx24110_readreg(state,0x10)&0x40) { - /* the RS error counter has finished one counting window */ - cx24110_writereg(state,0x10,0x60); /* select the byer reg */ - lastbyer=cx24110_readreg(state,0x12)| - (cx24110_readreg(state,0x13)<<8)| - (cx24110_readreg(state,0x14)<<16); - cx24110_writereg(state,0x10,0x70); /* select the bler reg */ - state->lastbler=cx24110_readreg(state,0x12)| - (cx24110_readreg(state,0x13)<<8)| - (cx24110_readreg(state,0x14)<<16); - cx24110_writereg(state,0x10,0x20); /* start new count window */ - } - *ucblocks = state->lastbler; - - return 0; -} - -static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24110_state *state = fe->demodulator_priv; - - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - cx24110_set_inversion (state, p->inversion); - cx24110_set_fec (state, p->u.qpsk.fec_inner); - cx24110_set_symbolrate (state, p->u.qpsk.symbol_rate); - cx24110_writereg(state,0x04,0x05); /* start aquisition */ - - return 0; -} - -static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24110_state *state = fe->demodulator_priv; - s32 afc; unsigned sclk; - -/* cannot read back tuner settings (freq). Need to have some private storage */ - - sclk = cx24110_readreg (state, 0x07) & 0x03; -/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz. - * Need 64 bit arithmetic. Is thiss possible in the kernel? */ - if (sclk==0) sclk=90999000L/2L; - else if (sclk==1) sclk=60666000L; - else if (sclk==2) sclk=80888000L; - else sclk=90999000L; - sclk>>=8; - afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+ - ((sclk*cx24110_readreg (state, 0x45))>>8)+ - ((sclk*cx24110_readreg (state, 0x46))>>16); - - p->frequency += afc; - p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ? - INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = cx24110_get_fec (state); - - return 0; -} - -static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct cx24110_state *state = fe->demodulator_priv; - - return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0)); -} - -static void cx24110_release(struct dvb_frontend* fe) -{ - struct cx24110_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops cx24110_ops; - -struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c) -{ - struct cx24110_state* state = NULL; - int ret; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->lastber = 0; - state->lastbler = 0; - state->lastesn0 = 0; - - /* check if the demod is there */ - ret = cx24110_readreg(state, 0x00); - if ((ret != 0x5a) && (ret != 0x69)) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24110_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops cx24110_ops = { - - .info = { - .name = "Conexant CX24110 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24110_release, - - .init = cx24110_initfe, - .write = _cx24110_pll_write, - .set_frontend = cx24110_set_frontend, - .get_frontend = cx24110_get_frontend, - .read_status = cx24110_read_status, - .read_ber = cx24110_read_ber, - .read_signal_strength = cx24110_read_signal_strength, - .read_snr = cx24110_read_snr, - .read_ucblocks = cx24110_read_ucblocks, - - .diseqc_send_master_cmd = cx24110_send_diseqc_msg, - .set_tone = cx24110_set_tone, - .set_voltage = cx24110_set_voltage, - .diseqc_send_burst = cx24110_diseqc_send_burst, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Conexant CX24110 DVB-S Demodulator driver"); -MODULE_AUTHOR("Peter Hettkamp"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx24110_attach); diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h deleted file mode 100644 index fdcceee91f3..00000000000 --- a/drivers/media/dvb/frontends/cx24110.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - cx24110 - Single Chip Satellite Channel Receiver driver module - - Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on - work - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef CX24110_H -#define CX24110_H - -#include <linux/dvb/frontend.h> - -struct cx24110_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) -{ - u8 buf[] = { - (u8)((val >> 24) & 0xff), - (u8)((val >> 16) & 0xff), - (u8)((val >> 8) & 0xff) - }; - - if (fe->ops.write) - return fe->ops.write(fe, buf, 3); - return 0; -} - -#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) -extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_CX24110 - -#endif // CX24110_H diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c deleted file mode 100644 index f6e7b0380a5..00000000000 --- a/drivers/media/dvb/frontends/cx24113.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * Driver for Conexant CX24113/CX24128 Tuner (Satellite) - * - * Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org> - * - * Developed for BBTI / Technisat - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "dvb_frontend.h" -#include "cx24113.h" - -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 dprintk(args...) \ - do { \ - if (debug) { \ - printk(KERN_DEBUG "CX24113: %s: ", __func__); \ - printk(args); \ - } \ - } while (0) - -struct cx24113_state { - struct i2c_adapter *i2c; - const struct cx24113_config *config; - -#define REV_CX24113 0x23 - u8 rev; - u8 ver; - - u8 icp_mode:1; - -#define ICP_LEVEL1 0 -#define ICP_LEVEL2 1 -#define ICP_LEVEL3 2 -#define ICP_LEVEL4 3 - u8 icp_man:2; - u8 icp_auto_low:2; - u8 icp_auto_mlow:2; - u8 icp_auto_mhi:2; - u8 icp_auto_hi:2; - u8 icp_dig; - -#define LNA_MIN_GAIN 0 -#define LNA_MID_GAIN 1 -#define LNA_MAX_GAIN 2 - u8 lna_gain:2; - - u8 acp_on:1; - - u8 vco_mode:2; - u8 vco_shift:1; -#define VCOBANDSEL_6 0x80 -#define VCOBANDSEL_5 0x01 -#define VCOBANDSEL_4 0x02 -#define VCOBANDSEL_3 0x04 -#define VCOBANDSEL_2 0x08 -#define VCOBANDSEL_1 0x10 - u8 vco_band; - -#define VCODIV4 4 -#define VCODIV2 2 - u8 vcodiv; - - u8 bs_delay:4; - u16 bs_freqcnt:13; - u16 bs_rdiv; - u8 prescaler_mode:1; - - u8 rfvga_bias_ctrl; - - s16 tuner_gain_thres; - u8 gain_level; - - u32 frequency; - - u8 refdiv; - - u8 Fwindow_enabled; -}; - -static int cx24113_writereg(struct cx24113_state *state, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->i2c_addr, - .flags = 0, .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk(KERN_DEBUG "%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); - return err; - } - - return 0; -} - -static int cx24113_readreg(struct cx24113_state *state, u8 reg) -{ - int ret; - u8 b; - struct i2c_msg msg[] = { - { .addr = state->config->i2c_addr, - .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->config->i2c_addr, - .flags = I2C_M_RD, .buf = &b, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk(KERN_DEBUG "%s: reg=0x%x (error=%d)\n", - __func__, reg, ret); - return ret; - } - - return b; -} - -static void cx24113_set_parameters(struct cx24113_state *state) -{ - u8 r; - - r = cx24113_readreg(state, 0x10) & 0x82; - r |= state->icp_mode; - r |= state->icp_man << 4; - r |= state->icp_dig << 2; - r |= state->prescaler_mode << 5; - cx24113_writereg(state, 0x10, r); - - r = (state->icp_auto_low << 0) | (state->icp_auto_mlow << 2) - | (state->icp_auto_mhi << 4) | (state->icp_auto_hi << 6); - cx24113_writereg(state, 0x11, r); - - if (state->rev == REV_CX24113) { - r = cx24113_readreg(state, 0x20) & 0xec; - r |= state->lna_gain; - r |= state->rfvga_bias_ctrl << 4; - cx24113_writereg(state, 0x20, r); - } - - r = cx24113_readreg(state, 0x12) & 0x03; - r |= state->acp_on << 2; - r |= state->bs_delay << 4; - cx24113_writereg(state, 0x12, r); - - r = cx24113_readreg(state, 0x18) & 0x40; - r |= state->vco_shift; - if (state->vco_band == VCOBANDSEL_6) - r |= (1 << 7); - else - r |= (state->vco_band << 1); - cx24113_writereg(state, 0x18, r); - - r = cx24113_readreg(state, 0x14) & 0x20; - r |= (state->vco_mode << 6) | ((state->bs_freqcnt >> 8) & 0x1f); - cx24113_writereg(state, 0x14, r); - cx24113_writereg(state, 0x15, (state->bs_freqcnt & 0xff)); - - cx24113_writereg(state, 0x16, (state->bs_rdiv >> 4) & 0xff); - r = (cx24113_readreg(state, 0x17) & 0x0f) | - ((state->bs_rdiv & 0x0f) << 4); - cx24113_writereg(state, 0x17, r); -} - -#define VGA_0 0x00 -#define VGA_1 0x04 -#define VGA_2 0x02 -#define VGA_3 0x06 -#define VGA_4 0x01 -#define VGA_5 0x05 -#define VGA_6 0x03 -#define VGA_7 0x07 - -#define RFVGA_0 0x00 -#define RFVGA_1 0x01 -#define RFVGA_2 0x02 -#define RFVGA_3 0x03 - -static int cx24113_set_gain_settings(struct cx24113_state *state, - s16 power_estimation) -{ - u8 ampout = cx24113_readreg(state, 0x1d) & 0xf0, - vga = cx24113_readreg(state, 0x1f) & 0x3f, - rfvga = cx24113_readreg(state, 0x20) & 0xf3; - u8 gain_level = power_estimation >= state->tuner_gain_thres; - - dprintk("power estimation: %d, thres: %d, gain_level: %d/%d\n", - power_estimation, state->tuner_gain_thres, - state->gain_level, gain_level); - - if (gain_level == state->gain_level) - return 0; /* nothing to be done */ - - ampout |= 0xf; - - if (gain_level) { - rfvga |= RFVGA_0 << 2; - vga |= (VGA_7 << 3) | VGA_7; - } else { - rfvga |= RFVGA_2 << 2; - vga |= (VGA_6 << 3) | VGA_2; - } - state->gain_level = gain_level; - - cx24113_writereg(state, 0x1d, ampout); - cx24113_writereg(state, 0x1f, vga); - cx24113_writereg(state, 0x20, rfvga); - - return 1; /* did something */ -} - -static int cx24113_set_Fref(struct cx24113_state *state, u8 high) -{ - u8 xtal = cx24113_readreg(state, 0x02); - if (state->rev == 0x43 && state->vcodiv == VCODIV4) - high = 1; - - xtal &= ~0x2; - if (high) - xtal |= high << 1; - return cx24113_writereg(state, 0x02, xtal); -} - -static int cx24113_enable(struct cx24113_state *state, u8 enable) -{ - u8 r21 = (cx24113_readreg(state, 0x21) & 0xc0) | enable; - if (state->rev == REV_CX24113) - r21 |= (1 << 1); - return cx24113_writereg(state, 0x21, r21); -} - -static int cx24113_set_bandwidth(struct cx24113_state *state, u32 bandwidth_khz) -{ - u8 r; - - if (bandwidth_khz <= 19000) - r = 0x03 << 6; - else if (bandwidth_khz <= 25000) - r = 0x02 << 6; - else - r = 0x01 << 6; - - dprintk("bandwidth to be set: %d\n", bandwidth_khz); - bandwidth_khz *= 10; - bandwidth_khz -= 10000; - bandwidth_khz /= 1000; - bandwidth_khz += 5; - bandwidth_khz /= 10; - - dprintk("bandwidth: %d %d\n", r >> 6, bandwidth_khz); - - r |= bandwidth_khz & 0x3f; - - return cx24113_writereg(state, 0x1e, r); -} - -static int cx24113_set_clk_inversion(struct cx24113_state *state, u8 on) -{ - u8 r = (cx24113_readreg(state, 0x10) & 0x7f) | ((on & 0x1) << 7); - return cx24113_writereg(state, 0x10, r); -} - -static int cx24113_get_status(struct dvb_frontend *fe, u32 *status) -{ - struct cx24113_state *state = fe->tuner_priv; - u8 r = (cx24113_readreg(state, 0x10) & 0x02) >> 1; - if (r) - *status |= TUNER_STATUS_LOCKED; - dprintk("PLL locked: %d\n", r); - return 0; -} - -static u8 cx24113_set_ref_div(struct cx24113_state *state, u8 refdiv) -{ - if (state->rev == 0x43 && state->vcodiv == VCODIV4) - refdiv = 2; - return state->refdiv = refdiv; -} - -static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f) -{ - s32 N; - s64 F; - u8 R, r; - u8 vcodiv; - u8 factor; - s32 freq_hz = state->frequency * 1000; - - if (state->config->xtal_khz < 20000) - factor = 1; - else - factor = 2; - - if (state->rev == REV_CX24113) { - if (state->frequency >= 1100000) - vcodiv = VCODIV2; - else - vcodiv = VCODIV4; - } else { - if (state->frequency >= 1165000) - vcodiv = VCODIV2; - else - vcodiv = VCODIV4; - } - state->vcodiv = vcodiv; - - dprintk("calculating N/F for %dHz with vcodiv %d\n", freq_hz, vcodiv); - R = 0; - do { - R = cx24113_set_ref_div(state, R + 1); - - /* calculate tuner PLL settings: */ - N = (freq_hz / 100 * vcodiv) * R; - N /= (state->config->xtal_khz) * factor * 2; - N += 5; /* For round up. */ - N /= 10; - N -= 32; - } while (N < 6 && R < 3); - - if (N < 6) { - err("strange frequency: N < 6\n"); - return; - } - F = freq_hz; - F *= (u64) (R * vcodiv * 262144); - dprintk("1 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - do_div(F, state->config->xtal_khz*1000 * factor * 2); - dprintk("2 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - F -= (N + 32) * 262144; - - dprintk("3 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - - if (state->Fwindow_enabled) { - if (F > (262144 / 2 - 1638)) - F = 262144 / 2 - 1638; - if (F < (-262144 / 2 + 1638)) - F = -262144 / 2 + 1638; - if ((F < 3277 && F > 0) || (F > -3277 && F < 0)) { - F = 0; - r = cx24113_readreg(state, 0x10); - cx24113_writereg(state, 0x10, r | (1 << 6)); - } - } - dprintk("4 N: %d, F: %lld, R: %d\n", N, (long long)F, R); - - *n = (u16) N; - *f = (s32) F; -} - - -static void cx24113_set_nfr(struct cx24113_state *state, u16 n, s32 f, u8 r) -{ - u8 reg; - cx24113_writereg(state, 0x19, (n >> 1) & 0xff); - - reg = ((n & 0x1) << 7) | ((f >> 11) & 0x7f); - cx24113_writereg(state, 0x1a, reg); - - cx24113_writereg(state, 0x1b, (f >> 3) & 0xff); - - reg = cx24113_readreg(state, 0x1c) & 0x1f; - cx24113_writereg(state, 0x1c, reg | ((f & 0x7) << 5)); - - cx24113_set_Fref(state, r - 1); -} - -static int cx24113_set_frequency(struct cx24113_state *state, u32 frequency) -{ - u8 r = 1; /* or 2 */ - u16 n = 6; - s32 f = 0; - - r = cx24113_readreg(state, 0x14); - cx24113_writereg(state, 0x14, r & 0x3f); - - r = cx24113_readreg(state, 0x10); - cx24113_writereg(state, 0x10, r & 0xbf); - - state->frequency = frequency; - - dprintk("tuning to frequency: %d\n", frequency); - - cx24113_calc_pll_nf(state, &n, &f); - cx24113_set_nfr(state, n, f, state->refdiv); - - r = cx24113_readreg(state, 0x18) & 0xbf; - if (state->vcodiv != VCODIV2) - r |= 1 << 6; - cx24113_writereg(state, 0x18, r); - - /* The need for this sleep is not clear. But helps in some cases */ - msleep(5); - - r = cx24113_readreg(state, 0x1c) & 0xef; - cx24113_writereg(state, 0x1c, r | (1 << 4)); - return 0; -} - -static int cx24113_init(struct dvb_frontend *fe) -{ - struct cx24113_state *state = fe->tuner_priv; - int ret; - - state->tuner_gain_thres = -50; - state->gain_level = 255; /* to force a gain-setting initialization */ - state->icp_mode = 0; - - if (state->config->xtal_khz < 11000) { - state->icp_auto_hi = ICP_LEVEL4; - state->icp_auto_mhi = ICP_LEVEL4; - state->icp_auto_mlow = ICP_LEVEL3; - state->icp_auto_low = ICP_LEVEL3; - } else { - state->icp_auto_hi = ICP_LEVEL4; - state->icp_auto_mhi = ICP_LEVEL4; - state->icp_auto_mlow = ICP_LEVEL3; - state->icp_auto_low = ICP_LEVEL2; - } - - state->icp_dig = ICP_LEVEL3; - state->icp_man = ICP_LEVEL1; - state->acp_on = 1; - state->vco_mode = 0; - state->vco_shift = 0; - state->vco_band = VCOBANDSEL_1; - state->bs_delay = 8; - state->bs_freqcnt = 0x0fff; - state->bs_rdiv = 0x0fff; - state->prescaler_mode = 0; - state->lna_gain = LNA_MAX_GAIN; - state->rfvga_bias_ctrl = 1; - state->Fwindow_enabled = 1; - - cx24113_set_Fref(state, 0); - cx24113_enable(state, 0x3d); - cx24113_set_parameters(state); - - cx24113_set_gain_settings(state, -30); - - cx24113_set_bandwidth(state, 18025); - cx24113_set_clk_inversion(state, 1); - - if (state->config->xtal_khz >= 40000) - ret = cx24113_writereg(state, 0x02, - (cx24113_readreg(state, 0x02) & 0xfb) | (1 << 2)); - else - ret = cx24113_writereg(state, 0x02, - (cx24113_readreg(state, 0x02) & 0xfb) | (0 << 2)); - - return ret; -} - -static int cx24113_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24113_state *state = fe->tuner_priv; - /* for a ROLL-OFF factor of 0.35, 0.2: 600, 0.25: 625 */ - u32 roll_off = 675; - u32 bw; - - bw = ((p->u.qpsk.symbol_rate/100) * roll_off) / 1000; - bw += (10000000/100) + 5; - bw /= 10; - bw += 1000; - cx24113_set_bandwidth(state, bw); - - cx24113_set_frequency(state, p->frequency); - msleep(5); - return cx24113_get_status(fe, &bw); -} - -static s8 cx24113_agc_table[2][10] = { - {-54, -41, -35, -30, -25, -21, -16, -10, -6, -2}, - {-39, -35, -30, -25, -19, -15, -11, -5, 1, 9}, -}; - -void cx24113_agc_callback(struct dvb_frontend *fe) -{ - struct cx24113_state *state = fe->tuner_priv; - s16 s, i; - if (!fe->ops.read_signal_strength) - return; - - do { - /* this only works with the current CX24123 implementation */ - fe->ops.read_signal_strength(fe, (u16 *) &s); - s >>= 8; - dprintk("signal strength: %d\n", s); - for (i = 0; i < sizeof(cx24113_agc_table[0]); i++) - if (cx24113_agc_table[state->gain_level][i] > s) - break; - s = -25 - i*5; - } while (cx24113_set_gain_settings(state, s)); -} -EXPORT_SYMBOL(cx24113_agc_callback); - -static int cx24113_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct cx24113_state *state = fe->tuner_priv; - *frequency = state->frequency; - return 0; -} - -static int cx24113_release(struct dvb_frontend *fe) -{ - struct cx24113_state *state = fe->tuner_priv; - dprintk("\n"); - fe->tuner_priv = NULL; - kfree(state); - return 0; -} - -static const struct dvb_tuner_ops cx24113_tuner_ops = { - .info = { - .name = "Conexant CX24113", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 125, - }, - - .release = cx24113_release, - - .init = cx24113_init, - .sleep = NULL, - - .set_params = cx24113_set_params, - .get_frequency = cx24113_get_frequency, - .get_bandwidth = NULL, - .get_status = cx24113_get_status, -}; - -struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, - const struct cx24113_config *config, struct i2c_adapter *i2c) -{ - /* allocate memory for the internal state */ - struct cx24113_state *state = - kzalloc(sizeof(struct cx24113_state), GFP_KERNEL); - int rc; - if (state == NULL) { - err("Unable to kmalloc\n"); - goto error; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - info("trying to detect myself\n"); - - /* making a dummy read, because of some expected troubles - * after power on */ - cx24113_readreg(state, 0x00); - - rc = cx24113_readreg(state, 0x00); - if (rc < 0) { - info("CX24113 not found.\n"); - goto error; - } - state->rev = rc; - - switch (rc) { - case 0x43: - info("detected CX24113 variant\n"); - break; - case REV_CX24113: - info("sucessfully detected\n"); - break; - default: - err("unsupported device id: %x\n", state->rev); - goto error; - } - state->ver = cx24113_readreg(state, 0x01); - info("version: %x\n", state->ver); - - /* create dvb_frontend */ - memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops, - sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = state; - return fe; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(cx24113_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>"); -MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24113/CX24128hardware"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/cx24113.h b/drivers/media/dvb/frontends/cx24113.h deleted file mode 100644 index 5de0f7ffd8d..00000000000 --- a/drivers/media/dvb/frontends/cx24113.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Driver for Conexant CX24113/CX24128 Tuner (Satelite) - * - * Copyright (C) 2007-8 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef CX24113_H -#define CX24113_H - -struct dvb_frontend; - -struct cx24113_config { - u8 i2c_addr; /* 0x14 or 0x54 */ - - u32 xtal_khz; -}; - -#if defined(CONFIG_DVB_TUNER_CX24113) || \ - (defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE)) -extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *, - const struct cx24113_config *config, struct i2c_adapter *i2c); - -extern void cx24113_agc_callback(struct dvb_frontend *fe); -#else -static inline struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, - const struct cx24113_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline void cx24113_agc_callback(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -} -#endif - -#endif /* CX24113_H */ diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c deleted file mode 100644 index 28ad609e73f..00000000000 --- a/drivers/media/dvb/frontends/cx24116.c +++ /dev/null @@ -1,1494 +0,0 @@ -/* - Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver - - Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com> - Copyright (C) 2006-2007 Georg Acher - Copyright (C) 2007-2008 Darron Broad - March 2007 - Fixed some bugs. - Added diseqc support. - Added corrected signal strength support. - August 2007 - Sync with legacy version. - Some clean ups. - Copyright (C) 2008 Igor Liplianin - September, 9th 2008 - Fixed locking on high symbol rates (>30000). - Implement MPEG initialization parameter. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/firmware.h> - -#include "dvb_frontend.h" -#include "cx24116.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_INFO "cx24116: " args); \ - } while (0) - -#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw" -#define CX24116_SEARCH_RANGE_KHZ 5000 - -/* known registers */ -#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */ -#define CX24116_REG_EXECUTE (0x1f) /* execute command */ -#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */ -#define CX24116_REG_RESET (0x20) /* reset status > 0 */ -#define CX24116_REG_SIGNAL (0x9e) /* signal low */ -#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */ -#define CX24116_REG_QUALITY8 (0xa3) -#define CX24116_REG_QSTATUS (0xbc) -#define CX24116_REG_QUALITY0 (0xd5) -#define CX24116_REG_BER0 (0xc9) -#define CX24116_REG_BER8 (0xc8) -#define CX24116_REG_BER16 (0xc7) -#define CX24116_REG_BER24 (0xc6) -#define CX24116_REG_UCB0 (0xcb) -#define CX24116_REG_UCB8 (0xca) -#define CX24116_REG_CLKDIV (0xf3) -#define CX24116_REG_RATEDIV (0xf9) - -/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */ -#define CX24116_REG_FECSTATUS (0x9c) - -/* FECSTATUS bits */ -/* mask to determine configured fec (not tuned) or actual fec (tuned) */ -#define CX24116_FEC_FECMASK (0x1f) - -/* Select DVB-S demodulator, else DVB-S2 */ -#define CX24116_FEC_DVBS (0x20) -#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */ - -/* Pilot mode requested when tuning else always reset when tuned */ -#define CX24116_FEC_PILOT (0x80) - -/* arg buffer size */ -#define CX24116_ARGLEN (0x1e) - -/* rolloff */ -#define CX24116_ROLLOFF_020 (0x00) -#define CX24116_ROLLOFF_025 (0x01) -#define CX24116_ROLLOFF_035 (0x02) - -/* pilot bit */ -#define CX24116_PILOT_OFF (0x00) -#define CX24116_PILOT_ON (0x40) - -/* signal status */ -#define CX24116_HAS_SIGNAL (0x01) -#define CX24116_HAS_CARRIER (0x02) -#define CX24116_HAS_VITERBI (0x04) -#define CX24116_HAS_SYNCLOCK (0x08) -#define CX24116_HAS_UNKNOWN1 (0x10) -#define CX24116_HAS_UNKNOWN2 (0x20) -#define CX24116_STATUS_MASK (0x0f) -#define CX24116_SIGNAL_MASK (0xc0) - -#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */ -#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */ -#define CX24116_DISEQC_MESGCACHE (2) /* message cached */ - -/* arg offset for DiSEqC */ -#define CX24116_DISEQC_BURST (1) -#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */ -#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */ -#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */ -#define CX24116_DISEQC_MSGLEN (5) -#define CX24116_DISEQC_MSGOFS (6) - -/* DiSEqC burst */ -#define CX24116_DISEQC_MINI_A (0) -#define CX24116_DISEQC_MINI_B (1) - -/* DiSEqC tone burst */ -static int toneburst = 1; -module_param(toneburst, int, 0644); -MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\ - "2=MESSAGE CACHE (default:1)"); - -/* SNR measurements */ -static int esno_snr; -module_param(esno_snr, int, 0644); -MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\ - "1=ESNO(db * 10) (default:0)"); - -enum cmds { - CMD_SET_VCO = 0x10, - CMD_TUNEREQUEST = 0x11, - CMD_MPEGCONFIG = 0x13, - CMD_TUNERINIT = 0x14, - CMD_BANDWIDTH = 0x15, - CMD_GETAGC = 0x19, - CMD_LNBCONFIG = 0x20, - CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */ - CMD_SET_TONEPRE = 0x22, - CMD_SET_TONE = 0x23, - CMD_UPDFWVERS = 0x35, - CMD_TUNERSLEEP = 0x36, - CMD_AGCCONTROL = 0x3b, /* Unknown */ -}; - -/* The Demod/Tuner can't easily provide these, we cache them */ -struct cx24116_tuning { - u32 frequency; - u32 symbol_rate; - fe_spectral_inversion_t inversion; - fe_code_rate_t fec; - - fe_delivery_system_t delsys; - fe_modulation_t modulation; - fe_pilot_t pilot; - fe_rolloff_t rolloff; - - /* Demod values */ - u8 fec_val; - u8 fec_mask; - u8 inversion_val; - u8 pilot_val; - u8 rolloff_val; -}; - -/* Basic commands that are sent to the firmware */ -struct cx24116_cmd { - u8 len; - u8 args[CX24116_ARGLEN]; -}; - -struct cx24116_state { - struct i2c_adapter *i2c; - const struct cx24116_config *config; - - struct dvb_frontend frontend; - - struct cx24116_tuning dcur; - struct cx24116_tuning dnxt; - - u8 skip_fw_load; - u8 burst; - struct cx24116_cmd dsec_cmd; -}; - -static int cx24116_writereg(struct cx24116_state *state, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 2 }; - int err; - - if (debug > 1) - printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n", - __func__, reg, data); - - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x," - " value == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -/* Bulk byte writes to a single I2C address, for 32k firmware load */ -static int cx24116_writeregN(struct cx24116_state *state, int reg, - const u8 *data, u16 len) -{ - int ret = -EREMOTEIO; - struct i2c_msg msg; - u8 *buf; - - buf = kmalloc(len + 1, GFP_KERNEL); - if (buf == NULL) { - printk("Unable to kmalloc\n"); - ret = -ENOMEM; - goto error; - } - - *(buf) = reg; - memcpy(buf + 1, data, len); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = len + 1; - - if (debug > 1) - printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n", - __func__, reg, len); - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) { - printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n", - __func__, ret, reg); - ret = -EREMOTEIO; - } - -error: - kfree(buf); - - return ret; -} - -static int cx24116_readreg(struct cx24116_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk(KERN_ERR "%s: reg=0x%x (error=%d)\n", - __func__, reg, ret); - return ret; - } - - if (debug > 1) - printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n", - reg, b1[0]); - - return b1[0]; -} - -static int cx24116_set_inversion(struct cx24116_state *state, - fe_spectral_inversion_t inversion) -{ - dprintk("%s(%d)\n", __func__, inversion); - - switch (inversion) { - case INVERSION_OFF: - state->dnxt.inversion_val = 0x00; - break; - case INVERSION_ON: - state->dnxt.inversion_val = 0x04; - break; - case INVERSION_AUTO: - state->dnxt.inversion_val = 0x0C; - break; - default: - return -EINVAL; - } - - state->dnxt.inversion = inversion; - - return 0; -} - -/* - * modfec (modulation and FEC) - * =========================== - * - * MOD FEC mask/val standard - * ---- -------- ----------- -------- - * QPSK FEC_1_2 0x02 0x02+X DVB-S - * QPSK FEC_2_3 0x04 0x02+X DVB-S - * QPSK FEC_3_4 0x08 0x02+X DVB-S - * QPSK FEC_4_5 0x10 0x02+X DVB-S (?) - * QPSK FEC_5_6 0x20 0x02+X DVB-S - * QPSK FEC_6_7 0x40 0x02+X DVB-S - * QPSK FEC_7_8 0x80 0x02+X DVB-S - * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?) - * QPSK AUTO 0xff 0x02+X DVB-S - * - * For DVB-S high byte probably represents FEC - * and low byte selects the modulator. The high - * byte is search range mask. Bit 5 may turn - * on DVB-S and remaining bits represent some - * kind of calibration (how/what i do not know). - * - * Eg.(2/3) szap "Zone Horror" - * - * mask/val = 0x04, 0x20 - * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK - * - * mask/val = 0x04, 0x30 - * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK - * - * After tuning FECSTATUS contains actual FEC - * in use numbered 1 through to 8 for 1/2 .. 2/3 etc - * - * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only) - * - * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2 - * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2 - * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2 - * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2 - * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2 - * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2 - * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2 - * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2 - * - * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2 - * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2 - * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2 - * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2 - * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2 - * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2 - * - * For DVB-S2 low bytes selects both modulator - * and FEC. High byte is meaningless here. To - * set pilot, bit 6 (0x40) is set. When inspecting - * FECSTATUS bit 7 (0x80) represents the pilot - * selection whilst not tuned. When tuned, actual FEC - * in use is found in FECSTATUS as per above. Pilot - * value is reset. - */ - -/* A table of modulation, fec and configuration bytes for the demod. - * Not all S2 mmodulation schemes are support and not all rates with - * a scheme are support. Especially, no auto detect when in S2 mode. - */ -static struct cx24116_modfec { - fe_delivery_system_t delivery_system; - fe_modulation_t modulation; - fe_code_rate_t fec; - u8 mask; /* In DVBS mode this is used to autodetect */ - u8 val; /* Passed to the firmware to indicate mode selection */ -} CX24116_MODFEC_MODES[] = { - /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */ - - /*mod fec mask val */ - { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 }, - { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */ - { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */ - { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */ - { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */ - { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */ - { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */ - { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */ - { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */ - { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 }, - /* NBC-QPSK */ - { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 }, - { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 }, - { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 }, - { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 }, - { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 }, - { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 }, - { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a }, - { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b }, - /* 8PSK */ - { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c }, - { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d }, - { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e }, - { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f }, - { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 }, - { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 }, - /* - * `val' can be found in the FECSTATUS register when tuning. - * FECSTATUS will give the actual FEC in use if tuning was successful. - */ -}; - -static int cx24116_lookup_fecmod(struct cx24116_state *state, - fe_delivery_system_t d, fe_modulation_t m, fe_code_rate_t f) -{ - int i, ret = -EOPNOTSUPP; - - dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f); - - for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) { - if ((d == CX24116_MODFEC_MODES[i].delivery_system) && - (m == CX24116_MODFEC_MODES[i].modulation) && - (f == CX24116_MODFEC_MODES[i].fec)) { - ret = i; - break; - } - } - - return ret; -} - -static int cx24116_set_fec(struct cx24116_state *state, - fe_delivery_system_t delsys, fe_modulation_t mod, fe_code_rate_t fec) -{ - int ret = 0; - - dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec); - - ret = cx24116_lookup_fecmod(state, delsys, mod, fec); - - if (ret < 0) - return ret; - - state->dnxt.fec = fec; - state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val; - state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask; - dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__, - state->dnxt.fec_mask, state->dnxt.fec_val); - - return 0; -} - -static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate) -{ - dprintk("%s(%d)\n", __func__, rate); - - /* check if symbol rate is within limits */ - if ((rate > state->frontend.ops.info.symbol_rate_max) || - (rate < state->frontend.ops.info.symbol_rate_min)) { - dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate); - return -EOPNOTSUPP; - } - - state->dnxt.symbol_rate = rate; - dprintk("%s() symbol_rate = %d\n", __func__, rate); - - return 0; -} - -static int cx24116_load_firmware(struct dvb_frontend *fe, - const struct firmware *fw); - -static int cx24116_firmware_ondemand(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - const struct firmware *fw; - int ret = 0; - - dprintk("%s()\n", __func__); - - if (cx24116_readreg(state, 0x20) > 0) { - - if (state->skip_fw_load) - return 0; - - /* Load firmware */ - /* request the firmware, this will block until loaded */ - printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", - __func__, CX24116_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, - &state->i2c->dev); - printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", - __func__); - if (ret) { - printk(KERN_ERR "%s: No firmware uploaded " - "(timeout or file not found?)\n", __func__); - return ret; - } - - /* Make sure we don't recurse back through here - * during loading */ - state->skip_fw_load = 1; - - ret = cx24116_load_firmware(fe, fw); - if (ret) - printk(KERN_ERR "%s: Writing firmware to device failed\n", - __func__); - - release_firmware(fw); - - printk(KERN_INFO "%s: Firmware upload %s\n", __func__, - ret == 0 ? "complete" : "failed"); - - /* Ensure firmware is always loaded if required */ - state->skip_fw_load = 0; - } - - return ret; -} - -/* Take a basic firmware command structure, format it - * and forward it for processing - */ -static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i, ret; - - dprintk("%s()\n", __func__); - - /* Load the firmware if required */ - ret = cx24116_firmware_ondemand(fe); - if (ret != 0) { - printk(KERN_ERR "%s(): Unable initialise the firmware\n", - __func__); - return ret; - } - - /* Write the command */ - for (i = 0; i < cmd->len ; i++) { - dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]); - cx24116_writereg(state, i, cmd->args[i]); - } - - /* Start execution and wait for cmd to terminate */ - cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01); - while (cx24116_readreg(state, CX24116_REG_EXECUTE)) { - msleep(10); - if (i++ > 64) { - /* Avoid looping forever if the firmware does - not respond */ - printk(KERN_WARNING "%s() Firmware not responding\n", - __func__); - return -EREMOTEIO; - } - } - return 0; -} - -static int cx24116_load_firmware(struct dvb_frontend *fe, - const struct firmware *fw) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int i, ret; - unsigned char vers[4]; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n", - fw->size, - fw->data[0], - fw->data[1], - fw->data[fw->size-2], - fw->data[fw->size-1]); - - /* Toggle 88x SRST pin to reset demod */ - if (state->config->reset_device) - state->config->reset_device(fe); - - /* Begin the firmware load process */ - /* Prepare the demod, load the firmware, cleanup after load */ - - /* Init PLL */ - cx24116_writereg(state, 0xE5, 0x00); - cx24116_writereg(state, 0xF1, 0x08); - cx24116_writereg(state, 0xF2, 0x13); - - /* Start PLL */ - cx24116_writereg(state, 0xe0, 0x03); - cx24116_writereg(state, 0xe0, 0x00); - - /* Unknown */ - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); - - /* Unknown */ - cx24116_writereg(state, 0xF0, 0x03); - cx24116_writereg(state, 0xF4, 0x81); - cx24116_writereg(state, 0xF5, 0x00); - cx24116_writereg(state, 0xF6, 0x00); - - /* write the entire firmware as one transaction */ - cx24116_writeregN(state, 0xF7, fw->data, fw->size); - - cx24116_writereg(state, 0xF4, 0x10); - cx24116_writereg(state, 0xF0, 0x00); - cx24116_writereg(state, 0xF8, 0x06); - - /* Firmware CMD 10: VCO config */ - cmd.args[0x00] = CMD_SET_VCO; - cmd.args[0x01] = 0x05; - cmd.args[0x02] = 0xdc; - cmd.args[0x03] = 0xda; - cmd.args[0x04] = 0xae; - cmd.args[0x05] = 0xaa; - cmd.args[0x06] = 0x04; - cmd.args[0x07] = 0x9d; - cmd.args[0x08] = 0xfc; - cmd.args[0x09] = 0x06; - cmd.len = 0x0a; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00); - - /* Firmware CMD 14: Tuner config */ - cmd.args[0x00] = CMD_TUNERINIT; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x00; - cmd.len = 0x03; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - cx24116_writereg(state, 0xe5, 0x00); - - /* Firmware CMD 13: MPEG config */ - cmd.args[0x00] = CMD_MPEGCONFIG; - cmd.args[0x01] = 0x01; - cmd.args[0x02] = 0x75; - cmd.args[0x03] = 0x00; - if (state->config->mpg_clk_pos_pol) - cmd.args[0x04] = state->config->mpg_clk_pos_pol; - else - cmd.args[0x04] = 0x02; - cmd.args[0x05] = 0x00; - cmd.len = 0x06; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Firmware CMD 35: Get firmware version */ - cmd.args[0x00] = CMD_UPDFWVERS; - cmd.len = 0x02; - for (i = 0; i < 4; i++) { - cmd.args[0x01] = i; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX); - } - printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__, - vers[0], vers[1], vers[2], vers[3]); - - return 0; -} - -static int cx24116_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - /* The isl6421 module will override this function in the fops. */ - dprintk("%s() This should never appear if the isl6421 module " - "is loaded correctly\n", __func__); - - return -EOPNOTSUPP; -} - -static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct cx24116_state *state = fe->demodulator_priv; - - int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) & - CX24116_STATUS_MASK; - - dprintk("%s: status = 0x%02x\n", __func__, lock); - - *status = 0; - - if (lock & CX24116_HAS_SIGNAL) - *status |= FE_HAS_SIGNAL; - if (lock & CX24116_HAS_CARRIER) - *status |= FE_HAS_CARRIER; - if (lock & CX24116_HAS_VITERBI) - *status |= FE_HAS_VITERBI; - if (lock & CX24116_HAS_SYNCLOCK) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - return 0; -} - -static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) | - (cx24116_readreg(state, CX24116_REG_BER16) << 16) | - (cx24116_readreg(state, CX24116_REG_BER8) << 8) | - cx24116_readreg(state, CX24116_REG_BER0); - - return 0; -} - -/* TODO Determine function and scale appropriately */ -static int cx24116_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - u16 sig_reading; - - dprintk("%s()\n", __func__); - - /* Firmware CMD 19: Get AGC */ - cmd.args[0x00] = CMD_GETAGC; - cmd.len = 0x01; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - sig_reading = - (cx24116_readreg(state, - CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) | - (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6); - *signal_strength = 0 - sig_reading; - - dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", - __func__, sig_reading, *signal_strength); - - return 0; -} - -/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */ -static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr) -{ - struct cx24116_state *state = fe->demodulator_priv; - u8 snr_reading; - static const u32 snr_tab[] = { /* 10 x Table (rounded up) */ - 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667, - 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667, - 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667, - 0x18000 }; - - dprintk("%s()\n", __func__); - - snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0); - - if (snr_reading >= 0xa0 /* 100% */) - *snr = 0xffff; - else - *snr = snr_tab[(snr_reading & 0xf0) >> 4] + - (snr_tab[(snr_reading & 0x0f)] >> 4); - - dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__, - snr_reading, *snr); - - return 0; -} - -/* The reelbox patches show the value in the registers represents - * ESNO, from 0->30db (values 0->300). We provide this value by - * default. - */ -static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 | - cx24116_readreg(state, CX24116_REG_QUALITY0); - - dprintk("%s: raw 0x%04x\n", __func__, *snr); - - return 0; -} - -static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - if (esno_snr == 1) - return cx24116_read_snr_esno(fe, snr); - else - return cx24116_read_snr_pct(fe, snr); -} - -static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct cx24116_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) | - cx24116_readreg(state, CX24116_REG_UCB0); - - return 0; -} - -/* Overwrite the current tuning params, we are about to tune */ -static void cx24116_clone_params(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur)); -} - -/* Wait for LNB */ -static int cx24116_wait_for_lnb(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i; - - dprintk("%s() qstatus = 0x%02x\n", __func__, - cx24116_readreg(state, CX24116_REG_QSTATUS)); - - /* Wait for up to 300 ms */ - for (i = 0; i < 30 ; i++) { - if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20) - return 0; - msleep(10); - } - - dprintk("%s(): LNB not ready\n", __func__); - - return -ETIMEDOUT; /* -EBUSY ? */ -} - -static int cx24116_set_tone(struct dvb_frontend *fe, - fe_sec_tone_mode_t tone) -{ - struct cx24116_cmd cmd; - int ret; - - dprintk("%s(%d)\n", __func__, tone); - if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) { - printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone); - return -EINVAL; - } - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Min delay time after DiSEqC send */ - msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - - /* This is always done before the tone is set */ - cmd.args[0x00] = CMD_SET_TONEPRE; - cmd.args[0x01] = 0x00; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Now we set the tone */ - cmd.args[0x00] = CMD_SET_TONE; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x00; - - switch (tone) { - case SEC_TONE_ON: - dprintk("%s: setting tone on\n", __func__); - cmd.args[0x03] = 0x01; - break; - case SEC_TONE_OFF: - dprintk("%s: setting tone off\n", __func__); - cmd.args[0x03] = 0x00; - break; - } - cmd.len = 0x04; - - /* Min delay time before DiSEqC send */ - msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */ - - return cx24116_cmd_execute(fe, &cmd); -} - -/* Initialise DiSEqC */ -static int cx24116_diseqc_init(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - /* Firmware CMD 20: LNB/DiSEqC config */ - cmd.args[0x00] = CMD_LNBCONFIG; - cmd.args[0x01] = 0x00; - cmd.args[0x02] = 0x10; - cmd.args[0x03] = 0x00; - cmd.args[0x04] = 0x8f; - cmd.args[0x05] = 0x28; - cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01; - cmd.args[0x07] = 0x01; - cmd.len = 0x08; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Prepare a DiSEqC command */ - state->dsec_cmd.args[0x00] = CMD_LNBSEND; - - /* DiSEqC burst */ - state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A; - - /* Unknown */ - state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02; - state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00; - /* Continuation flag? */ - state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; - - /* DiSEqC message length */ - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00; - - /* Command length */ - state->dsec_cmd.len = CX24116_DISEQC_MSGOFS; - - return 0; -} - -/* Send DiSEqC message with derived burst (hack) || previous burst */ -static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *d) -{ - struct cx24116_state *state = fe->demodulator_priv; - int i, ret; - - /* Dump DiSEqC message */ - if (debug) { - printk(KERN_INFO "cx24116: %s(", __func__); - for (i = 0 ; i < d->msg_len ;) { - printk(KERN_INFO "0x%02x", d->msg[i]); - if (++i < d->msg_len) - printk(KERN_INFO ", "); - } - 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]; - - /* DiSEqC message length */ - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len; - - /* Command length */ - state->dsec_cmd.len = CX24116_DISEQC_MSGOFS + - state->dsec_cmd.args[CX24116_DISEQC_MSGLEN]; - - /* DiSEqC toneburst */ - if (toneburst == CX24116_DISEQC_MESGCACHE) - /* Message is cached */ - return 0; - - else if (toneburst == CX24116_DISEQC_TONEOFF) - /* Message is sent without burst */ - state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0; - - else if (toneburst == CX24116_DISEQC_TONECACHE) { - /* - * Message is sent with derived else cached burst - * - * WRITE PORT GROUP COMMAND 38 - * - * 0/A/A: E0 10 38 F0..F3 - * 1/B/B: E0 10 38 F4..F7 - * 2/C/A: E0 10 38 F8..FB - * 3/D/B: E0 10 38 FC..FF - * - * databyte[3]= 8421:8421 - * ABCD:WXYZ - * CLR :SET - * - * WX= PORT SELECT 0..3 (X=TONEBURST) - * Y = VOLTAGE (0=13V, 1=18V) - * Z = BAND (0=LOW, 1=HIGH(22K)) - */ - if (d->msg_len >= 4 && d->msg[2] == 0x38) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - ((d->msg[3] & 4) >> 2); - if (debug) - dprintk("%s burst=%d\n", __func__, - state->dsec_cmd.args[CX24116_DISEQC_BURST]); - } - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - /* Command */ - ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if (ret != 0) - return ret; - /* - * Wait for send - * - * Eutelsat spec: - * >15ms delay + (XXX determine if FW does this, see set_tone) - * 13.5ms per byte + - * >15ms delay + - * 12.5ms burst + - * >15ms delay (XXX determine if FW does this, see set_tone) - */ - msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + - ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60)); - - return 0; -} - -/* Send DiSEqC burst */ -static int cx24116_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct cx24116_state *state = fe->demodulator_priv; - int ret; - - dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst); - - /* DiSEqC burst */ - if (burst == SEC_MINI_A) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - CX24116_DISEQC_MINI_A; - else if (burst == SEC_MINI_B) - state->dsec_cmd.args[CX24116_DISEQC_BURST] = - CX24116_DISEQC_MINI_B; - else - return -EINVAL; - - /* DiSEqC toneburst */ - if (toneburst != CX24116_DISEQC_MESGCACHE) - /* Burst is cached */ - return 0; - - /* Burst is to be sent with cached message */ - - /* Wait for LNB ready */ - ret = cx24116_wait_for_lnb(fe); - if (ret != 0) - return ret; - - /* Wait for voltage/min repeat delay */ - msleep(100); - - /* Command */ - ret = cx24116_cmd_execute(fe, &state->dsec_cmd); - if (ret != 0) - return ret; - - /* - * Wait for send - * - * Eutelsat spec: - * >15ms delay + (XXX determine if FW does this, see set_tone) - * 13.5ms per byte + - * >15ms delay + - * 12.5ms burst + - * >15ms delay (XXX determine if FW does this, see set_tone) - */ - msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60); - - return 0; -} - -static void cx24116_release(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - dprintk("%s\n", __func__); - kfree(state); -} - -static struct dvb_frontend_ops cx24116_ops; - -struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, - struct i2c_adapter *i2c) -{ - struct cx24116_state *state = NULL; - int ret; - - dprintk("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL); - if (state == NULL) - goto error1; - - /* setup the state */ - memset(state, 0, sizeof(struct cx24116_state)); - - state->config = config; - state->i2c = i2c; - - /* check if the demod is present */ - ret = (cx24116_readreg(state, 0xFF) << 8) | - cx24116_readreg(state, 0xFE); - if (ret != 0x0501) { - printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n"); - goto error2; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24116_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error2: kfree(state); -error1: return NULL; -} -EXPORT_SYMBOL(cx24116_attach); - -/* - * Initialise or wake up device - * - * Power config will reset and load initial firmware if required - */ -static int cx24116_initfe(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - dprintk("%s()\n", __func__); - - /* Power on */ - cx24116_writereg(state, 0xe0, 0); - cx24116_writereg(state, 0xe1, 0); - cx24116_writereg(state, 0xea, 0); - - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 0; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - return cx24116_diseqc_init(fe); -} - -/* - * Put device to sleep - */ -static int cx24116_sleep(struct dvb_frontend *fe) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct cx24116_cmd cmd; - int ret; - - dprintk("%s()\n", __func__); - - /* Firmware CMD 36: Power config */ - cmd.args[0x00] = CMD_TUNERSLEEP; - cmd.args[0x01] = 1; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Power off (Shutdown clocks) */ - cx24116_writereg(state, 0xea, 0xff); - cx24116_writereg(state, 0xe1, 1); - cx24116_writereg(state, 0xe0, 1); - - return 0; -} - -static int cx24116_set_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int cx24116_get_property(struct dvb_frontend *fe, - struct dtv_property *tvp) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -/* dvb-core told us to tune, the tv property cache will be complete, - * it's safe for is to pull values and use them for tuning purposes. - */ -static int cx24116_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24116_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - struct cx24116_cmd cmd; - fe_status_t tunerstat; - int i, status, ret, retune = 1; - - dprintk("%s()\n", __func__); - - switch (c->delivery_system) { - case SYS_DVBS: - dprintk("%s: DVB-S delivery system selected\n", __func__); - - /* Only QPSK is supported for DVB-S */ - if (c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - /* Pilot doesn't exist in DVB-S, turn bit off */ - state->dnxt.pilot_val = CX24116_PILOT_OFF; - - /* DVB-S only supports 0.35 */ - if (c->rolloff != ROLLOFF_35) { - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; - - case SYS_DVBS2: - dprintk("%s: DVB-S2 delivery system selected\n", __func__); - - /* - * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2, - * but not hardware auto detection - */ - if (c->modulation != PSK_8 && c->modulation != QPSK) { - dprintk("%s: unsupported modulation selected (%d)\n", - __func__, c->modulation); - return -EOPNOTSUPP; - } - - switch (c->pilot) { - case PILOT_AUTO: /* Not supported but emulated */ - state->dnxt.pilot_val = (c->modulation == QPSK) - ? CX24116_PILOT_OFF : CX24116_PILOT_ON; - retune++; - break; - case PILOT_OFF: - state->dnxt.pilot_val = CX24116_PILOT_OFF; - break; - case PILOT_ON: - state->dnxt.pilot_val = CX24116_PILOT_ON; - break; - default: - dprintk("%s: unsupported pilot mode selected (%d)\n", - __func__, c->pilot); - return -EOPNOTSUPP; - } - - switch (c->rolloff) { - case ROLLOFF_20: - state->dnxt.rolloff_val = CX24116_ROLLOFF_020; - break; - case ROLLOFF_25: - state->dnxt.rolloff_val = CX24116_ROLLOFF_025; - break; - case ROLLOFF_35: - state->dnxt.rolloff_val = CX24116_ROLLOFF_035; - break; - case ROLLOFF_AUTO: /* Rolloff must be explicit */ - default: - dprintk("%s: unsupported rolloff selected (%d)\n", - __func__, c->rolloff); - return -EOPNOTSUPP; - } - break; - - default: - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - state->dnxt.delsys = c->delivery_system; - state->dnxt.modulation = c->modulation; - state->dnxt.frequency = c->frequency; - state->dnxt.pilot = c->pilot; - state->dnxt.rolloff = c->rolloff; - - ret = cx24116_set_inversion(state, c->inversion); - if (ret != 0) - return ret; - - /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */ - ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner); - if (ret != 0) - return ret; - - ret = cx24116_set_symbolrate(state, c->symbol_rate); - if (ret != 0) - return ret; - - /* discard the 'current' tuning parameters and prepare to tune */ - cx24116_clone_params(fe); - - dprintk("%s: delsys = %d\n", __func__, state->dcur.delsys); - dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation); - dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); - dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__, - state->dcur.pilot, state->dcur.pilot_val); - dprintk("%s: retune = %d\n", __func__, retune); - dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__, - state->dcur.rolloff, state->dcur.rolloff_val); - dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); - dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__, - state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val); - dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__, - state->dcur.inversion, state->dcur.inversion_val); - - /* This is also done in advise/acquire on HVR4000 but not on LITE */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* Set/Reset B/W */ - cmd.args[0x00] = CMD_BANDWIDTH; - cmd.args[0x01] = 0x01; - cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - /* Prepare a tune request */ - cmd.args[0x00] = CMD_TUNEREQUEST; - - /* Frequency */ - cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16; - cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8; - cmd.args[0x03] = (state->dcur.frequency & 0x0000ff); - - /* Symbol Rate */ - cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8; - cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff); - - /* Automatic Inversion */ - cmd.args[0x06] = state->dcur.inversion_val; - - /* Modulation / FEC / Pilot */ - cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val; - - cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8; - cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff; - cmd.args[0x0a] = 0x00; - cmd.args[0x0b] = 0x00; - cmd.args[0x0c] = state->dcur.rolloff_val; - cmd.args[0x0d] = state->dcur.fec_mask; - - if (state->dcur.symbol_rate > 30000000) { - cmd.args[0x0e] = 0x04; - cmd.args[0x0f] = 0x00; - cmd.args[0x10] = 0x01; - cmd.args[0x11] = 0x77; - cmd.args[0x12] = 0x36; - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01); - } else { - cmd.args[0x0e] = 0x06; - cmd.args[0x0f] = 0x00; - cmd.args[0x10] = 0x00; - cmd.args[0x11] = 0xFA; - cmd.args[0x12] = 0x24; - cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46); - cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00); - } - - cmd.len = 0x13; - - /* We need to support pilot and non-pilot tuning in the - * driver automatically. This is a workaround for because - * the demod does not support autodetect. - */ - do { - /* Reset status register */ - status = cx24116_readreg(state, CX24116_REG_SSTATUS) - & CX24116_SIGNAL_MASK; - cx24116_writereg(state, CX24116_REG_SSTATUS, status); - - /* Tune */ - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - break; - - /* - * Wait for up to 500 ms before retrying - * - * If we are able to tune then generally it occurs within 100ms. - * If it takes longer, try a different toneburst setting. - */ - for (i = 0; i < 50 ; i++) { - cx24116_read_status(fe, &tunerstat); - status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC); - if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) { - dprintk("%s: Tuned\n", __func__); - goto tuned; - } - msleep(10); - } - - dprintk("%s: Not tuned\n", __func__); - - /* Toggle pilot bit when in auto-pilot */ - if (state->dcur.pilot == PILOT_AUTO) - cmd.args[0x07] ^= CX24116_PILOT_ON; - } while (--retune); - -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; -} - -static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, - unsigned int mode_flags, unsigned int *delay, fe_status_t *status) -{ - *delay = HZ / 5; - if (params) { - int ret = cx24116_set_frontend(fe, params); - if (ret) - return ret; - } - return cx24116_read_status(fe, status); -} - -static int cx24116_get_algo(struct dvb_frontend *fe) -{ - return DVBFE_ALGO_HW; -} - -static struct dvb_frontend_ops cx24116_ops = { - - .info = { - .name = "Conexant CX24116/CX24118", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_2G_MODULATION | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24116_release, - - .init = cx24116_initfe, - .sleep = cx24116_sleep, - .read_status = cx24116_read_status, - .read_ber = cx24116_read_ber, - .read_signal_strength = cx24116_read_signal_strength, - .read_snr = cx24116_read_snr, - .read_ucblocks = cx24116_read_ucblocks, - .set_tone = cx24116_set_tone, - .set_voltage = cx24116_set_voltage, - .diseqc_send_master_cmd = cx24116_send_diseqc_msg, - .diseqc_send_burst = cx24116_diseqc_send_burst, - .get_frontend_algo = cx24116_get_algo, - .tune = cx24116_tune, - - .set_property = cx24116_set_property, - .get_property = cx24116_get_property, - .set_frontend = cx24116_set_frontend, -}; - -MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h deleted file mode 100644 index b1b76b47a14..00000000000 --- a/drivers/media/dvb/frontends/cx24116.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver - - Copyright (C) 2006 Steven Toth <stoth@linuxtv.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef CX24116_H -#define CX24116_H - -#include <linux/dvb/frontend.h> - -struct cx24116_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); - - /* Need to reset device during firmware loading */ - int (*reset_device)(struct dvb_frontend *fe); - - /* Need to set MPEG parameters */ - u8 mpg_clk_pos_pol:0x02; -}; - -#if defined(CONFIG_DVB_CX24116) || \ - (defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE)) -extern struct dvb_frontend *cx24116_attach( - const struct cx24116_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *cx24116_attach( - const struct cx24116_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif /* CX24116_H */ diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c deleted file mode 100644 index 1a8c36f7606..00000000000 --- a/drivers/media/dvb/frontends/cx24123.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - * - * Copyright (C) 2005 Steven Toth <stoth@linuxtv.org> - * - * Support for KWorld DVB-S 100 by Vadim Catana <skystar@moldova.cc> - * - * Support for CX24123/CX24113-NIM by Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> - -#include "dvb_frontend.h" -#include "cx24123.h" - -#define XTAL 10111000 - -static int force_band; -module_param(force_band, int, 0644); -MODULE_PARM_DESC(force_band, "Force a specific band select "\ - "(1-9, default:off)."); - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); - -#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0) -#define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0) - -#define dprintk(args...) \ - do { \ - if (debug) { \ - printk(KERN_DEBUG "CX24123: %s: ", __func__); \ - printk(args); \ - } \ - } while (0) - -struct cx24123_state { - struct i2c_adapter *i2c; - const struct cx24123_config *config; - - struct dvb_frontend frontend; - - /* Some PLL specifics for tuning */ - u32 VCAarg; - u32 VGAarg; - u32 bandselectarg; - u32 pllarg; - u32 FILTune; - - struct i2c_adapter tuner_i2c_adapter; - - u8 demod_rev; - - /* The Demod/Tuner can't easily provide these, we cache them */ - u32 currentfreq; - u32 currentsymbolrate; -}; - -/* Various tuner defaults need to be established for a given symbol rate Sps */ -static struct cx24123_AGC_val { - u32 symbolrate_low; - u32 symbolrate_high; - u32 VCAprogdata; - u32 VGAprogdata; - u32 FILTune; -} cx24123_AGC_vals[] = -{ - { - .symbolrate_low = 1000000, - .symbolrate_high = 4999999, - /* the specs recommend other values for VGA offsets, - but tests show they are wrong */ - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x07, - .FILTune = 0x27f /* 0.41 V */ - }, - { - .symbolrate_low = 5000000, - .symbolrate_high = 14999999, - .VGAprogdata = (1 << 19) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x1f, - .FILTune = 0x317 /* 0.90 V */ - }, - { - .symbolrate_low = 15000000, - .symbolrate_high = 45000000, - .VGAprogdata = (1 << 19) | (0x100 << 9) | 0x180, - .VCAprogdata = (2 << 19) | (0x07 << 9) | 0x3f, - .FILTune = 0x145 /* 2.70 V */ - }, -}; - -/* - * Various tuner defaults need to be established for a given frequency kHz. - * fixme: The bounds on the bands do not match the doc in real life. - * fixme: Some of them have been moved, other might need adjustment. - */ -static struct cx24123_bandselect_val { - u32 freq_low; - u32 freq_high; - u32 VCOdivider; - u32 progdata; -} cx24123_bandselect_vals[] = -{ - /* band 1 */ - { - .freq_low = 950000, - .freq_high = 1074999, - .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x40, - }, - - /* band 2 */ - { - .freq_low = 1075000, - .freq_high = 1177999, - .VCOdivider = 4, - .progdata = (0 << 19) | (0 << 9) | 0x80, - }, - - /* band 3 */ - { - .freq_low = 1178000, - .freq_high = 1295999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x01, - }, - - /* band 4 */ - { - .freq_low = 1296000, - .freq_high = 1431999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x02, - }, - - /* band 5 */ - { - .freq_low = 1432000, - .freq_high = 1575999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x04, - }, - - /* band 6 */ - { - .freq_low = 1576000, - .freq_high = 1717999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x08, - }, - - /* band 7 */ - { - .freq_low = 1718000, - .freq_high = 1855999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x10, - }, - - /* band 8 */ - { - .freq_low = 1856000, - .freq_high = 2035999, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x20, - }, - - /* band 9 */ - { - .freq_low = 2036000, - .freq_high = 2150000, - .VCOdivider = 2, - .progdata = (0 << 19) | (1 << 9) | 0x40, - }, -}; - -static struct { - u8 reg; - u8 data; -} cx24123_regdata[] = -{ - {0x00, 0x03}, /* Reset system */ - {0x00, 0x00}, /* Clear reset */ - {0x03, 0x07}, /* QPSK, DVB, Auto Acquisition (default) */ - {0x04, 0x10}, /* MPEG */ - {0x05, 0x04}, /* MPEG */ - {0x06, 0x31}, /* MPEG (default) */ - {0x0b, 0x00}, /* Freq search start point (default) */ - {0x0c, 0x00}, /* Demodulator sample gain (default) */ - {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */ - {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */ - {0x0f, 0xfe}, /* FEC search mask (all supported codes) */ - {0x10, 0x01}, /* Default search inversion, no repeat (default) */ - {0x16, 0x00}, /* Enable reading of frequency */ - {0x17, 0x01}, /* Enable EsNO Ready Counter */ - {0x1c, 0x80}, /* Enable error counter */ - {0x20, 0x00}, /* Tuner burst clock rate = 500KHz */ - {0x21, 0x15}, /* Tuner burst mode, word length = 0x15 */ - {0x28, 0x00}, /* Enable FILTERV with positive pol., DiSEqC 2.x off */ - {0x29, 0x00}, /* DiSEqC LNB_DC off */ - {0x2a, 0xb0}, /* DiSEqC Parameters (default) */ - {0x2b, 0x73}, /* DiSEqC Tone Frequency (default) */ - {0x2c, 0x00}, /* DiSEqC Message (0x2c - 0x31) */ - {0x2d, 0x00}, - {0x2e, 0x00}, - {0x2f, 0x00}, - {0x30, 0x00}, - {0x31, 0x00}, - {0x32, 0x8c}, /* DiSEqC Parameters (default) */ - {0x33, 0x00}, /* Interrupts off (0x33 - 0x34) */ - {0x34, 0x00}, - {0x35, 0x03}, /* DiSEqC Tone Amplitude (default) */ - {0x36, 0x02}, /* DiSEqC Parameters (default) */ - {0x37, 0x3a}, /* DiSEqC Parameters (default) */ - {0x3a, 0x00}, /* Enable AGC accumulator (for signal strength) */ - {0x44, 0x00}, /* Constellation (default) */ - {0x45, 0x00}, /* Symbol count (default) */ - {0x46, 0x0d}, /* Symbol rate estimator on (default) */ - {0x56, 0xc1}, /* Error Counter = Viterbi BER */ - {0x57, 0xff}, /* Error Counter Window (default) */ - {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */ - {0x67, 0x83}, /* Non-DCII symbol clock */ -}; - -static int cx24123_i2c_writereg(struct cx24123_state *state, - u8 i2c_addr, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2 - }; - int err; - - /* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */ - - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __func__, err, reg, data); - return err; - } - - return 0; -} - -static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg) -{ - int ret; - u8 b = 0; - struct i2c_msg msg[] = { - { .addr = i2c_addr, .flags = 0, .buf = ®, .len = 1 }, - { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &b, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - err("%s: reg=0x%x (error=%d)\n", __func__, reg, ret); - return ret; - } - - /* printk(KERN_DEBUG "rd(%02x): %02x %02x\n", i2c_addr, reg, b); */ - - return b; -} - -#define cx24123_readreg(state, reg) \ - cx24123_i2c_readreg(state, state->config->demod_address, reg) -#define cx24123_writereg(state, reg, val) \ - cx24123_i2c_writereg(state, state->config->demod_address, reg, val) - -static int cx24123_set_inversion(struct cx24123_state *state, - fe_spectral_inversion_t inversion) -{ - u8 nom_reg = cx24123_readreg(state, 0x0e); - u8 auto_reg = cx24123_readreg(state, 0x10); - - switch (inversion) { - case INVERSION_OFF: - dprintk("inversion off\n"); - cx24123_writereg(state, 0x0e, nom_reg & ~0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); - break; - case INVERSION_ON: - dprintk("inversion on\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x80); - cx24123_writereg(state, 0x10, auto_reg | 0x80); - break; - case INVERSION_AUTO: - dprintk("inversion auto\n"); - cx24123_writereg(state, 0x10, auto_reg & ~0x80); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cx24123_get_inversion(struct cx24123_state *state, - fe_spectral_inversion_t *inversion) -{ - u8 val; - - val = cx24123_readreg(state, 0x1b) >> 7; - - if (val == 0) { - dprintk("read inversion off\n"); - *inversion = INVERSION_OFF; - } else { - dprintk("read inversion on\n"); - *inversion = INVERSION_ON; - } - - return 0; -} - -static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec) -{ - u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07; - - if ((fec < FEC_NONE) || (fec > FEC_AUTO)) - fec = FEC_AUTO; - - /* Set the soft decision threshold */ - if (fec == FEC_1_2) - cx24123_writereg(state, 0x43, - cx24123_readreg(state, 0x43) | 0x01); - else - cx24123_writereg(state, 0x43, - cx24123_readreg(state, 0x43) & ~0x01); - - switch (fec) { - case FEC_1_2: - dprintk("set FEC to 1/2\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x01); - cx24123_writereg(state, 0x0f, 0x02); - break; - case FEC_2_3: - dprintk("set FEC to 2/3\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x02); - cx24123_writereg(state, 0x0f, 0x04); - break; - case FEC_3_4: - dprintk("set FEC to 3/4\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x03); - cx24123_writereg(state, 0x0f, 0x08); - break; - case FEC_4_5: - dprintk("set FEC to 4/5\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x04); - cx24123_writereg(state, 0x0f, 0x10); - break; - case FEC_5_6: - dprintk("set FEC to 5/6\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x05); - cx24123_writereg(state, 0x0f, 0x20); - break; - case FEC_6_7: - dprintk("set FEC to 6/7\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x06); - cx24123_writereg(state, 0x0f, 0x40); - break; - case FEC_7_8: - dprintk("set FEC to 7/8\n"); - cx24123_writereg(state, 0x0e, nom_reg | 0x07); - cx24123_writereg(state, 0x0f, 0x80); - break; - case FEC_AUTO: - dprintk("set FEC to auto\n"); - cx24123_writereg(state, 0x0f, 0xfe); - break; - default: - return -EOPNOTSUPP; - } - - return 0; -} - -static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec) -{ - int ret; - - ret = cx24123_readreg(state, 0x1b); - if (ret < 0) - return ret; - ret = ret & 0x07; - - switch (ret) { - case 1: - *fec = FEC_1_2; - break; - case 2: - *fec = FEC_2_3; - break; - case 3: - *fec = FEC_3_4; - break; - case 4: - *fec = FEC_4_5; - break; - case 5: - *fec = FEC_5_6; - break; - case 6: - *fec = FEC_6_7; - break; - case 7: - *fec = FEC_7_8; - break; - default: - /* this can happen when there's no lock */ - *fec = FEC_NONE; - } - - return 0; -} - -/* Approximation of closest integer of log2(a/b). It actually gives the - lowest integer i such that 2^i >= round(a/b) */ -static u32 cx24123_int_log2(u32 a, u32 b) -{ - u32 exp, nearest = 0; - u32 div = a / b; - if (a % b >= b / 2) - ++div; - if (div < (1 << 31)) { - for (exp = 1; div > exp; nearest++) - exp += exp; - } - return nearest; -} - -static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate) -{ - u32 tmp, sample_rate, ratio, sample_gain; - u8 pll_mult; - - /* check if symbol rate is within limits */ - if ((srate > state->frontend.ops.info.symbol_rate_max) || - (srate < state->frontend.ops.info.symbol_rate_min)) - return -EOPNOTSUPP;; - - /* choose the sampling rate high enough for the required operation, - while optimizing the power consumed by the demodulator */ - if (srate < (XTAL*2)/2) - pll_mult = 2; - else if (srate < (XTAL*3)/2) - pll_mult = 3; - else if (srate < (XTAL*4)/2) - pll_mult = 4; - else if (srate < (XTAL*5)/2) - pll_mult = 5; - else if (srate < (XTAL*6)/2) - pll_mult = 6; - else if (srate < (XTAL*7)/2) - pll_mult = 7; - else if (srate < (XTAL*8)/2) - pll_mult = 8; - else - pll_mult = 9; - - - sample_rate = pll_mult * XTAL; - - /* - SYSSymbolRate[21:0] = (srate << 23) / sample_rate - - We have to use 32 bit unsigned arithmetic without precision loss. - The maximum srate is 45000000 or 0x02AEA540. This number has - only 6 clear bits on top, hence we can shift it left only 6 bits - at a time. Borrowed from cx24110.c - */ - - tmp = srate << 6; - ratio = tmp / sample_rate; - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 6; - ratio = (ratio << 6) + (tmp / sample_rate); - - tmp = (tmp % sample_rate) << 5; - ratio = (ratio << 5) + (tmp / sample_rate); - - - cx24123_writereg(state, 0x01, pll_mult * 6); - - cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f); - cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff); - cx24123_writereg(state, 0x0a, ratio & 0xff); - - /* also set the demodulator sample gain */ - sample_gain = cx24123_int_log2(sample_rate, srate); - tmp = cx24123_readreg(state, 0x0c) & ~0xe0; - cx24123_writereg(state, 0x0c, tmp | sample_gain << 5); - - dprintk("srate=%d, ratio=0x%08x, sample_rate=%i sample_gain=%d\n", - srate, ratio, sample_rate, sample_gain); - - return 0; -} - -/* - * Based on the required frequency and symbolrate, the tuner AGC has - * to be configured and the correct band selected. - * Calculate those values. - */ -static int cx24123_pll_calculate(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - u32 ndiv = 0, adiv = 0, vco_div = 0; - int i = 0; - int pump = 2; - int band = 0; - int num_bands = ARRAY_SIZE(cx24123_bandselect_vals); - struct cx24123_bandselect_val *bsv = NULL; - struct cx24123_AGC_val *agcv = NULL; - - /* Defaults for low freq, low rate */ - state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; - state->VGAarg = cx24123_AGC_vals[0].VGAprogdata; - state->bandselectarg = cx24123_bandselect_vals[0].progdata; - vco_div = cx24123_bandselect_vals[0].VCOdivider; - - /* For the given symbol rate, determine the VCA, VGA and - * FILTUNE programming bits */ - for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) { - agcv = &cx24123_AGC_vals[i]; - if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) && - (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) { - state->VCAarg = agcv->VCAprogdata; - state->VGAarg = agcv->VGAprogdata; - state->FILTune = agcv->FILTune; - } - } - - /* determine the band to use */ - if (force_band < 1 || force_band > num_bands) { - for (i = 0; i < num_bands; i++) { - bsv = &cx24123_bandselect_vals[i]; - if ((bsv->freq_low <= p->frequency) && - (bsv->freq_high >= p->frequency)) - band = i; - } - } else - band = force_band - 1; - - state->bandselectarg = cx24123_bandselect_vals[band].progdata; - vco_div = cx24123_bandselect_vals[band].VCOdivider; - - /* determine the charge pump current */ - if (p->frequency < (cx24123_bandselect_vals[band].freq_low + - cx24123_bandselect_vals[band].freq_high) / 2) - pump = 0x01; - else - pump = 0x02; - - /* Determine the N/A dividers for the requested lband freq (in kHz). */ - /* Note: the reference divider R=10, frequency is in KHz, - * XTAL is in Hz */ - ndiv = (((p->frequency * vco_div * 10) / - (2 * XTAL / 1000)) / 32) & 0x1ff; - adiv = (((p->frequency * vco_div * 10) / - (2 * XTAL / 1000)) % 32) & 0x1f; - - if (adiv == 0 && ndiv > 0) - ndiv--; - - /* control bits 11, refdiv 11, charge pump polarity 1, - * charge pump current, ndiv, adiv */ - state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | - (pump << 14) | (ndiv << 5) | adiv; - - return 0; -} - -/* - * Tuner data is 21 bits long, must be left-aligned in data. - * Tuner cx24109 is written through a dedicated 3wire interface - * on the demod chip. - */ -static int cx24123_pll_writereg(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p, u32 data) -{ - struct cx24123_state *state = fe->demodulator_priv; - unsigned long timeout; - - dprintk("pll writereg called, data=0x%08x\n", data); - - /* align the 21 bytes into to bit23 boundary */ - data = data << 3; - - /* Reset the demod pll word length to 0x15 bits */ - cx24123_writereg(state, 0x21, 0x15); - - /* write the msb 8 bits, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data >> 16) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { - if (time_after(jiffies, timeout)) { - err("%s: demodulator is not responding, "\ - "possibly hung, aborting.\n", __func__); - return -EREMOTEIO; - } - msleep(10); - } - - /* send another 8 bytes, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data >> 8) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { - if (time_after(jiffies, timeout)) { - err("%s: demodulator is not responding, "\ - "possibly hung, aborting.\n", __func__); - return -EREMOTEIO; - } - msleep(10); - } - - /* send the lower 5 bits of this byte, padded with 3 LBB, - * wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x80)) { - if (time_after(jiffies, timeout)) { - err("%s: demodulator is not responding," \ - "possibly hung, aborting.\n", __func__); - return -EREMOTEIO; - } - msleep(10); - } - - /* Trigger the demod to configure the tuner */ - cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2); - cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd); - - return 0; -} - -static int cx24123_pll_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - dprintk("frequency=%i\n", p->frequency); - - if (cx24123_pll_calculate(fe, p) != 0) { - err("%s: cx24123_pll_calcutate failed\n", __func__); - return -EINVAL; - } - - /* Write the new VCO/VGA */ - cx24123_pll_writereg(fe, p, state->VCAarg); - cx24123_pll_writereg(fe, p, state->VGAarg); - - /* Write the new bandselect and pll args */ - cx24123_pll_writereg(fe, p, state->bandselectarg); - cx24123_pll_writereg(fe, p, state->pllarg); - - /* set the FILTUNE voltage */ - val = cx24123_readreg(state, 0x28) & ~0x3; - cx24123_writereg(state, 0x27, state->FILTune >> 2); - cx24123_writereg(state, 0x28, val | (state->FILTune & 0x3)); - - dprintk("pll tune VCA=%d, band=%d, pll=%d\n", state->VCAarg, - state->bandselectarg, state->pllarg); - - return 0; -} - - -/* - * 0x23: - * [7:7] = BTI enabled - * [6:6] = I2C repeater enabled - * [5:5] = I2C repeater start - * [0:0] = BTI start - */ - -/* mode == 1 -> i2c-repeater, 0 -> bti */ -static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start) -{ - u8 r = cx24123_readreg(state, 0x23) & 0x1e; - if (mode) - r |= (1 << 6) | (start << 5); - else - r |= (1 << 7) | (start); - return cx24123_writereg(state, 0x23, r); -} - -static int cx24123_initfe(struct dvb_frontend *fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - int i; - - dprintk("init frontend\n"); - - /* Configure the demod to a good set of defaults */ - for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++) - cx24123_writereg(state, cx24123_regdata[i].reg, - cx24123_regdata[i].data); - - /* Set the LNB polarity */ - if (state->config->lnb_polarity) - cx24123_writereg(state, 0x32, - cx24123_readreg(state, 0x32) | 0x02); - - if (state->config->dont_use_pll) - cx24123_repeater_mode(state, 1, 0); - - return 0; -} - -static int cx24123_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - val = cx24123_readreg(state, 0x29) & ~0x40; - - switch (voltage) { - case SEC_VOLTAGE_13: - dprintk("setting voltage 13V\n"); - return cx24123_writereg(state, 0x29, val & 0x7f); - case SEC_VOLTAGE_18: - dprintk("setting voltage 18V\n"); - return cx24123_writereg(state, 0x29, val | 0x80); - case SEC_VOLTAGE_OFF: - /* already handled in cx88-dvb */ - return 0; - default: - return -EINVAL; - }; - - return 0; -} - -/* wait for diseqc queue to become ready (or timeout) */ -static void cx24123_wait_for_diseqc(struct cx24123_state *state) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(200); - while (!(cx24123_readreg(state, 0x29) & 0x40)) { - if (time_after(jiffies, timeout)) { - err("%s: diseqc queue not ready, " \ - "command may be lost.\n", __func__); - break; - } - msleep(10); - } -} - -static int cx24123_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *cmd) -{ - struct cx24123_state *state = fe->demodulator_priv; - int i, val, tone; - - dprintk("\n"); - - /* stop continuous tone if enabled */ - tone = cx24123_readreg(state, 0x29); - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x50); - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); - - for (i = 0; i < cmd->msg_len; i++) - cx24123_writereg(state, 0x2C + i, cmd->msg[i]); - - val = cx24123_readreg(state, 0x29); - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | - ((cmd->msg_len-3) & 3)); - - /* wait for diseqc message to finish sending */ - cx24123_wait_for_diseqc(state); - - /* restart continuous tone if enabled */ - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x40); - - return 0; -} - -static int cx24123_diseqc_send_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct cx24123_state *state = fe->demodulator_priv; - int val, tone; - - dprintk("\n"); - - /* stop continuous tone if enabled */ - tone = cx24123_readreg(state, 0x29); - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x50); - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - /* select tone mode */ - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4); - msleep(30); - val = cx24123_readreg(state, 0x29); - if (burst == SEC_MINI_A) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00)); - else if (burst == SEC_MINI_B) - cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x08)); - else - return -EINVAL; - - cx24123_wait_for_diseqc(state); - cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb); - - /* restart continuous tone if enabled */ - if (tone & 0x10) - cx24123_writereg(state, 0x29, tone & ~0x40); - - return 0; -} - -static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct cx24123_state *state = fe->demodulator_priv; - int sync = cx24123_readreg(state, 0x14); - - *status = 0; - if (state->config->dont_use_pll) { - u32 tun_status = 0; - if (fe->ops.tuner_ops.get_status) - fe->ops.tuner_ops.get_status(fe, &tun_status); - if (tun_status & TUNER_STATUS_LOCKED) - *status |= FE_HAS_SIGNAL; - } else { - int lock = cx24123_readreg(state, 0x20); - if (lock & 0x01) - *status |= FE_HAS_SIGNAL; - } - - if (sync & 0x02) - *status |= FE_HAS_CARRIER; /* Phase locked */ - if (sync & 0x04) - *status |= FE_HAS_VITERBI; - - /* Reed-Solomon Status */ - if (sync & 0x08) - *status |= FE_HAS_SYNC; - if (sync & 0x80) - *status |= FE_HAS_LOCK; /*Full Sync */ - - return 0; -} - -/* - * Configured to return the measurement of errors in blocks, - * because no UCBLOCKS value is available, so this value doubles up - * to satisfy both measurements. - */ -static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct cx24123_state *state = fe->demodulator_priv; - - /* The true bit error rate is this value divided by - the window size (set as 256 * 255) */ - *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | - (cx24123_readreg(state, 0x1d) << 8 | - cx24123_readreg(state, 0x1e)); - - dprintk("BER = %d\n", *ber); - - return 0; -} - -static int cx24123_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct cx24123_state *state = fe->demodulator_priv; - - /* larger = better */ - *signal_strength = cx24123_readreg(state, 0x3b) << 8; - - dprintk("Signal strength = %d\n", *signal_strength); - - return 0; -} - -static int cx24123_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct cx24123_state *state = fe->demodulator_priv; - - /* Inverted raw Es/N0 count, totally bogus but better than the - BER threshold. */ - *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) | - (u16)cx24123_readreg(state, 0x19)); - - dprintk("read S/N index = %d\n", *snr); - - return 0; -} - -static int cx24123_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - dprintk("\n"); - - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - state->currentfreq = p->frequency; - state->currentsymbolrate = p->u.qpsk.symbol_rate; - - cx24123_set_inversion(state, p->inversion); - cx24123_set_fec(state, p->u.qpsk.fec_inner); - cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); - - if (!state->config->dont_use_pll) - cx24123_pll_tune(fe, p); - else if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, p); - else - err("it seems I don't have a tuner..."); - - /* Enable automatic aquisition and reset cycle */ - cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); - cx24123_writereg(state, 0x00, 0x10); - cx24123_writereg(state, 0x00, 0); - - if (state->config->agc_callback) - state->config->agc_callback(fe); - - return 0; -} - -static int cx24123_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - dprintk("\n"); - - if (cx24123_get_inversion(state, &p->inversion) != 0) { - err("%s: Failed to get inversion status\n", __func__); - return -EREMOTEIO; - } - if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { - err("%s: Failed to get fec status\n", __func__); - return -EREMOTEIO; - } - p->frequency = state->currentfreq; - p->u.qpsk.symbol_rate = state->currentsymbolrate; - - return 0; -} - -static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - /* wait for diseqc queue ready */ - cx24123_wait_for_diseqc(state); - - val = cx24123_readreg(state, 0x29) & ~0x40; - - switch (tone) { - case SEC_TONE_ON: - dprintk("setting tone on\n"); - return cx24123_writereg(state, 0x29, val | 0x10); - case SEC_TONE_OFF: - dprintk("setting tone off\n"); - return cx24123_writereg(state, 0x29, val & 0xef); - default: - err("CASE reached default with tone=%d\n", tone); - return -EINVAL; - } - - return 0; -} - -static int cx24123_tune(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, - unsigned int mode_flags, - unsigned int *delay, - fe_status_t *status) -{ - int retval = 0; - - if (params != NULL) - retval = cx24123_set_frontend(fe, params); - - if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) - cx24123_read_status(fe, status); - *delay = HZ/10; - - return retval; -} - -static int cx24123_get_algo(struct dvb_frontend *fe) -{ - return 1; /* FE_ALGO_HW */ -} - -static void cx24123_release(struct dvb_frontend *fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - dprintk("\n"); - i2c_del_adapter(&state->tuner_i2c_adapter); - kfree(state); -} - -static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msg[], int num) -{ - struct cx24123_state *state = i2c_get_adapdata(i2c_adap); - /* this repeater closes after the first stop */ - cx24123_repeater_mode(state, 1, 1); - return i2c_transfer(state->i2c, msg, num); -} - -static u32 cx24123_tuner_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static struct i2c_algorithm cx24123_tuner_i2c_algo = { - .master_xfer = cx24123_tuner_i2c_tuner_xfer, - .functionality = cx24123_tuner_i2c_func, -}; - -struct i2c_adapter * - cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - return &state->tuner_i2c_adapter; -} -EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter); - -static struct dvb_frontend_ops cx24123_ops; - -struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, - struct i2c_adapter *i2c) -{ - struct cx24123_state *state = - kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); - - dprintk("\n"); - /* allocate memory for the internal state */ - if (state == NULL) { - err("Unable to kmalloc\n"); - goto error; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - state->demod_rev = cx24123_readreg(state, 0x00); - switch (state->demod_rev) { - case 0xe1: - info("detected CX24123C\n"); - break; - case 0xd1: - info("detected CX24123\n"); - break; - default: - err("wrong demod revision: %x\n", state->demod_rev); - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &cx24123_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* create tuner i2c adapter */ - if (config->dont_use_pll) - cx24123_repeater_mode(state, 1, 0); - - strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus", - sizeof(state->tuner_i2c_adapter.name)); - state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, - state->tuner_i2c_adapter.algo = &cx24123_tuner_i2c_algo; - state->tuner_i2c_adapter.algo_data = NULL; - i2c_set_adapdata(&state->tuner_i2c_adapter, state); - if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { - err("tuner i2c bus could not be initialized\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(cx24123_attach); - -static struct dvb_frontend_ops cx24123_ops = { - - .info = { - .name = "Conexant CX24123/CX24109", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 5000, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24123_release, - - .init = cx24123_initfe, - .set_frontend = cx24123_set_frontend, - .get_frontend = cx24123_get_frontend, - .read_status = cx24123_read_status, - .read_ber = cx24123_read_ber, - .read_signal_strength = cx24123_read_signal_strength, - .read_snr = cx24123_read_snr, - .diseqc_send_master_cmd = cx24123_send_diseqc_msg, - .diseqc_send_burst = cx24123_diseqc_send_burst, - .set_tone = cx24123_set_tone, - .set_voltage = cx24123_set_voltage, - .tune = cx24123_tune, - .get_frontend_algo = cx24123_get_algo, -}; - -MODULE_DESCRIPTION("DVB Frontend module for Conexant " \ - "CX24123/CX24109/CX24113 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h deleted file mode 100644 index 51ae866e9fe..00000000000 --- a/drivers/media/dvb/frontends/cx24123.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef CX24123_H -#define CX24123_H - -#include <linux/dvb/frontend.h> - -struct cx24123_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); - - /* 0 = LNB voltage normal, 1 = LNB voltage inverted */ - int lnb_polarity; - - /* this device has another tuner */ - u8 dont_use_pll; - void (*agc_callback) (struct dvb_frontend *); -}; - -#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, - struct i2c_adapter *i2c); -extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *); -#else -static inline struct dvb_frontend *cx24123_attach( - const struct cx24123_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -static struct i2c_adapter * - cx24123_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif /* CX24123_H */ diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c deleted file mode 100644 index fe895bf7b18..00000000000 --- a/drivers/media/dvb/frontends/dib0070.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib0070.h" -#include "dibx000_common.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0) - -#define DIB0070_P1D 0x00 -#define DIB0070_P1F 0x01 -#define DIB0070_P1G 0x03 -#define DIB0070S_P1A 0x02 - -struct dib0070_state { - struct i2c_adapter *i2c; - struct dvb_frontend *fe; - const struct dib0070_config *cfg; - u16 wbd_ff_offset; - u8 revision; -}; - -static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) -{ - u8 b[2]; - struct i2c_msg msg[2] = { - { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, - }; - if (i2c_transfer(state->i2c, msg, 2) != 2) { - printk(KERN_WARNING "DiB0070 I2C read failed\n"); - return 0; - } - return (b[0] << 8) | b[1]; -} - -static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) -{ - u8 b[3] = { reg, val >> 8, val & 0xff }; - struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - printk(KERN_WARNING "DiB0070 I2C write failed\n"); - return -EREMOTEIO; - } - return 0; -} - -#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0) - -static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) -{ - struct dib0070_state *st = fe->tuner_priv; - u16 tmp = 0; - tmp = dib0070_read_reg(st, 0x02) & 0x3fff; - - switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) { - case 8000: - tmp |= (0 << 14); - break; - case 7000: - tmp |= (1 << 14); - break; - case 6000: - tmp |= (2 << 14); - break; - case 5000: - default: - tmp |= (3 << 14); - break; - } - dib0070_write_reg(st, 0x02, tmp); - return 0; -} - -static void dib0070_captrim(struct dib0070_state *st, u16 LO4) -{ - int8_t captrim, fcaptrim, step_sign, step; - u16 adc, adc_diff = 3000; - - - - dib0070_write_reg(st, 0x0f, 0xed10); - dib0070_write_reg(st, 0x17, 0x0034); - - dib0070_write_reg(st, 0x18, 0x0032); - msleep(2); - - step = captrim = fcaptrim = 64; - - do { - step /= 2; - dib0070_write_reg(st, 0x14, LO4 | captrim); - msleep(1); - adc = dib0070_read_reg(st, 0x19); - - dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024); - - if (adc >= 400) { - adc -= 400; - step_sign = -1; - } else { - adc = 400 - adc; - step_sign = 1; - } - - if (adc < adc_diff) { - dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff); - adc_diff = adc; - fcaptrim = captrim; - - - - } - captrim += (step_sign * step); - } while (step >= 1); - - dib0070_write_reg(st, 0x14, LO4 | fcaptrim); - dib0070_write_reg(st, 0x18, 0x07ff); -} - -#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 -#define LO4_SET_VCO_HFDIV(l, v, h) l |= ((v) << 11) | ((h) << 7) -#define LO4_SET_SD(l, s) l |= ((s) << 14) | ((s) << 12) -#define LO4_SET_CTRIM(l, c) l |= (c) << 10 -static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) -{ - struct dib0070_state *st = fe->tuner_priv; - u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf); - - u8 band = BAND_OF_FREQUENCY(freq), c; - - /*******************VCO***********************************/ - u16 lo4 = 0; - - u8 REFDIV, PRESC = 2; - u32 FBDiv, Rest, FREF, VCOF_kHz; - u16 Num, Den; - /*******************FrontEnd******************************/ - u16 value = 0; - - dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); - - - dib0070_write_reg(st, 0x17, 0x30); - - dib0070_set_bandwidth(fe, ch); /* c is used as HF */ - switch (st->revision) { - case DIB0070S_P1A: - switch (band) { - case BAND_LBAND: - LO4_SET_VCO_HFDIV(lo4, 1, 1); - c = 2; - break; - case BAND_SBAND: - LO4_SET_VCO_HFDIV(lo4, 0, 0); - LO4_SET_CTRIM(lo4, 1);; - c = 1; - break; - case BAND_UHF: - default: - if (freq < 570000) { - LO4_SET_VCO_HFDIV(lo4, 1, 3); - PRESC = 6; c = 6; - } else if (freq < 680000) { - LO4_SET_VCO_HFDIV(lo4, 0, 2); - c = 4; - } else { - LO4_SET_VCO_HFDIV(lo4, 1, 2); - c = 4; - } - break; - } break; - - case DIB0070_P1G: - case DIB0070_P1F: - default: - switch (band) { - case BAND_FM: - LO4_SET_VCO_HFDIV(lo4, 0, 7); - c = 24; - break; - case BAND_LBAND: - LO4_SET_VCO_HFDIV(lo4, 1, 0); - c = 2; - break; - case BAND_VHF: - if (freq < 180000) { - LO4_SET_VCO_HFDIV(lo4, 0, 3); - c = 16; - } else if (freq < 190000) { - LO4_SET_VCO_HFDIV(lo4, 1, 3); - c = 16; - } else { - LO4_SET_VCO_HFDIV(lo4, 0, 6); - c = 12; - } - break; - - case BAND_UHF: - default: - if (freq < 570000) { - LO4_SET_VCO_HFDIV(lo4, 1, 5); - c = 6; - } else if (freq < 700000) { - LO4_SET_VCO_HFDIV(lo4, 0, 1); - c = 4; - } else { - LO4_SET_VCO_HFDIV(lo4, 1, 1); - c = 4; - } - break; - } - break; - } - - dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf); - dprintk( "VCO = %hd", (lo4 >> 11) & 0x3); - - - VCOF_kHz = (c * freq) * 2; - dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq); - - switch (band) { - case BAND_VHF: - REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000); - break; - case BAND_FM: - REFDIV = (u8) ((st->cfg->clock_khz) / 1000); - break; - default: - REFDIV = (u8) ( st->cfg->clock_khz / 10000); - break; - } - FREF = st->cfg->clock_khz / REFDIV; - - dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); - - - - switch (st->revision) { - case DIB0070S_P1A: - FBDiv = (VCOF_kHz / PRESC / FREF); - Rest = (VCOF_kHz / PRESC) - FBDiv * FREF; - break; - - case DIB0070_P1G: - case DIB0070_P1F: - default: - FBDiv = (freq / (FREF / 2)); - Rest = 2 * freq - FBDiv * FREF; - break; - } - - - if (Rest < LPF) Rest = 0; - else if (Rest < 2 * LPF) Rest = 2 * LPF; - else if (Rest > (FREF - LPF)) { Rest = 0 ; FBDiv += 1; } - else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF; - Rest = (Rest * 6528) / (FREF / 10); - dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest); - - Num = 0; - Den = 1; - - if (Rest > 0) { - LO4_SET_SD(lo4, 1); - Den = 255; - Num = (u16)Rest; - } - dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1); - - - - dib0070_write_reg(st, 0x11, (u16)FBDiv); - - - dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV); - - - dib0070_write_reg(st, 0x13, Num); - - - value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001; - - switch (band) { - case BAND_UHF: value |= 0x4000 | 0x0800; break; - case BAND_LBAND: value |= 0x2000 | 0x0400; break; - default: value |= 0x8000 | 0x1000; break; - } - dib0070_write_reg(st, 0x20, value); - - dib0070_captrim(st, lo4); - if (st->revision == DIB0070S_P1A) { - if (band == BAND_SBAND) - dib0070_write_reg(st, 0x15, 0x16e2); - else - dib0070_write_reg(st, 0x15, 0x56e5); - } - - - - switch (band) { - case BAND_UHF: value = 0x7c82; break; - case BAND_LBAND: value = 0x7c84; break; - default: value = 0x7c81; break; - } - dib0070_write_reg(st, 0x0f, value); - dib0070_write_reg(st, 0x06, 0x3fff); - - /* Front End */ - /* c == TUNE, value = SWITCH */ - c = 0; - value = 0; - switch (band) { - case BAND_FM: - c = 0; value = 1; - break; - - case BAND_VHF: - if (freq <= 180000) c = 0; - else if (freq <= 188200) c = 1; - else if (freq <= 196400) c = 2; - else c = 3; - value = 1; - break; - - case BAND_LBAND: - if (freq <= 1500000) c = 0; - else if (freq <= 1600000) c = 1; - else c = 3; - break; - - case BAND_SBAND: - c = 7; - dib0070_write_reg(st, 0x1d,0xFFFF); - break; - - case BAND_UHF: - default: - if (st->cfg->flip_chip) { - if (freq <= 550000) c = 0; - else if (freq <= 590000) c = 1; - else if (freq <= 666000) c = 3; - else c = 5; - } else { - if (freq <= 550000) c = 2; - else if (freq <= 650000) c = 3; - else if (freq <= 750000) c = 5; - else if (freq <= 850000) c = 6; - else c = 7; - } - value = 2; - break; - } - - /* default: LNA_MATCH=7, BIAS=3 */ - dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0)); - dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127)); - dib0070_write_reg(st, 0x0d, 0x0d80); - - - dib0070_write_reg(st, 0x18, 0x07ff); - dib0070_write_reg(st, 0x17, 0x0033); - - return 0; -} - -static int dib0070_wakeup(struct dvb_frontend *fe) -{ - struct dib0070_state *st = fe->tuner_priv; - if (st->cfg->sleep) - st->cfg->sleep(fe, 0); - return 0; -} - -static int dib0070_sleep(struct dvb_frontend *fe) -{ - struct dib0070_state *st = fe->tuner_priv; - if (st->cfg->sleep) - st->cfg->sleep(fe, 1); - return 0; -} - -static u16 dib0070_p1f_defaults[] = - -{ - 7, 0x02, - 0x0008, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0002, - 0x0100, - - 3, 0x0d, - 0x0d80, - 0x0001, - 0x0000, - - 4, 0x11, - 0x0000, - 0x0103, - 0x0000, - 0x0000, - - 3, 0x16, - 0x0004 | 0x0040, - 0x0030, - 0x07ff, - - 6, 0x1b, - 0x4112, - 0xff00, - 0xc07f, - 0x0000, - 0x0180, - 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, - - 0, -}; - -static void dib0070_wbd_calibration(struct dvb_frontend *fe) -{ - u16 wbd_offs; - struct dib0070_state *state = fe->tuner_priv; - - if (state->cfg->sleep) - state->cfg->sleep(fe, 0); - - dib0070_write_reg(state, 0x0f, 0x6d81); - dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); - msleep(9); - wbd_offs = dib0070_read_reg(state, 0x19); - dib0070_write_reg(state, 0x20, 0); - state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2); - dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset); - - if (state->cfg->sleep) - state->cfg->sleep(fe, 1); - -} - -u16 dib0070_wbd_offset(struct dvb_frontend *fe) -{ - struct dib0070_state *st = fe->tuner_priv; - return st->wbd_ff_offset; -} - -EXPORT_SYMBOL(dib0070_wbd_offset); -static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt) -{ - struct dib0070_state *state = fe->tuner_priv; - u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); - dprintk( "CTRL_LO5: 0x%x", lo5); - return dib0070_write_reg(state, 0x15, lo5); -} - -#define pgm_read_word(w) (*w) -static int dib0070_reset(struct dib0070_state *state) -{ - u16 l, r, *n; - - HARD_RESET(state); - - -#ifndef FORCE_SBAND_TUNER - if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) - state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; - else -#endif - state->revision = DIB0070S_P1A; - - /* P1F or not */ - dprintk( "Revision: %x", state->revision); - - if (state->revision == DIB0070_P1D) { - dprintk( "Error: this driver is not to be used meant for P1D or earlier"); - return -EINVAL; - } - - n = (u16 *) dib0070_p1f_defaults; - l = pgm_read_word(n++); - while (l) { - r = pgm_read_word(n++); - do { - dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); - r++; - } while (--l); - l = pgm_read_word(n++); - } - - if (state->cfg->force_crystal_mode != 0) - r = state->cfg->force_crystal_mode; - else if (state->cfg->clock_khz >= 24000) - r = 1; - else - r = 2; - - r |= state->cfg->osc_buffer_state << 3; - - dib0070_write_reg(state, 0x10, r); - dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4)); - - if (state->cfg->invert_iq) { - r = dib0070_read_reg(state, 0x02) & 0xffdf; - dib0070_write_reg(state, 0x02, r | (1 << 5)); - } - - - if (state->revision == DIB0070S_P1A) - dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1); - else - dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0); - - dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); - return 0; -} - - -static int dib0070_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static struct dvb_tuner_ops dib0070_ops = { - .info = { - .name = "DiBcom DiB0070", - .frequency_min = 45000000, - .frequency_max = 860000000, - .frequency_step = 1000, - }, - .release = dib0070_release, - - .init = dib0070_wakeup, - .sleep = dib0070_sleep, - .set_params = dib0070_tune_digital, -// .get_frequency = dib0070_get_frequency, -// .get_bandwidth = dib0070_get_bandwidth -}; - -struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) -{ - struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - state->cfg = cfg; - state->i2c = i2c; - state->fe = fe; - fe->tuner_priv = state; - - if (dib0070_reset(state) != 0) - goto free_mem; - - dib0070_wbd_calibration(fe); - - printk(KERN_INFO "DiB0070: successfully identified\n"); - memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = state; - return fe; - -free_mem: - kfree(state); - fe->tuner_priv = NULL; - return NULL; -} -EXPORT_SYMBOL(dib0070_attach); - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h deleted file mode 100644 index 21f2c5161af..00000000000 --- a/drivers/media/dvb/frontends/dib0070.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#ifndef DIB0070_H -#define DIB0070_H - -struct dvb_frontend; -struct i2c_adapter; - -#define DEFAULT_DIB0070_I2C_ADDRESS 0x60 - -struct dib0070_config { - u8 i2c_address; - - /* tuner pins controlled externally */ - int (*reset) (struct dvb_frontend *, int); - int (*sleep) (struct dvb_frontend *, int); - - /* offset in kHz */ - int freq_offset_khz_uhf; - int freq_offset_khz_vhf; - - u8 osc_buffer_state; /* 0= normal, 1= tri-state */ - u32 clock_khz; - u8 clock_pad_drive; /* (Drive + 1) * 2mA */ - - u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */ - - u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */ - - u8 flip_chip; -}; - -#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dib0070_config *cfg); -extern u16 dib0070_wbd_offset(struct dvb_frontend *); -#else -static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dib0070_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} -#endif - -extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); - -#endif diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h deleted file mode 100644 index ba917359fa6..00000000000 --- a/drivers/media/dvb/frontends/dib3000.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * public header file of the frontend drivers for mobile DVB-T demodulators - * DiBcom 3000M-B and DiBcom 3000P/M-C (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DibCom, which has - * - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * Acknowledgements - * - * 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 - * - */ - -#ifndef DIB3000_H -#define DIB3000_H - -#include <linux/dvb/frontend.h> - -struct dib3000_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -struct dib_fe_xfer_ops -{ - /* pid and transfer handling is done in the demodulator */ - int (*pid_parse)(struct dvb_frontend *fe, int onoff); - int (*fifo_ctrl)(struct dvb_frontend *fe, int onoff); - int (*pid_ctrl)(struct dvb_frontend *fe, int index, int pid, int onoff); - int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); -}; - -#if defined(CONFIG_DVB_DIB3000MB) || (defined(CONFIG_DVB_DIB3000MB_MODULE) && defined(MODULE)) -extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); -#else -static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_DIB3000MB - -#endif // DIB3000_H diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c deleted file mode 100644 index 136b9d2164d..00000000000 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ /dev/null @@ -1,841 +0,0 @@ -/* - * Frontend driver for mobile DVB-T demodulator DiBcom 3000M-B - * DiBcom (http://www.dibcom.fr/) - * - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * based on GPL code from DibCom, which has - * - * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * Acknowledgements - * - * 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 - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" - -#include "dib3000.h" -#include "dib3000mb_priv.h" - -/* Version information */ -#define DRIVER_VERSION "0.1" -#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator" -#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); -#endif -#define deb_info(args...) dprintk(0x01,args) -#define deb_i2c(args...) dprintk(0x02,args) -#define deb_srch(args...) dprintk(0x04,args) -#define deb_info(args...) dprintk(0x01,args) -#define deb_xfer(args...) dprintk(0x02,args) -#define deb_setf(args...) dprintk(0x04,args) -#define deb_getf(args...) dprintk(0x08,args) - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able))."); -#endif - -static int dib3000_read_reg(struct dib3000_state *state, u16 reg) -{ - u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[] = { - { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c, msg, 2) != 2) - deb_i2c("i2c read error\n"); - - deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg, - (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]); - - return (rb[0] << 8) | rb[1]; -} - -static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val) -{ - u8 b[] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg[] = { - { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 } - }; - deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val); - - return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0; -} - -static int dib3000_search_status(u16 irq,u16 lock) -{ - if (irq & 0x02) { - if (lock & 0x01) { - deb_srch("auto search succeeded\n"); - return 1; // auto search succeeded - } else { - deb_srch("auto search not successful\n"); - return 0; // auto search failed - } - } else if (irq & 0x01) { - deb_srch("auto search failed\n"); - return 0; // auto search failed - } - return -1; // try again -} - -/* for auto search */ -static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */ - { /* fft */ - { /* gua */ - { 0, 1 }, /* 0 0 { 0,1 } */ - { 3, 9 }, /* 0 1 { 0,1 } */ - }, - { - { 2, 5 }, /* 1 0 { 0,1 } */ - { 6, 11 }, /* 1 1 { 0,1 } */ - } - }; - -static int dib3000mb_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep); - -static int dib3000mb_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep, int tuner) -{ - struct dib3000_state* state = fe->demodulator_priv; - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; - fe_code_rate_t fe_cr = FEC_NONE; - int search_state, seq; - - if (tuner && fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - - deb_setf("bandwidth: "); - switch (ofdm->bandwidth) { - case BANDWIDTH_8_MHZ: - deb_setf("8 MHz\n"); - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); - break; - case BANDWIDTH_7_MHZ: - deb_setf("7 MHz\n"); - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[1]); - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_7mhz); - break; - case BANDWIDTH_6_MHZ: - deb_setf("6 MHz\n"); - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[0]); - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_6mhz); - break; - case BANDWIDTH_AUTO: - return -EOPNOTSUPP; - default: - err("unkown bandwidth value."); - return -EINVAL; - } - } - wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); - - deb_setf("transmission mode: "); - switch (ofdm->transmission_mode) { - case TRANSMISSION_MODE_2K: - deb_setf("2k\n"); - wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_2K); - break; - case TRANSMISSION_MODE_8K: - deb_setf("8k\n"); - wr(DIB3000MB_REG_FFT, DIB3000_TRANSMISSION_MODE_8K); - break; - case TRANSMISSION_MODE_AUTO: - deb_setf("auto\n"); - break; - default: - return -EINVAL; - } - - deb_setf("guard: "); - switch (ofdm->guard_interval) { - case GUARD_INTERVAL_1_32: - deb_setf("1_32\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_32); - break; - case GUARD_INTERVAL_1_16: - deb_setf("1_16\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_16); - break; - case GUARD_INTERVAL_1_8: - deb_setf("1_8\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_8); - break; - case GUARD_INTERVAL_1_4: - deb_setf("1_4\n"); - wr(DIB3000MB_REG_GUARD_TIME, DIB3000_GUARD_TIME_1_4); - break; - case GUARD_INTERVAL_AUTO: - deb_setf("auto\n"); - break; - default: - return -EINVAL; - } - - deb_setf("inversion: "); - switch (fep->inversion) { - case INVERSION_OFF: - deb_setf("off\n"); - wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_OFF); - break; - case INVERSION_AUTO: - deb_setf("auto "); - break; - case INVERSION_ON: - deb_setf("on\n"); - wr(DIB3000MB_REG_DDS_INV, DIB3000_DDS_INVERSION_ON); - break; - default: - return -EINVAL; - } - - deb_setf("constellation: "); - switch (ofdm->constellation) { - case QPSK: - deb_setf("qpsk\n"); - wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_QPSK); - break; - case QAM_16: - deb_setf("qam16\n"); - wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_16QAM); - break; - case QAM_64: - deb_setf("qam64\n"); - wr(DIB3000MB_REG_QAM, DIB3000_CONSTELLATION_64QAM); - break; - case QAM_AUTO: - break; - default: - return -EINVAL; - } - deb_setf("hierarchy: "); - switch (ofdm->hierarchy_information) { - case HIERARCHY_NONE: - deb_setf("none "); - /* fall through */ - case HIERARCHY_1: - deb_setf("alpha=1\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_1); - break; - case HIERARCHY_2: - deb_setf("alpha=2\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_2); - break; - case HIERARCHY_4: - deb_setf("alpha=4\n"); - wr(DIB3000MB_REG_VIT_ALPHA, DIB3000_ALPHA_4); - break; - case HIERARCHY_AUTO: - deb_setf("alpha=auto\n"); - break; - default: - return -EINVAL; - } - - deb_setf("hierarchy: "); - if (ofdm->hierarchy_information == HIERARCHY_NONE) { - deb_setf("none\n"); - wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_OFF); - wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_HP); - fe_cr = ofdm->code_rate_HP; - } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) { - deb_setf("on\n"); - wr(DIB3000MB_REG_VIT_HRCH, DIB3000_HRCH_ON); - wr(DIB3000MB_REG_VIT_HP, DIB3000_SELECT_LP); - fe_cr = ofdm->code_rate_LP; - } - deb_setf("fec: "); - switch (fe_cr) { - case FEC_1_2: - deb_setf("1_2\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_1_2); - break; - case FEC_2_3: - deb_setf("2_3\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_2_3); - break; - case FEC_3_4: - deb_setf("3_4\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_3_4); - break; - case FEC_5_6: - deb_setf("5_6\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_5_6); - break; - case FEC_7_8: - deb_setf("7_8\n"); - wr(DIB3000MB_REG_VIT_CODE_RATE, DIB3000_FEC_7_8); - break; - case FEC_NONE: - deb_setf("none "); - break; - case FEC_AUTO: - deb_setf("auto\n"); - break; - default: - return -EINVAL; - } - - seq = dib3000_seq - [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] - [ofdm->guard_interval == GUARD_INTERVAL_AUTO] - [fep->inversion == INVERSION_AUTO]; - - deb_setf("seq? %d\n", seq); - - wr(DIB3000MB_REG_SEQ, seq); - - wr(DIB3000MB_REG_ISI, seq ? DIB3000MB_ISI_INHIBIT : DIB3000MB_ISI_ACTIVATE); - - if (ofdm->transmission_mode == TRANSMISSION_MODE_2K) { - if (ofdm->guard_interval == GUARD_INTERVAL_1_8) { - wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_2K_1_8); - } else { - wr(DIB3000MB_REG_SYNC_IMPROVEMENT, DIB3000MB_SYNC_IMPROVE_DEFAULT); - } - - wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_2K); - } else { - wr(DIB3000MB_REG_UNK_121, DIB3000MB_UNK_121_DEFAULT); - } - - wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_OFF); - wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); - wr(DIB3000MB_REG_MOBILE_MODE, DIB3000MB_MOBILE_MODE_OFF); - - wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_high); - - wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_ACTIVATE); - - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC + DIB3000MB_RESTART_CTRL); - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - - /* wait for AGC lock */ - msleep(70); - - wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); - - /* something has to be auto searched */ - if (ofdm->constellation == QAM_AUTO || - ofdm->hierarchy_information == HIERARCHY_AUTO || - fe_cr == FEC_AUTO || - fep->inversion == INVERSION_AUTO) { - int as_count=0; - - deb_setf("autosearch enabled.\n"); - - wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); - - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AUTO_SEARCH); - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - - while ((search_state = - dib3000_search_status( - rd(DIB3000MB_REG_AS_IRQ_PENDING), - rd(DIB3000MB_REG_LOCK2_VALUE))) < 0 && as_count++ < 100) - msleep(1); - - deb_setf("search_state after autosearch %d after %d checks\n",search_state,as_count); - - if (search_state == 1) { - struct dvb_frontend_parameters feps; - if (dib3000mb_get_frontend(fe, &feps) == 0) { - deb_setf("reading tuning data from frontend succeeded.\n"); - return dib3000mb_set_frontend(fe, &feps, 0); - } - } - - } else { - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_CTRL); - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_OFF); - } - - return 0; -} - -static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) -{ - struct dib3000_state* state = fe->demodulator_priv; - - deb_info("dib3000mb is getting up.\n"); - wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP); - - wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC); - - wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE); - wr(DIB3000MB_REG_RESET_DEVICE, DIB3000MB_RESET_DEVICE_RST); - - wr(DIB3000MB_REG_CLOCK, DIB3000MB_CLOCK_DEFAULT); - - wr(DIB3000MB_REG_ELECT_OUT_MODE, DIB3000MB_ELECT_OUT_MODE_ON); - - wr(DIB3000MB_REG_DDS_FREQ_MSB, DIB3000MB_DDS_FREQ_MSB); - wr(DIB3000MB_REG_DDS_FREQ_LSB, DIB3000MB_DDS_FREQ_LSB); - - wr_foreach(dib3000mb_reg_timing_freq, dib3000mb_timing_freq[2]); - - wr_foreach(dib3000mb_reg_impulse_noise, - dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF]); - - wr_foreach(dib3000mb_reg_agc_gain, dib3000mb_default_agc_gain); - - wr(DIB3000MB_REG_PHASE_NOISE, DIB3000MB_PHASE_NOISE_DEFAULT); - - wr_foreach(dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase); - - wr_foreach(dib3000mb_reg_lock_duration, dib3000mb_default_lock_duration); - - wr_foreach(dib3000mb_reg_agc_bandwidth, dib3000mb_agc_bandwidth_low); - - wr(DIB3000MB_REG_LOCK0_MASK, DIB3000MB_LOCK0_DEFAULT); - wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4); - wr(DIB3000MB_REG_LOCK2_MASK, DIB3000MB_LOCK2_DEFAULT); - wr(DIB3000MB_REG_SEQ, dib3000_seq[1][1][1]); - - wr_foreach(dib3000mb_reg_bandwidth, dib3000mb_bandwidth_8mhz); - - wr(DIB3000MB_REG_UNK_68, DIB3000MB_UNK_68); - wr(DIB3000MB_REG_UNK_69, DIB3000MB_UNK_69); - wr(DIB3000MB_REG_UNK_71, DIB3000MB_UNK_71); - wr(DIB3000MB_REG_UNK_77, DIB3000MB_UNK_77); - wr(DIB3000MB_REG_UNK_78, DIB3000MB_UNK_78); - wr(DIB3000MB_REG_ISI, DIB3000MB_ISI_INHIBIT); - wr(DIB3000MB_REG_UNK_92, DIB3000MB_UNK_92); - wr(DIB3000MB_REG_UNK_96, DIB3000MB_UNK_96); - wr(DIB3000MB_REG_UNK_97, DIB3000MB_UNK_97); - wr(DIB3000MB_REG_UNK_106, DIB3000MB_UNK_106); - wr(DIB3000MB_REG_UNK_107, DIB3000MB_UNK_107); - wr(DIB3000MB_REG_UNK_108, DIB3000MB_UNK_108); - wr(DIB3000MB_REG_UNK_122, DIB3000MB_UNK_122); - wr(DIB3000MB_REG_MOBILE_MODE_QAM, DIB3000MB_MOBILE_MODE_QAM_OFF); - wr(DIB3000MB_REG_BERLEN, DIB3000MB_BERLEN_DEFAULT); - - wr_foreach(dib3000mb_reg_filter_coeffs, dib3000mb_filter_coeffs); - - wr(DIB3000MB_REG_MOBILE_ALGO, DIB3000MB_MOBILE_ALGO_ON); - wr(DIB3000MB_REG_MULTI_DEMOD_MSB, DIB3000MB_MULTI_DEMOD_MSB); - wr(DIB3000MB_REG_MULTI_DEMOD_LSB, DIB3000MB_MULTI_DEMOD_LSB); - - wr(DIB3000MB_REG_OUTPUT_MODE, DIB3000MB_OUTPUT_MODE_SLAVE); - - wr(DIB3000MB_REG_FIFO_142, DIB3000MB_FIFO_142); - wr(DIB3000MB_REG_MPEG2_OUT_MODE, DIB3000MB_MPEG2_OUT_MODE_188); - wr(DIB3000MB_REG_PID_PARSE, DIB3000MB_PID_PARSE_ACTIVATE); - wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); - wr(DIB3000MB_REG_FIFO_146, DIB3000MB_FIFO_146); - wr(DIB3000MB_REG_FIFO_147, DIB3000MB_FIFO_147); - - wr(DIB3000MB_REG_DATA_IN_DIVERSITY, DIB3000MB_DATA_DIVERSITY_IN_OFF); - - return 0; -} - -static int dib3000mb_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib3000_state* state = fe->demodulator_priv; - struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; - fe_code_rate_t *cr; - u16 tps_val; - int inv_test1,inv_test2; - u32 dds_val, threshold = 0x800000; - - if (!rd(DIB3000MB_REG_TPS_LOCK)) - return 0; - - dds_val = ((rd(DIB3000MB_REG_DDS_VALUE_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB); - deb_getf("DDS_VAL: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_VALUE_MSB), rd(DIB3000MB_REG_DDS_VALUE_LSB)); - if (dds_val < threshold) - inv_test1 = 0; - else if (dds_val == threshold) - inv_test1 = 1; - else - inv_test1 = 2; - - dds_val = ((rd(DIB3000MB_REG_DDS_FREQ_MSB) & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB); - deb_getf("DDS_FREQ: %x %x %x",dds_val, rd(DIB3000MB_REG_DDS_FREQ_MSB), rd(DIB3000MB_REG_DDS_FREQ_LSB)); - if (dds_val < threshold) - inv_test2 = 0; - else if (dds_val == threshold) - inv_test2 = 1; - else - inv_test2 = 2; - - fep->inversion = - ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || - ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ? - INVERSION_ON : INVERSION_OFF; - - deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); - - switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) { - case DIB3000_CONSTELLATION_QPSK: - deb_getf("QPSK "); - ofdm->constellation = QPSK; - break; - case DIB3000_CONSTELLATION_16QAM: - deb_getf("QAM16 "); - ofdm->constellation = QAM_16; - break; - case DIB3000_CONSTELLATION_64QAM: - deb_getf("QAM64 "); - ofdm->constellation = QAM_64; - break; - default: - err("Unexpected constellation returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - if (rd(DIB3000MB_REG_TPS_HRCH)) { - deb_getf("HRCH ON\n"); - cr = &ofdm->code_rate_LP; - ofdm->code_rate_HP = FEC_NONE; - switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) { - case DIB3000_ALPHA_0: - deb_getf("HIERARCHY_NONE "); - ofdm->hierarchy_information = HIERARCHY_NONE; - break; - case DIB3000_ALPHA_1: - deb_getf("HIERARCHY_1 "); - ofdm->hierarchy_information = HIERARCHY_1; - break; - case DIB3000_ALPHA_2: - deb_getf("HIERARCHY_2 "); - ofdm->hierarchy_information = HIERARCHY_2; - break; - case DIB3000_ALPHA_4: - deb_getf("HIERARCHY_4 "); - ofdm->hierarchy_information = HIERARCHY_4; - break; - default: - err("Unexpected ALPHA value returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP); - } else { - deb_getf("HRCH OFF\n"); - cr = &ofdm->code_rate_HP; - ofdm->code_rate_LP = FEC_NONE; - ofdm->hierarchy_information = HIERARCHY_NONE; - - tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP); - } - - switch (tps_val) { - case DIB3000_FEC_1_2: - deb_getf("FEC_1_2 "); - *cr = FEC_1_2; - break; - case DIB3000_FEC_2_3: - deb_getf("FEC_2_3 "); - *cr = FEC_2_3; - break; - case DIB3000_FEC_3_4: - deb_getf("FEC_3_4 "); - *cr = FEC_3_4; - break; - case DIB3000_FEC_5_6: - deb_getf("FEC_5_6 "); - *cr = FEC_4_5; - break; - case DIB3000_FEC_7_8: - deb_getf("FEC_7_8 "); - *cr = FEC_7_8; - break; - default: - err("Unexpected FEC returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n",tps_val); - - switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) { - case DIB3000_GUARD_TIME_1_32: - deb_getf("GUARD_INTERVAL_1_32 "); - ofdm->guard_interval = GUARD_INTERVAL_1_32; - break; - case DIB3000_GUARD_TIME_1_16: - deb_getf("GUARD_INTERVAL_1_16 "); - ofdm->guard_interval = GUARD_INTERVAL_1_16; - break; - case DIB3000_GUARD_TIME_1_8: - deb_getf("GUARD_INTERVAL_1_8 "); - ofdm->guard_interval = GUARD_INTERVAL_1_8; - break; - case DIB3000_GUARD_TIME_1_4: - deb_getf("GUARD_INTERVAL_1_4 "); - ofdm->guard_interval = GUARD_INTERVAL_1_4; - break; - default: - err("Unexpected Guard Time returned by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) { - case DIB3000_TRANSMISSION_MODE_2K: - deb_getf("TRANSMISSION_MODE_2K "); - ofdm->transmission_mode = TRANSMISSION_MODE_2K; - break; - case DIB3000_TRANSMISSION_MODE_8K: - deb_getf("TRANSMISSION_MODE_8K "); - ofdm->transmission_mode = TRANSMISSION_MODE_8K; - break; - default: - err("unexpected transmission mode return by TPS (%d)", tps_val); - break; - } - deb_getf("TPS: %d\n", tps_val); - - return 0; -} - -static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *stat = 0; - - if (rd(DIB3000MB_REG_AGC_LOCK)) - *stat |= FE_HAS_SIGNAL; - if (rd(DIB3000MB_REG_CARRIER_LOCK)) - *stat |= FE_HAS_CARRIER; - if (rd(DIB3000MB_REG_VIT_LCK)) - *stat |= FE_HAS_VITERBI; - if (rd(DIB3000MB_REG_TS_SYNC_LOCK)) - *stat |= (FE_HAS_SYNC | FE_HAS_LOCK); - - deb_getf("actual status is %2x\n",*stat); - - deb_getf("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n", - rd(DIB3000MB_REG_TPS_LOCK), - rd(DIB3000MB_REG_TPS_QAM), - rd(DIB3000MB_REG_TPS_HRCH), - rd(DIB3000MB_REG_TPS_VIT_ALPHA), - rd(DIB3000MB_REG_TPS_CODE_RATE_HP), - rd(DIB3000MB_REG_TPS_CODE_RATE_LP), - rd(DIB3000MB_REG_TPS_GUARD_TIME), - rd(DIB3000MB_REG_TPS_FFT), - rd(DIB3000MB_REG_TPS_CELL_ID)); - - //*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - return 0; -} - -static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB)); - return 0; -} - -/* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */ -static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170; - return 0; -} - -static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - struct dib3000_state* state = fe->demodulator_priv; - short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER); - int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) | - rd(DIB3000MB_REG_NOISE_POWER_LSB); - *snr = (sigpow << 8) / ((icipow > 0) ? icipow : 1); - return 0; -} - -static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) -{ - struct dib3000_state* state = fe->demodulator_priv; - - *unc = rd(DIB3000MB_REG_PACKET_ERROR_RATE); - return 0; -} - -static int dib3000mb_sleep(struct dvb_frontend* fe) -{ - struct dib3000_state* state = fe->demodulator_priv; - deb_info("dib3000mb is going to bed.\n"); - wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN); - return 0; -} - -static int dib3000mb_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 800; - return 0; -} - -static int dib3000mb_fe_init_nonmobile(struct dvb_frontend* fe) -{ - return dib3000mb_fe_init(fe, 0); -} - -static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) -{ - return dib3000mb_set_frontend(fe, fep, 1); -} - -static void dib3000mb_release(struct dvb_frontend* fe) -{ - struct dib3000_state *state = fe->demodulator_priv; - kfree(state); -} - -/* pid filter and transfer stuff */ -static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0); - wr(index+DIB3000MB_REG_FIRST_PID,pid); - return 0; -} - -static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - - deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); - if (onoff) { - wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_ACTIVATE); - } else { - wr(DIB3000MB_REG_FIFO, DIB3000MB_FIFO_INHIBIT); - } - return 0; -} - -static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff) -{ - struct dib3000_state *state = fe->demodulator_priv; - deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling"); - wr(DIB3000MB_REG_PID_PARSE,onoff); - return 0; -} - -static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) -{ - struct dib3000_state *state = fe->demodulator_priv; - if (onoff) { - wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); - } else { - wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr)); - } - return 0; -} - -static struct dvb_frontend_ops dib3000mb_ops; - -struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, - struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops) -{ - struct dib3000_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config,config,sizeof(struct dib3000_config)); - - /* check for the correct demod */ - if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM) - goto error; - - if (rd(DIB3000_REG_DEVICE_ID) != DIB3000MB_DEVICE_ID) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dib3000mb_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* set the xfer operations */ - xfer_ops->pid_parse = dib3000mb_pid_parse; - xfer_ops->fifo_ctrl = dib3000mb_fifo_control; - xfer_ops->pid_ctrl = dib3000mb_pid_control; - xfer_ops->tuner_pass_ctrl = dib3000mb_tuner_pass_ctrl; - - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dib3000mb_ops = { - - .info = { - .name = "DiBcom 3000M-B DVB-T", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib3000mb_release, - - .init = dib3000mb_fe_init_nonmobile, - .sleep = dib3000mb_sleep, - - .set_frontend = dib3000mb_set_frontend_and_tuner, - .get_frontend = dib3000mb_get_frontend, - .get_tune_settings = dib3000mb_fe_get_tune_settings, - - .read_status = dib3000mb_read_status, - .read_ber = dib3000mb_read_ber, - .read_signal_strength = dib3000mb_read_signal_strength, - .read_snr = dib3000mb_read_snr, - .read_ucblocks = dib3000mb_read_unc_blocks, -}; - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(dib3000mb_attach); diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h deleted file mode 100644 index 1a12747fdc9..00000000000 --- a/drivers/media/dvb/frontends/dib3000mb_priv.h +++ /dev/null @@ -1,560 +0,0 @@ -/* - * dib3000mb_priv.h - * - * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - * for more information see dib3000mb.c . - */ - -#ifndef __DIB3000MB_PRIV_H_INCLUDED__ -#define __DIB3000MB_PRIV_H_INCLUDED__ - -/* info and err, taken from usb.h, if there is anything available like by default. */ -#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg) -#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg) - -/* handy shortcuts */ -#define rd(reg) dib3000_read_reg(state,reg) - -#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \ - { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; } - -#define wr_foreach(a,v) { int i; \ - if (sizeof(a) != sizeof(v)) \ - err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\ - for (i=0; i < sizeof(a)/sizeof(u16); i++) \ - wr(a[i],v[i]); \ - } - -#define set_or(reg,val) wr(reg,rd(reg) | val) - -#define set_and(reg,val) wr(reg,rd(reg) & val) - -/* debug */ - -#ifdef CONFIG_DVB_DIBCOM_DEBUG -#define dprintk(level,args...) \ - do { if ((debug & level)) { printk(args); } } while (0) -#else -#define dprintk(args...) do { } while (0) -#endif - -/* mask for enabling a specific pid for the pid_filter */ -#define DIB3000_ACTIVATE_PID_FILTERING (0x2000) - -/* common values for tuning */ -#define DIB3000_ALPHA_0 ( 0) -#define DIB3000_ALPHA_1 ( 1) -#define DIB3000_ALPHA_2 ( 2) -#define DIB3000_ALPHA_4 ( 4) - -#define DIB3000_CONSTELLATION_QPSK ( 0) -#define DIB3000_CONSTELLATION_16QAM ( 1) -#define DIB3000_CONSTELLATION_64QAM ( 2) - -#define DIB3000_GUARD_TIME_1_32 ( 0) -#define DIB3000_GUARD_TIME_1_16 ( 1) -#define DIB3000_GUARD_TIME_1_8 ( 2) -#define DIB3000_GUARD_TIME_1_4 ( 3) - -#define DIB3000_TRANSMISSION_MODE_2K ( 0) -#define DIB3000_TRANSMISSION_MODE_8K ( 1) - -#define DIB3000_SELECT_LP ( 0) -#define DIB3000_SELECT_HP ( 1) - -#define DIB3000_FEC_1_2 ( 1) -#define DIB3000_FEC_2_3 ( 2) -#define DIB3000_FEC_3_4 ( 3) -#define DIB3000_FEC_5_6 ( 5) -#define DIB3000_FEC_7_8 ( 7) - -#define DIB3000_HRCH_OFF ( 0) -#define DIB3000_HRCH_ON ( 1) - -#define DIB3000_DDS_INVERSION_OFF ( 0) -#define DIB3000_DDS_INVERSION_ON ( 1) - -#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8)) -#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7))) - -#define DIB3000_REG_MANUFACTOR_ID ( 1025) -#define DIB3000_I2C_ID_DIBCOM (0x01b3) - -#define DIB3000_REG_DEVICE_ID ( 1026) -#define DIB3000MB_DEVICE_ID (0x3000) -#define DIB3000MC_DEVICE_ID (0x3001) -#define DIB3000P_DEVICE_ID (0x3002) - -/* frontend state */ -struct dib3000_state { - struct i2c_adapter* i2c; - -/* configuration settings */ - struct dib3000_config config; - - struct dvb_frontend frontend; - int timing_offset; - int timing_offset_comp_done; - - fe_bandwidth_t last_tuned_bw; - u32 last_tuned_freq; -}; - -/* register addresses and some of their default values */ - -/* restart subsystems */ -#define DIB3000MB_REG_RESTART ( 0) - -#define DIB3000MB_RESTART_OFF ( 0) -#define DIB3000MB_RESTART_AUTO_SEARCH (1 << 1) -#define DIB3000MB_RESTART_CTRL (1 << 2) -#define DIB3000MB_RESTART_AGC (1 << 3) - -/* FFT size */ -#define DIB3000MB_REG_FFT ( 1) - -/* Guard time */ -#define DIB3000MB_REG_GUARD_TIME ( 2) - -/* QAM */ -#define DIB3000MB_REG_QAM ( 3) - -/* Alpha coefficient high priority Viterbi algorithm */ -#define DIB3000MB_REG_VIT_ALPHA ( 4) - -/* spectrum inversion */ -#define DIB3000MB_REG_DDS_INV ( 5) - -/* DDS frequency value (IF position) ad ? values don't match reg_3000mb.txt */ -#define DIB3000MB_REG_DDS_FREQ_MSB ( 6) -#define DIB3000MB_REG_DDS_FREQ_LSB ( 7) -#define DIB3000MB_DDS_FREQ_MSB ( 178) -#define DIB3000MB_DDS_FREQ_LSB ( 8990) - -/* timing frequency (carrier spacing) */ -static u16 dib3000mb_reg_timing_freq[] = { 8,9 }; -static u16 dib3000mb_timing_freq[][2] = { - { 126 , 48873 }, /* 6 MHz */ - { 147 , 57019 }, /* 7 MHz */ - { 168 , 65164 }, /* 8 MHz */ -}; - -/* impulse noise parameter */ -/* 36 ??? */ - -static u16 dib3000mb_reg_impulse_noise[] = { 10,11,12,15,36 }; - -enum dib3000mb_impulse_noise_type { - DIB3000MB_IMPNOISE_OFF, - DIB3000MB_IMPNOISE_MOBILE, - DIB3000MB_IMPNOISE_FIXED, - DIB3000MB_IMPNOISE_DEFAULT -}; - -static u16 dib3000mb_impulse_noise_values[][5] = { - { 0x0000, 0x0004, 0x0014, 0x01ff, 0x0399 }, /* off */ - { 0x0001, 0x0004, 0x0014, 0x01ff, 0x037b }, /* mobile */ - { 0x0001, 0x0004, 0x0020, 0x01bd, 0x0399 }, /* fixed */ - { 0x0000, 0x0002, 0x000a, 0x01ff, 0x0399 }, /* default */ -}; - -/* - * Dual Automatic-Gain-Control - * - gains RF in tuner (AGC1) - * - gains IF after filtering (AGC2) - */ - -/* also from 16 to 18 */ -static u16 dib3000mb_reg_agc_gain[] = { - 19,20,21,22,23,24,25,26,27,28,29,30,31,32 -}; - -static u16 dib3000mb_default_agc_gain[] = - { 0x0001, 52429, 623, 128, 166, 195, 61, /* RF ??? */ - 0x0001, 53766, 38011, 0, 90, 33, 23 }; /* IF ??? */ - -/* phase noise */ -/* 36 is set when setting the impulse noise */ -static u16 dib3000mb_reg_phase_noise[] = { 33,34,35,37,38 }; - -static u16 dib3000mb_default_noise_phase[] = { 2, 544, 0, 5, 4 }; - -/* lock duration */ -static u16 dib3000mb_reg_lock_duration[] = { 39,40 }; -static u16 dib3000mb_default_lock_duration[] = { 135, 135 }; - -/* AGC loop bandwidth */ -static u16 dib3000mb_reg_agc_bandwidth[] = { 43,44,45,46,47,48,49,50 }; - -static u16 dib3000mb_agc_bandwidth_low[] = - { 2088, 10, 2088, 10, 3448, 5, 3448, 5 }; -static u16 dib3000mb_agc_bandwidth_high[] = - { 2349, 5, 2349, 5, 2586, 2, 2586, 2 }; - -/* - * lock0 definition (coff_lock) - */ -#define DIB3000MB_REG_LOCK0_MASK ( 51) -#define DIB3000MB_LOCK0_DEFAULT ( 4) - -/* - * lock1 definition (cpil_lock) - * for auto search - * which values hide behind the lock masks - */ -#define DIB3000MB_REG_LOCK1_MASK ( 52) -#define DIB3000MB_LOCK1_SEARCH_4 (0x0004) -#define DIB3000MB_LOCK1_SEARCH_2048 (0x0800) -#define DIB3000MB_LOCK1_DEFAULT (0x0001) - -/* - * lock2 definition (fec_lock) */ -#define DIB3000MB_REG_LOCK2_MASK ( 53) -#define DIB3000MB_LOCK2_DEFAULT (0x0080) - -/* - * SEQ ? what was that again ... :) - * changes when, inversion, guard time and fft is - * either automatically detected or not - */ -#define DIB3000MB_REG_SEQ ( 54) - -/* bandwidth */ -static u16 dib3000mb_reg_bandwidth[] = { 55,56,57,58,59,60,61,62,63,64,65,66,67 }; -static u16 dib3000mb_bandwidth_6mhz[] = - { 0, 33, 53312, 112, 46635, 563, 36565, 0, 1000, 0, 1010, 1, 45264 }; - -static u16 dib3000mb_bandwidth_7mhz[] = - { 0, 28, 64421, 96, 39973, 483, 3255, 0, 1000, 0, 1010, 1, 45264 }; - -static u16 dib3000mb_bandwidth_8mhz[] = - { 0, 25, 23600, 84, 34976, 422, 43808, 0, 1000, 0, 1010, 1, 45264 }; - -#define DIB3000MB_REG_UNK_68 ( 68) -#define DIB3000MB_UNK_68 ( 0) - -#define DIB3000MB_REG_UNK_69 ( 69) -#define DIB3000MB_UNK_69 ( 0) - -#define DIB3000MB_REG_UNK_71 ( 71) -#define DIB3000MB_UNK_71 ( 0) - -#define DIB3000MB_REG_UNK_77 ( 77) -#define DIB3000MB_UNK_77 ( 6) - -#define DIB3000MB_REG_UNK_78 ( 78) -#define DIB3000MB_UNK_78 (0x0080) - -/* isi */ -#define DIB3000MB_REG_ISI ( 79) -#define DIB3000MB_ISI_ACTIVATE ( 0) -#define DIB3000MB_ISI_INHIBIT ( 1) - -/* sync impovement */ -#define DIB3000MB_REG_SYNC_IMPROVEMENT ( 84) -#define DIB3000MB_SYNC_IMPROVE_2K_1_8 ( 3) -#define DIB3000MB_SYNC_IMPROVE_DEFAULT ( 0) - -/* phase noise compensation inhibition */ -#define DIB3000MB_REG_PHASE_NOISE ( 87) -#define DIB3000MB_PHASE_NOISE_DEFAULT ( 0) - -#define DIB3000MB_REG_UNK_92 ( 92) -#define DIB3000MB_UNK_92 (0x0080) - -#define DIB3000MB_REG_UNK_96 ( 96) -#define DIB3000MB_UNK_96 (0x0010) - -#define DIB3000MB_REG_UNK_97 ( 97) -#define DIB3000MB_UNK_97 (0x0009) - -/* mobile mode ??? */ -#define DIB3000MB_REG_MOBILE_MODE ( 101) -#define DIB3000MB_MOBILE_MODE_ON ( 1) -#define DIB3000MB_MOBILE_MODE_OFF ( 0) - -#define DIB3000MB_REG_UNK_106 ( 106) -#define DIB3000MB_UNK_106 (0x0080) - -#define DIB3000MB_REG_UNK_107 ( 107) -#define DIB3000MB_UNK_107 (0x0080) - -#define DIB3000MB_REG_UNK_108 ( 108) -#define DIB3000MB_UNK_108 (0x0080) - -/* fft */ -#define DIB3000MB_REG_UNK_121 ( 121) -#define DIB3000MB_UNK_121_2K ( 7) -#define DIB3000MB_UNK_121_DEFAULT ( 5) - -#define DIB3000MB_REG_UNK_122 ( 122) -#define DIB3000MB_UNK_122 ( 2867) - -/* QAM for mobile mode */ -#define DIB3000MB_REG_MOBILE_MODE_QAM ( 126) -#define DIB3000MB_MOBILE_MODE_QAM_64 ( 3) -#define DIB3000MB_MOBILE_MODE_QAM_QPSK_16 ( 1) -#define DIB3000MB_MOBILE_MODE_QAM_OFF ( 0) - -/* - * data diversity when having more than one chip on-board - * see also DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY - */ -#define DIB3000MB_REG_DATA_IN_DIVERSITY ( 127) -#define DIB3000MB_DATA_DIVERSITY_IN_OFF ( 0) -#define DIB3000MB_DATA_DIVERSITY_IN_ON ( 2) - -/* vit hrch */ -#define DIB3000MB_REG_VIT_HRCH ( 128) - -/* vit code rate */ -#define DIB3000MB_REG_VIT_CODE_RATE ( 129) - -/* vit select hp */ -#define DIB3000MB_REG_VIT_HP ( 130) - -/* time frame for Bit-Error-Rate calculation */ -#define DIB3000MB_REG_BERLEN ( 135) -#define DIB3000MB_BERLEN_LONG ( 0) -#define DIB3000MB_BERLEN_DEFAULT ( 1) -#define DIB3000MB_BERLEN_MEDIUM ( 2) -#define DIB3000MB_BERLEN_SHORT ( 3) - -/* 142 - 152 FIFO parameters - * which is what ? - */ - -#define DIB3000MB_REG_FIFO_142 ( 142) -#define DIB3000MB_FIFO_142 ( 0) - -/* MPEG2 TS output mode */ -#define DIB3000MB_REG_MPEG2_OUT_MODE ( 143) -#define DIB3000MB_MPEG2_OUT_MODE_204 ( 0) -#define DIB3000MB_MPEG2_OUT_MODE_188 ( 1) - -#define DIB3000MB_REG_PID_PARSE ( 144) -#define DIB3000MB_PID_PARSE_INHIBIT ( 0) -#define DIB3000MB_PID_PARSE_ACTIVATE ( 1) - -#define DIB3000MB_REG_FIFO ( 145) -#define DIB3000MB_FIFO_INHIBIT ( 1) -#define DIB3000MB_FIFO_ACTIVATE ( 0) - -#define DIB3000MB_REG_FIFO_146 ( 146) -#define DIB3000MB_FIFO_146 ( 3) - -#define DIB3000MB_REG_FIFO_147 ( 147) -#define DIB3000MB_FIFO_147 (0x0100) - -/* - * pidfilter - * it is not a hardware pidfilter but a filter which drops all pids - * except the ones set. Necessary because of the limited USB1.1 bandwidth. - * regs 153-168 - */ - -#define DIB3000MB_REG_FIRST_PID ( 153) -#define DIB3000MB_NUM_PIDS ( 16) - -/* - * output mode - * USB devices have to use 'slave'-mode - * see also DIB3000MB_REG_ELECT_OUT_MODE - */ -#define DIB3000MB_REG_OUTPUT_MODE ( 169) -#define DIB3000MB_OUTPUT_MODE_GATED_CLK ( 0) -#define DIB3000MB_OUTPUT_MODE_CONT_CLK ( 1) -#define DIB3000MB_OUTPUT_MODE_SERIAL ( 2) -#define DIB3000MB_OUTPUT_MODE_DATA_DIVERSITY ( 5) -#define DIB3000MB_OUTPUT_MODE_SLAVE ( 6) - -/* irq event mask */ -#define DIB3000MB_REG_IRQ_EVENT_MASK ( 170) -#define DIB3000MB_IRQ_EVENT_MASK ( 0) - -/* filter coefficients */ -static u16 dib3000mb_reg_filter_coeffs[] = { - 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, - 188, 189, 190, 191, 192, 194 -}; - -static u16 dib3000mb_filter_coeffs[] = { - 226, 160, 29, - 979, 998, 19, - 22, 1019, 1006, - 1022, 12, 6, - 1017, 1017, 3, - 6, 1019, - 1021, 2, 3, - 1, 0, -}; - -/* - * mobile algorithm (when you are moving with your device) - * but not faster than 90 km/h - */ -#define DIB3000MB_REG_MOBILE_ALGO ( 195) -#define DIB3000MB_MOBILE_ALGO_ON ( 0) -#define DIB3000MB_MOBILE_ALGO_OFF ( 1) - -/* multiple demodulators algorithm */ -#define DIB3000MB_REG_MULTI_DEMOD_MSB ( 206) -#define DIB3000MB_REG_MULTI_DEMOD_LSB ( 207) - -/* terminator, no more demods */ -#define DIB3000MB_MULTI_DEMOD_MSB ( 32767) -#define DIB3000MB_MULTI_DEMOD_LSB ( 4095) - -/* bring the device into a known */ -#define DIB3000MB_REG_RESET_DEVICE ( 1024) -#define DIB3000MB_RESET_DEVICE (0x812c) -#define DIB3000MB_RESET_DEVICE_RST ( 0) - -/* hardware clock configuration */ -#define DIB3000MB_REG_CLOCK ( 1027) -#define DIB3000MB_CLOCK_DEFAULT (0x9000) -#define DIB3000MB_CLOCK_DIVERSITY (0x92b0) - -/* power down config */ -#define DIB3000MB_REG_POWER_CONTROL ( 1028) -#define DIB3000MB_POWER_DOWN ( 1) -#define DIB3000MB_POWER_UP ( 0) - -/* electrical output mode */ -#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029) -#define DIB3000MB_ELECT_OUT_MODE_OFF ( 0) -#define DIB3000MB_ELECT_OUT_MODE_ON ( 1) - -/* set the tuner i2c address */ -#define DIB3000MB_REG_TUNER ( 1089) - -/* monitoring registers (read only) */ - -/* agc loop locked (size: 1) */ -#define DIB3000MB_REG_AGC_LOCK ( 324) - -/* agc power (size: 16) */ -#define DIB3000MB_REG_AGC_POWER ( 325) - -/* agc1 value (16) */ -#define DIB3000MB_REG_AGC1_VALUE ( 326) - -/* agc2 value (16) */ -#define DIB3000MB_REG_AGC2_VALUE ( 327) - -/* total RF power (16), can be used for signal strength */ -#define DIB3000MB_REG_RF_POWER ( 328) - -/* dds_frequency with offset (24) */ -#define DIB3000MB_REG_DDS_VALUE_MSB ( 339) -#define DIB3000MB_REG_DDS_VALUE_LSB ( 340) - -/* timing offset signed (24) */ -#define DIB3000MB_REG_TIMING_OFFSET_MSB ( 341) -#define DIB3000MB_REG_TIMING_OFFSET_LSB ( 342) - -/* fft start position (13) */ -#define DIB3000MB_REG_FFT_WINDOW_POS ( 353) - -/* carriers locked (1) */ -#define DIB3000MB_REG_CARRIER_LOCK ( 355) - -/* noise power (24) */ -#define DIB3000MB_REG_NOISE_POWER_MSB ( 372) -#define DIB3000MB_REG_NOISE_POWER_LSB ( 373) - -#define DIB3000MB_REG_MOBILE_NOISE_MSB ( 374) -#define DIB3000MB_REG_MOBILE_NOISE_LSB ( 375) - -/* - * signal power (16), this and the above can be - * used to calculate the signal/noise - ratio - */ -#define DIB3000MB_REG_SIGNAL_POWER ( 380) - -/* mer (24) */ -#define DIB3000MB_REG_MER_MSB ( 381) -#define DIB3000MB_REG_MER_LSB ( 382) - -/* - * Transmission Parameter Signalling (TPS) - * the following registers can be used to get TPS-information. - * The values are according to the DVB-T standard. - */ - -/* TPS locked (1) */ -#define DIB3000MB_REG_TPS_LOCK ( 394) - -/* QAM from TPS (2) (values according to DIB3000MB_REG_QAM) */ -#define DIB3000MB_REG_TPS_QAM ( 398) - -/* hierarchy from TPS (1) */ -#define DIB3000MB_REG_TPS_HRCH ( 399) - -/* alpha from TPS (3) (values according to DIB3000MB_REG_VIT_ALPHA) */ -#define DIB3000MB_REG_TPS_VIT_ALPHA ( 400) - -/* code rate high priority from TPS (3) (values according to DIB3000MB_FEC_*) */ -#define DIB3000MB_REG_TPS_CODE_RATE_HP ( 401) - -/* code rate low priority from TPS (3) if DIB3000MB_REG_TPS_VIT_ALPHA */ -#define DIB3000MB_REG_TPS_CODE_RATE_LP ( 402) - -/* guard time from TPS (2) (values according to DIB3000MB_REG_GUARD_TIME */ -#define DIB3000MB_REG_TPS_GUARD_TIME ( 403) - -/* fft size from TPS (2) (values according to DIB3000MB_REG_FFT) */ -#define DIB3000MB_REG_TPS_FFT ( 404) - -/* cell id from TPS (16) */ -#define DIB3000MB_REG_TPS_CELL_ID ( 406) - -/* TPS (68) */ -#define DIB3000MB_REG_TPS_1 ( 408) -#define DIB3000MB_REG_TPS_2 ( 409) -#define DIB3000MB_REG_TPS_3 ( 410) -#define DIB3000MB_REG_TPS_4 ( 411) -#define DIB3000MB_REG_TPS_5 ( 412) - -/* bit error rate (before RS correction) (21) */ -#define DIB3000MB_REG_BER_MSB ( 414) -#define DIB3000MB_REG_BER_LSB ( 415) - -/* packet error rate (uncorrected TS packets) (16) */ -#define DIB3000MB_REG_PACKET_ERROR_RATE ( 417) - -/* uncorrected packet count (16) */ -#define DIB3000MB_REG_UNC ( 420) - -/* viterbi locked (1) */ -#define DIB3000MB_REG_VIT_LCK ( 421) - -/* viterbi inidcator (16) */ -#define DIB3000MB_REG_VIT_INDICATOR ( 422) - -/* transport stream sync lock (1) */ -#define DIB3000MB_REG_TS_SYNC_LOCK ( 423) - -/* transport stream RS lock (1) */ -#define DIB3000MB_REG_TS_RS_LOCK ( 424) - -/* lock mask 0 value (1) */ -#define DIB3000MB_REG_LOCK0_VALUE ( 425) - -/* lock mask 1 value (1) */ -#define DIB3000MB_REG_LOCK1_VALUE ( 426) - -/* lock mask 2 value (1) */ -#define DIB3000MB_REG_LOCK2_VALUE ( 427) - -/* interrupt pending for auto search */ -#define DIB3000MB_REG_AS_IRQ_PENDING ( 434) - -#endif diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c deleted file mode 100644 index fa851601e7d..00000000000 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ /dev/null @@ -1,924 +0,0 @@ -/* - * Driver for DiBcom DiB3000MC/P-demodulator. - * - * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/) - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) - * - * This code is partially based on the previous dib3000mc.c . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ - -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib3000mc.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -static int buggy_sfn_workaround; -module_param(buggy_sfn_workaround, int, 0644); -MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0) - -struct dib3000mc_state { - struct dvb_frontend demod; - struct dib3000mc_config *cfg; - - u8 i2c_addr; - struct i2c_adapter *i2c_adap; - - struct dibx000_i2c_master i2c_master; - - u32 timf; - - fe_bandwidth_t current_bandwidth; - - u16 dev_id; - - u8 sfn_workaround_active :1; -}; - -static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) -{ - u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c_adap, msg, 2) != 2) - dprintk("i2c read error on %d\n",reg); - - return (rb[0] << 8) | rb[1]; -} - -static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} - -static int dib3000mc_identify(struct dib3000mc_state *state) -{ - u16 value; - if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) { - dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value); - return -EREMOTEIO; - } - - value = dib3000mc_read_word(state, 1026); - if (value != 0x3001 && value != 0x3002) { - dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value); - return -EREMOTEIO; - } - state->dev_id = value; - - dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id); - - return 0; -} - -static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset) -{ - u32 timf; - - if (state->timf == 0) { - timf = 1384402; // default value for 8MHz - if (update_offset) - msleep(200); // first time we do an update - } else - timf = state->timf; - - timf *= (bw / 1000); - - if (update_offset) { - s16 tim_offs = dib3000mc_read_word(state, 416); - - if (tim_offs & 0x2000) - tim_offs -= 0x4000; - - if (nfft == TRANSMISSION_MODE_2K) - tim_offs *= 4; - - timf += tim_offs; - state->timf = timf / (bw / 1000); - } - - dprintk("timf: %d\n", timf); - - dib3000mc_write_word(state, 23, (u16) (timf >> 16)); - dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff); - - return 0; -} - -static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) -{ - u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb; - if (state->cfg->pwm3_inversion) { - reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0); - reg_52 |= (1 << 2); - } else { - reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0); - reg_52 |= (1 << 8); - } - dib3000mc_write_word(state, 51, reg_51); - dib3000mc_write_word(state, 52, reg_52); - - if (state->cfg->use_pwm3) - dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0)); - else - dib3000mc_write_word(state, 245, 0); - - dib3000mc_write_word(state, 1040, 0x3); - return 0; -} - -static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode) -{ - int ret = 0; - u16 fifo_threshold = 1792; - u16 outreg = 0; - u16 outmode = 0; - u16 elecout = 1; - u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */ - - dprintk("-I- Setting output mode for demod %p to %d\n", - &state->demod, mode); - - switch (mode) { - case OUTMODE_HIGH_Z: // disable - elecout = 0; - break; - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock - outmode = 0; - break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock - outmode = 1; - break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input - outmode = 2; - break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding - elecout = 3; - /*ADDR @ 206 : - P_smo_error_discard [1;6:6] = 0 - P_smo_rs_discard [1;5:5] = 0 - P_smo_pid_parse [1;4:4] = 0 - P_smo_fifo_flush [1;3:3] = 0 - P_smo_mode [2;2:1] = 11 - P_smo_ovf_prot [1;0:0] = 0 - */ - smo_reg |= 3 << 1; - fifo_threshold = 512; - outmode = 5; - break; - case OUTMODE_DIVERSITY: - outmode = 4; - elecout = 1; - break; - default: - dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); - outmode = 0; - break; - } - - if ((state->cfg->output_mpeg2_in_188_bytes)) - smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1 - - outreg = dib3000mc_read_word(state, 244) & 0x07FF; - outreg |= (outmode << 11); - ret |= dib3000mc_write_word(state, 244, outreg); - ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/ - ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */ - ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */ - return ret; -} - -static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw) -{ - u16 bw_cfg[6] = { 0 }; - u16 imp_bw_cfg[3] = { 0 }; - u16 reg; - -/* settings here are for 27.7MHz */ - switch (bw) { - case 8000: - bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20; - imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7; - break; - - case 7000: - bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7; - imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0; - break; - - case 6000: - bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5; - imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089; - break; - - case 5000: - bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500; - imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072; - break; - - default: return -EINVAL; - } - - for (reg = 6; reg < 12; reg++) - dib3000mc_write_word(state, reg, bw_cfg[reg - 6]); - dib3000mc_write_word(state, 12, 0x0000); - dib3000mc_write_word(state, 13, 0x03e8); - dib3000mc_write_word(state, 14, 0x0000); - dib3000mc_write_word(state, 15, 0x03f2); - dib3000mc_write_word(state, 16, 0x0001); - dib3000mc_write_word(state, 17, 0xb0d0); - // P_sec_len - dib3000mc_write_word(state, 18, 0x0393); - dib3000mc_write_word(state, 19, 0x8700); - - for (reg = 55; reg < 58; reg++) - dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]); - - // Timing configuration - dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0); - - return 0; -} - -static u16 impulse_noise_val[29] = - -{ - 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3, - 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2, - 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd -}; - -static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft) -{ - u16 i; - for (i = 58; i < 87; i++) - dib3000mc_write_word(state, i, impulse_noise_val[i-58]); - - if (nfft == TRANSMISSION_MODE_8K) { - dib3000mc_write_word(state, 58, 0x3b); - dib3000mc_write_word(state, 84, 0x00); - dib3000mc_write_word(state, 85, 0x8200); - } - - dib3000mc_write_word(state, 34, 0x1294); - dib3000mc_write_word(state, 35, 0x1ff8); - if (mode == 1) - dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10)); -} - -static int dib3000mc_init(struct dvb_frontend *demod) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - struct dibx000_agc_config *agc = state->cfg->agc; - - // Restart Configuration - dib3000mc_write_word(state, 1027, 0x8000); - dib3000mc_write_word(state, 1027, 0x0000); - - // power up the demod + mobility configuration - dib3000mc_write_word(state, 140, 0x0000); - dib3000mc_write_word(state, 1031, 0); - - if (state->cfg->mobile_mode) { - dib3000mc_write_word(state, 139, 0x0000); - dib3000mc_write_word(state, 141, 0x0000); - dib3000mc_write_word(state, 175, 0x0002); - dib3000mc_write_word(state, 1032, 0x0000); - } else { - dib3000mc_write_word(state, 139, 0x0001); - dib3000mc_write_word(state, 141, 0x0000); - dib3000mc_write_word(state, 175, 0x0000); - dib3000mc_write_word(state, 1032, 0x012C); - } - dib3000mc_write_word(state, 1033, 0x0000); - - // P_clk_cfg - dib3000mc_write_word(state, 1037, 0x3130); - - // other configurations - - // P_ctrl_sfreq - dib3000mc_write_word(state, 33, (5 << 0)); - dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0)); - - // Phase noise control - // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange - dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0)); - - if (state->cfg->phase_noise_mode == 0) - dib3000mc_write_word(state, 111, 0x00); - else - dib3000mc_write_word(state, 111, 0x02); - - // P_agc_global - dib3000mc_write_word(state, 50, 0x8000); - - // agc setup misc - dib3000mc_setup_pwm_state(state); - - // P_agc_counter_lock - dib3000mc_write_word(state, 53, 0x87); - // P_agc_counter_unlock - dib3000mc_write_word(state, 54, 0x87); - - /* agc */ - dib3000mc_write_word(state, 36, state->cfg->max_time); - dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0)); - dib3000mc_write_word(state, 38, state->cfg->pwm3_value); - dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); - - // set_agc_loop_Bw - dib3000mc_write_word(state, 40, 0x0179); - dib3000mc_write_word(state, 41, 0x03f0); - - dib3000mc_write_word(state, 42, agc->agc1_max); - dib3000mc_write_word(state, 43, agc->agc1_min); - dib3000mc_write_word(state, 44, agc->agc2_max); - dib3000mc_write_word(state, 45, agc->agc2_min); - dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2); - dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2); - dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2); - dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2); - -// Begin: TimeOut registers - // P_pha3_thres - dib3000mc_write_word(state, 110, 3277); - // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80 - dib3000mc_write_word(state, 26, 0x6680); - // lock_mask0 - dib3000mc_write_word(state, 1, 4); - // lock_mask1 - dib3000mc_write_word(state, 2, 4); - // lock_mask2 - dib3000mc_write_word(state, 3, 0x1000); - // P_search_maxtrial=1 - dib3000mc_write_word(state, 5, 1); - - dib3000mc_set_bandwidth(state, 8000); - - // div_lock_mask - dib3000mc_write_word(state, 4, 0x814); - - dib3000mc_write_word(state, 21, (1 << 9) | 0x164); - dib3000mc_write_word(state, 22, 0x463d); - - // Spurious rm cfg - // P_cspu_regul, P_cspu_win_cut - dib3000mc_write_word(state, 120, 0x200f); - // P_adp_selec_monit - dib3000mc_write_word(state, 134, 0); - - // Fec cfg - dib3000mc_write_word(state, 195, 0x10); - - // diversity register: P_dvsy_sync_wait.. - dib3000mc_write_word(state, 180, 0x2FF0); - - // Impulse noise configuration - dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K); - - // output mode set-up - dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); - - /* close the i2c-gate */ - dib3000mc_write_word(state, 769, (1 << 7) ); - - return 0; -} - -static int dib3000mc_sleep(struct dvb_frontend *demod) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - - dib3000mc_write_word(state, 1031, 0xFFFF); - dib3000mc_write_word(state, 1032, 0xFFFF); - dib3000mc_write_word(state, 1033, 0xFFF0); - - return 0; -} - -static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) -{ - u16 cfg[4] = { 0 },reg; - switch (qam) { - case QPSK: - cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0; - break; - case QAM_16: - cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0; - break; - case QAM_64: - cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8; - break; - } - for (reg = 129; reg < 133; reg++) - dib3000mc_write_word(state, reg, cfg[reg - 129]); -} - -static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq) -{ - u16 value; - dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0); - -// if (boost) -// dib3000mc_write_word(state, 100, (11 << 6) + 6); -// else - dib3000mc_write_word(state, 100, (16 << 6) + 9); - - dib3000mc_write_word(state, 1027, 0x0800); - dib3000mc_write_word(state, 1027, 0x0000); - - //Default cfg isi offset adp - dib3000mc_write_word(state, 26, 0x6680); - dib3000mc_write_word(state, 29, 0x1273); - dib3000mc_write_word(state, 33, 5); - dib3000mc_set_adp_cfg(state, QAM_16); - dib3000mc_write_word(state, 133, 15564); - - dib3000mc_write_word(state, 12 , 0x0); - dib3000mc_write_word(state, 13 , 0x3e8); - dib3000mc_write_word(state, 14 , 0x0); - dib3000mc_write_word(state, 15 , 0x3f2); - - dib3000mc_write_word(state, 93,0); - dib3000mc_write_word(state, 94,0); - dib3000mc_write_word(state, 95,0); - dib3000mc_write_word(state, 96,0); - dib3000mc_write_word(state, 97,0); - dib3000mc_write_word(state, 98,0); - - dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode); - - value = 0; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (0 << 7); break; - default: - case TRANSMISSION_MODE_8K: value |= (1 << 7); break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: value |= (0 << 5); break; - case GUARD_INTERVAL_1_16: value |= (1 << 5); break; - case GUARD_INTERVAL_1_4: value |= (3 << 5); break; - default: - case GUARD_INTERVAL_1_8: value |= (2 << 5); break; - } - switch (ch->u.ofdm.constellation) { - case QPSK: value |= (0 << 3); break; - case QAM_16: value |= (1 << 3); break; - default: - case QAM_64: value |= (2 << 3); break; - } - switch (HIERARCHY_1) { - case HIERARCHY_2: value |= 2; break; - case HIERARCHY_4: value |= 4; break; - default: - case HIERARCHY_1: value |= 1; break; - } - dib3000mc_write_word(state, 0, value); - dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4)); - - value = 0; - if (ch->u.ofdm.hierarchy_information == 1) - value |= (1 << 4); - if (1 == 1) - value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { - case FEC_2_3: value |= (2 << 1); break; - case FEC_3_4: value |= (3 << 1); break; - case FEC_5_6: value |= (5 << 1); break; - case FEC_7_8: value |= (7 << 1); break; - default: - case FEC_1_2: value |= (1 << 1); break; - } - dib3000mc_write_word(state, 181, value); - - // diversity synchro delay add 50% SFN margin - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: value = 256; break; - case TRANSMISSION_MODE_2K: - default: value = 64; break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: value *= 2; break; - case GUARD_INTERVAL_1_8: value *= 4; break; - case GUARD_INTERVAL_1_4: value *= 8; break; - default: - case GUARD_INTERVAL_1_32: value *= 1; break; - } - value <<= 4; - value |= dib3000mc_read_word(state, 180) & 0x000f; - dib3000mc_write_word(state, 180, value); - - // restart demod - value = dib3000mc_read_word(state, 0); - dib3000mc_write_word(state, 0, value | (1 << 9)); - dib3000mc_write_word(state, 0, value); - - msleep(30); - - dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode); -} - -static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - u16 reg; -// u32 val; - struct dvb_frontend_parameters schan; - - schan = *chan; - - /* TODO what is that ? */ - - /* a channel for autosearch */ - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_2_3; - schan.u.ofdm.hierarchy_information = 0; - - dib3000mc_set_channel_cfg(state, &schan, 11); - - reg = dib3000mc_read_word(state, 0); - dib3000mc_write_word(state, 0, reg | (1 << 8)); - dib3000mc_read_word(state, 511); - dib3000mc_write_word(state, 0, reg); - - return 0; -} - -static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - u16 irq_pending = dib3000mc_read_word(state, 511); - - if (irq_pending & 0x1) // failed - return 1; - - if (irq_pending & 0x2) // succeeded - return 2; - - return 0; // still pending -} - -static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib3000mc_state *state = demod->demodulator_priv; - - // ** configure demod ** - dib3000mc_set_channel_cfg(state, ch, 0); - - // activates isi - if (state->sfn_workaround_active) { - dprintk("SFN workaround is active\n"); - dib3000mc_write_word(state, 29, 0x1273); - dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift - } else { - dib3000mc_write_word(state, 29, 0x1073); - dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift - } - - dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation); - if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) { - dib3000mc_write_word(state, 26, 38528); - dib3000mc_write_word(state, 33, 8); - } else { - dib3000mc_write_word(state, 26, 30336); - dib3000mc_write_word(state, 33, 6); - } - - if (dib3000mc_read_word(state, 509) & 0x80) - dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1); - - return 0; -} - -struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating) -{ - struct dib3000mc_state *st = demod->demodulator_priv; - return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating); -} - -EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master); - -static int dib3000mc_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 tps = dib3000mc_read_word(state,458); - - fep->inversion = INVERSION_AUTO; - - fep->u.ofdm.bandwidth = state->current_bandwidth; - - switch ((tps >> 8) & 0x1) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - } - - switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; - } - - switch ((tps >> 13) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; - case 2: - default: fep->u.ofdm.constellation = QAM_64; break; - } - - /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ - /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */ - - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; - - } - - switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; - } - - return 0; -} - -static int dib3000mc_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - int ret; - - dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); - - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); - - /* maybe the parameter has been changed */ - state->sfn_workaround_active = buggy_sfn_workaround; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fep); - msleep(100); - } - - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 1000, found; - - dib3000mc_autosearch_start(fe, fep); - do { - msleep(1); - found = dib3000mc_autosearch_is_irq(fe); - } while (found == 0 && i--); - - dprintk("autosearch returns: %d\n",found); - if (found == 0 || found == 1) - return 0; // no channel found - - dib3000mc_get_frontend(fe, fep); - } - - ret = dib3000mc_tune(fe, fep); - - /* make this a config parameter */ - dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); - return ret; -} - -static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 lock = dib3000mc_read_word(state, 509); - - *stat = 0; - - if (lock & 0x8000) - *stat |= FE_HAS_SIGNAL; - if (lock & 0x3000) - *stat |= FE_HAS_CARRIER; - if (lock & 0x0100) - *stat |= FE_HAS_VITERBI; - if (lock & 0x0010) - *stat |= FE_HAS_SYNC; - if (lock & 0x0008) - *stat |= FE_HAS_LOCK; - - return 0; -} - -static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501); - return 0; -} - -static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - *unc = dib3000mc_read_word(state, 508); - return 0; -} - -static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 val = dib3000mc_read_word(state, 392); - *strength = 65535 - val; - return 0; -} - -static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - *snr = 0x0000; - return 0; -} - -static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void dib3000mc_release(struct dvb_frontend *fe) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - dibx000_exit_i2c_master(&state->i2c_master); - kfree(state); -} - -int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0); - return 0; -} -EXPORT_SYMBOL(dib3000mc_pid_control); - -int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4); - tmp |= (onoff << 4); - return dib3000mc_write_word(state, 206, tmp); -} -EXPORT_SYMBOL(dib3000mc_pid_parse); - -void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg) -{ - struct dib3000mc_state *state = fe->demodulator_priv; - state->cfg = cfg; -} -EXPORT_SYMBOL(dib3000mc_set_config); - -int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]) -{ - struct dib3000mc_state st = { .i2c_adap = i2c }; - int k; - u8 new_addr; - - static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26}; - - for (k = no_of_demods-1; k >= 0; k--) { - st.cfg = &cfg[k]; - - /* designated i2c address */ - new_addr = DIB3000MC_I2C_ADDRESS[k]; - st.i2c_addr = new_addr; - if (dib3000mc_identify(&st) != 0) { - st.i2c_addr = default_addr; - if (dib3000mc_identify(&st) != 0) { - dprintk("-E- DiB3000P/MC #%d: not identified\n", k); - return -ENODEV; - } - } - - dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK); - - // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0) - dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1); - st.i2c_addr = new_addr; - } - - for (k = 0; k < no_of_demods; k++) { - st.cfg = &cfg[k]; - st.i2c_addr = DIB3000MC_I2C_ADDRESS[k]; - - dib3000mc_write_word(&st, 1024, st.i2c_addr << 3); - - /* turn off data output */ - dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z); - } - return 0; -} -EXPORT_SYMBOL(dib3000mc_i2c_enumeration); - -static struct dvb_frontend_ops dib3000mc_ops; - -struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) -{ - struct dvb_frontend *demod; - struct dib3000mc_state *st; - st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); - if (st == NULL) - return NULL; - - st->cfg = cfg; - st->i2c_adap = i2c_adap; - st->i2c_addr = i2c_addr; - - demod = &st->demod; - demod->demodulator_priv = st; - memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); - - if (dib3000mc_identify(st) != 0) - goto error; - - dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr); - - dib3000mc_write_word(st, 1037, 0x3130); - - return demod; - -error: - kfree(st); - return NULL; -} -EXPORT_SYMBOL(dib3000mc_attach); - -static struct dvb_frontend_ops dib3000mc_ops = { - .info = { - .name = "DiBcom 3000MC/P", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib3000mc_release, - - .init = dib3000mc_init, - .sleep = dib3000mc_sleep, - - .set_frontend = dib3000mc_set_frontend, - .get_tune_settings = dib3000mc_fe_get_tune_settings, - .get_frontend = dib3000mc_get_frontend, - - .read_status = dib3000mc_read_status, - .read_ber = dib3000mc_read_ber, - .read_signal_strength = dib3000mc_read_signal_strength, - .read_snr = dib3000mc_read_snr, - .read_ucblocks = dib3000mc_read_unc_blocks, -}; - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h deleted file mode 100644 index 4142ed7a47d..00000000000 --- a/drivers/media/dvb/frontends/dib3000mc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Driver for DiBcom DiB3000MC/P-demodulator. - * - * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/) - * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de) - * - * This code is partially based on the previous dib3000mc.c . - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#ifndef DIB3000MC_H -#define DIB3000MC_H - -#include "dibx000_common.h" - -struct dib3000mc_config { - struct dibx000_agc_config *agc; - - u8 phase_noise_mode; - u8 impulse_noise_mode; - - u8 pwm3_inversion; - u8 use_pwm3; - u16 pwm3_value; - - u16 max_time; - u16 ln_adc_level; - - u8 agc_command1 :1; - u8 agc_command2 :1; - - u8 mobile_mode; - - u8 output_mpeg2_in_188_bytes; -}; - -#define DEFAULT_DIB3000MC_I2C_ADDRESS 16 -#define DEFAULT_DIB3000P_I2C_ADDRESS 24 - -#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE)) -extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg); -#else -static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_DIB3000MC - -extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]); - -extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating); - -extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff); -extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff); - -extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *); - -#endif diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c deleted file mode 100644 index 0109720353b..00000000000 --- a/drivers/media/dvb/frontends/dib7000m.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's DiB7000M and - * first generation DiB7000P-demodulator-family. - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib7000m.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0) - -struct dib7000m_state { - struct dvb_frontend demod; - struct dib7000m_config cfg; - - u8 i2c_addr; - struct i2c_adapter *i2c_adap; - - struct dibx000_i2c_master i2c_master; - -/* offset is 1 in case of the 7000MC */ - u8 reg_offs; - - u16 wbd_ref; - - u8 current_band; - fe_bandwidth_t current_bandwidth; - struct dibx000_agc_config *current_agc; - u32 timf; - u32 timf_default; - u32 internal_clk; - - u8 div_force_off : 1; - u8 div_state : 1; - u16 div_sync_wait; - - u16 revision; - - u8 agc_state; -}; - -enum dib7000m_power_mode { - DIB7000M_POWER_ALL = 0, - - DIB7000M_POWER_NO, - DIB7000M_POWER_INTERF_ANALOG_AGC, - DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD, - DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD, - DIB7000M_POWER_INTERFACE_ONLY, -}; - -static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) -{ - u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c_adap, msg, 2) != 2) - dprintk("i2c read error on %d",reg); - - return (rb[0] << 8) | rb[1]; -} - -static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} -static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) -{ - u16 l = 0, r, *n; - n = buf; - l = *n++; - while (l) { - r = *n++; - - if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC - r++; - - do { - dib7000m_write_word(state, r, *n++); - r++; - } while (--l); - l = *n++; - } -} - -static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode) -{ - int ret = 0; - u16 outreg, fifo_threshold, smo_mode, - sram = 0x0005; /* by default SRAM output is disabled */ - - outreg = 0; - fifo_threshold = 1792; - smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1); - - dprintk( "setting output mode for demod %p to %d", &state->demod, mode); - - switch (mode) { - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock - outreg = (1 << 10); /* 0x0400 */ - break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock - outreg = (1 << 10) | (1 << 6); /* 0x0440 */ - break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input - outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */ - break; - case OUTMODE_DIVERSITY: - if (state->cfg.hostbus_diversity) - outreg = (1 << 10) | (4 << 6); /* 0x0500 */ - else - sram |= 0x0c00; - break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding - smo_mode |= (3 << 1); - fifo_threshold = 512; - outreg = (1 << 10) | (5 << 6); - break; - case OUTMODE_HIGH_Z: // disable - outreg = 0; - break; - default: - dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); - break; - } - - if (state->cfg.output_mpeg2_in_188_bytes) - smo_mode |= (1 << 5) ; - - ret |= dib7000m_write_word(state, 294 + state->reg_offs, smo_mode); - ret |= dib7000m_write_word(state, 295 + state->reg_offs, fifo_threshold); /* synchronous fread */ - ret |= dib7000m_write_word(state, 1795, outreg); - ret |= dib7000m_write_word(state, 1805, sram); - - if (state->revision == 0x4003) { - u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd; - if (mode == OUTMODE_DIVERSITY) - clk_cfg1 |= (1 << 1); // P_O_CLK_en - dib7000m_write_word(state, 909, clk_cfg1); - } - return ret; -} - -static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode) -{ - /* by default everything is going to be powered off */ - u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff; - u8 offset = 0; - - /* now, depending on the requested mode, we power on */ - switch (mode) { - /* power up everything in the demod */ - case DIB7000M_POWER_ALL: - reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000; - break; - - /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */ - case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */ - reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)); - break; - - case DIB7000M_POWER_INTERF_ANALOG_AGC: - reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10)); - reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2)); - reg_906 &= ~((1 << 0)); - break; - - case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD: - reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000; - break; - - case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD: - reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000; - break; - case DIB7000M_POWER_NO: - break; - } - - /* always power down unused parts */ - if (!state->cfg.mobile_mode) - reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1); - - /* P_sdio_select_clk = 0 on MC and after*/ - if (state->revision != 0x4000) - reg_906 <<= 1; - - if (state->revision == 0x4003) - offset = 1; - - dib7000m_write_word(state, 903 + offset, reg_903); - dib7000m_write_word(state, 904 + offset, reg_904); - dib7000m_write_word(state, 905 + offset, reg_905); - dib7000m_write_word(state, 906 + offset, reg_906); -} - -static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no) -{ - int ret = 0; - u16 reg_913 = dib7000m_read_word(state, 913), - reg_914 = dib7000m_read_word(state, 914); - - switch (no) { - case DIBX000_SLOW_ADC_ON: - reg_914 |= (1 << 1) | (1 << 0); - ret |= dib7000m_write_word(state, 914, reg_914); - reg_914 &= ~(1 << 1); - break; - - case DIBX000_SLOW_ADC_OFF: - reg_914 |= (1 << 1) | (1 << 0); - break; - - case DIBX000_ADC_ON: - if (state->revision == 0x4000) { // workaround for PA/MA - // power-up ADC - dib7000m_write_word(state, 913, 0); - dib7000m_write_word(state, 914, reg_914 & 0x3); - // power-down bandgag - dib7000m_write_word(state, 913, (1 << 15)); - dib7000m_write_word(state, 914, reg_914 & 0x3); - } - - reg_913 &= 0x0fff; - reg_914 &= 0x0003; - break; - - case DIBX000_ADC_OFF: // leave the VBG voltage on - reg_913 |= (1 << 14) | (1 << 13) | (1 << 12); - reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); - break; - - case DIBX000_VBG_ENABLE: - reg_913 &= ~(1 << 15); - break; - - case DIBX000_VBG_DISABLE: - reg_913 |= (1 << 15); - break; - - default: - break; - } - -// dprintk( "913: %x, 914: %x", reg_913, reg_914); - ret |= dib7000m_write_word(state, 913, reg_913); - ret |= dib7000m_write_word(state, 914, reg_914); - - return ret; -} - -static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw) -{ - u32 timf; - - // store the current bandwidth for later use - state->current_bandwidth = bw; - - if (state->timf == 0) { - dprintk( "using default timf"); - timf = state->timf_default; - } else { - dprintk( "using updated timf"); - timf = state->timf; - } - - timf = timf * (bw / 50) / 160; - - dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); - dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff)); - - return 0; -} - -static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff) -{ - struct dib7000m_state *state = demod->demodulator_priv; - - if (state->div_force_off) { - dprintk( "diversity combination deactivated - forced by COFDM parameters"); - onoff = 0; - } - state->div_state = (u8)onoff; - - if (onoff) { - dib7000m_write_word(state, 263 + state->reg_offs, 6); - dib7000m_write_word(state, 264 + state->reg_offs, 6); - dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); - } else { - dib7000m_write_word(state, 263 + state->reg_offs, 1); - dib7000m_write_word(state, 264 + state->reg_offs, 0); - dib7000m_write_word(state, 266 + state->reg_offs, 0); - } - - return 0; -} - -static int dib7000m_sad_calib(struct dib7000m_state *state) -{ - -/* internal */ -// dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth - dib7000m_write_word(state, 929, (0 << 1) | (0 << 0)); - dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096 - - /* do the calibration */ - dib7000m_write_word(state, 929, (1 << 0)); - dib7000m_write_word(state, 929, (0 << 0)); - - msleep(1); - - return 0; -} - -static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw) -{ - dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff)); - dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff)); - dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff)); - dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff)); - - dib7000m_write_word(state, 928, bw->sad_cfg); -} - -static void dib7000m_reset_pll(struct dib7000m_state *state) -{ - const struct dibx000_bandwidth_config *bw = state->cfg.bw; - u16 reg_907,reg_910; - - /* default */ - reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) | - (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | - (bw->enable_refdiv << 1) | (0 << 0); - reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset; - - // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value) - // this is only working only for 30 MHz crystals - if (!state->cfg.quartz_direct) { - reg_910 |= (1 << 5); // forcing the predivider to 1 - - // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2) - if(state->cfg.input_clk_is_div_2) - reg_907 |= (16 << 9); - else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary - reg_907 |= (8 << 9); - } else { - reg_907 |= (bw->pll_ratio & 0x3f) << 9; - reg_910 |= (bw->pll_prediv << 5); - } - - dib7000m_write_word(state, 910, reg_910); // pll cfg - dib7000m_write_word(state, 907, reg_907); // clk cfg0 - dib7000m_write_word(state, 908, 0x0006); // clk_cfg1 - - dib7000m_reset_pll_common(state, bw); -} - -static void dib7000mc_reset_pll(struct dib7000m_state *state) -{ - const struct dibx000_bandwidth_config *bw = state->cfg.bw; - u16 clk_cfg1; - - // clk_cfg0 - dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0)); - - // clk_cfg1 - //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) | - clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) | - (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) | - (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0); - dib7000m_write_word(state, 908, clk_cfg1); - clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3); - dib7000m_write_word(state, 908, clk_cfg1); - - // smpl_cfg - dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7)); - - dib7000m_reset_pll_common(state, bw); -} - -static int dib7000m_reset_gpio(struct dib7000m_state *st) -{ - /* reset the GPIOs */ - dib7000m_write_word(st, 773, st->cfg.gpio_dir); - dib7000m_write_word(st, 774, st->cfg.gpio_val); - - /* TODO 782 is P_gpio_od */ - - dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos); - - dib7000m_write_word(st, 780, st->cfg.pwm_freq_div); - return 0; -} - -static u16 dib7000m_defaults_common[] = - -{ - // auto search configuration - 3, 2, - 0x0004, - 0x1000, - 0x0814, - - 12, 6, - 0x001b, - 0x7740, - 0x005b, - 0x8d80, - 0x01c9, - 0xc380, - 0x0000, - 0x0080, - 0x0000, - 0x0090, - 0x0001, - 0xd4c0, - - 1, 26, - 0x6680, // P_corm_thres Lock algorithms configuration - - 1, 170, - 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on - - 8, 173, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - 1, 182, - 8192, // P_fft_nb_to_cut - - 2, 195, - 0x0ccd, // P_pha3_thres - 0, // P_cti_use_cpe, P_cti_use_prog - - 1, 205, - 0x200f, // P_cspu_regul, P_cspu_win_cut - - 5, 214, - 0x023d, // P_adp_regul_cnt - 0x00a4, // P_adp_noise_cnt - 0x00a4, // P_adp_regul_ext - 0x7ff0, // P_adp_noise_ext - 0x3ccc, // P_adp_fil - - 1, 226, - 0, // P_2d_byp_ti_num - - 1, 255, - 0x800, // P_equal_thres_wgn - - 1, 263, - 0x0001, - - 1, 281, - 0x0010, // P_fec_* - - 1, 294, - 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard - - 0 -}; - -static u16 dib7000m_defaults[] = - -{ - /* set ADC level to -16 */ - 11, 76, - (1 << 13) - 825 - 117, - (1 << 13) - 837 - 117, - (1 << 13) - 811 - 117, - (1 << 13) - 766 - 117, - (1 << 13) - 737 - 117, - (1 << 13) - 693 - 117, - (1 << 13) - 648 - 117, - (1 << 13) - 619 - 117, - (1 << 13) - 575 - 117, - (1 << 13) - 531 - 117, - (1 << 13) - 501 - 117, - - // Tuner IO bank: max drive (14mA) - 1, 912, - 0x2c8a, - - 1, 1817, - 1, - - 0, -}; - -static int dib7000m_demod_reset(struct dib7000m_state *state) -{ - dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); - - /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */ - dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE); - - /* restart all parts */ - dib7000m_write_word(state, 898, 0xffff); - dib7000m_write_word(state, 899, 0xffff); - dib7000m_write_word(state, 900, 0xff0f); - dib7000m_write_word(state, 901, 0xfffc); - - dib7000m_write_word(state, 898, 0); - dib7000m_write_word(state, 899, 0); - dib7000m_write_word(state, 900, 0); - dib7000m_write_word(state, 901, 0); - - if (state->revision == 0x4000) - dib7000m_reset_pll(state); - else - dib7000mc_reset_pll(state); - - if (dib7000m_reset_gpio(state) != 0) - dprintk( "GPIO reset was not successful."); - - if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0) - dprintk( "OUTPUT_MODE could not be reset."); - - /* unforce divstr regardless whether i2c enumeration was done or not */ - dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) ); - - dib7000m_set_bandwidth(state, 8000); - - dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON); - dib7000m_sad_calib(state); - dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF); - - if (state->cfg.dvbt_mode) - dib7000m_write_word(state, 1796, 0x0); // select DVB-T output - - if (state->cfg.mobile_mode) - dib7000m_write_word(state, 261 + state->reg_offs, 2); - else - dib7000m_write_word(state, 224 + state->reg_offs, 1); - - // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ... - if(state->cfg.tuner_is_baseband) - dib7000m_write_word(state, 36, 0x0755); - else - dib7000m_write_word(state, 36, 0x1f55); - - // P_divclksel=3 P_divbitsel=1 - if (state->revision == 0x4000) - dib7000m_write_word(state, 909, (3 << 10) | (1 << 6)); - else - dib7000m_write_word(state, 909, (3 << 4) | 1); - - dib7000m_write_tab(state, dib7000m_defaults_common); - dib7000m_write_tab(state, dib7000m_defaults); - - dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY); - - state->internal_clk = state->cfg.bw->internal; - - return 0; -} - -static void dib7000m_restart_agc(struct dib7000m_state *state) -{ - // P_restart_iqc & P_restart_agc - dib7000m_write_word(state, 898, 0x0c00); - dib7000m_write_word(state, 898, 0x0000); -} - -static int dib7000m_agc_soft_split(struct dib7000m_state *state) -{ - u16 agc,split_offset; - - if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0) - return 0; - - // n_agc_global - agc = dib7000m_read_word(state, 390); - - if (agc > state->current_agc->split.min_thres) - split_offset = state->current_agc->split.min; - else if (agc < state->current_agc->split.max_thres) - split_offset = state->current_agc->split.max; - else - split_offset = state->current_agc->split.max * - (agc - state->current_agc->split.min_thres) / - (state->current_agc->split.max_thres - state->current_agc->split.min_thres); - - dprintk( "AGC split_offset: %d",split_offset); - - // P_agc_force_split and P_agc_split_offset - return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset); -} - -static int dib7000m_update_lna(struct dib7000m_state *state) -{ - u16 dyn_gain; - - if (state->cfg.update_lna) { - // read dyn_gain here (because it is demod-dependent and not fe) - dyn_gain = dib7000m_read_word(state, 390); - - if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed - dib7000m_restart_agc(state); - return 1; - } - } - return 0; -} - -static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band) -{ - struct dibx000_agc_config *agc = NULL; - int i; - if (state->current_band == band && state->current_agc != NULL) - return 0; - state->current_band = band; - - for (i = 0; i < state->cfg.agc_config_count; i++) - if (state->cfg.agc[i].band_caps & band) { - agc = &state->cfg.agc[i]; - break; - } - - if (agc == NULL) { - dprintk( "no valid AGC configuration found for band 0x%02x",band); - return -EINVAL; - } - - state->current_agc = agc; - - /* AGC */ - dib7000m_write_word(state, 72 , agc->setup); - dib7000m_write_word(state, 73 , agc->inv_gain); - dib7000m_write_word(state, 74 , agc->time_stabiliz); - dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock); - - // Demod AGC loop configuration - dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp); - dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp); - - dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", - state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); - - /* AGC continued */ - if (state->wbd_ref != 0) - dib7000m_write_word(state, 102, state->wbd_ref); - else // use default - dib7000m_write_word(state, 102, agc->wbd_ref); - - dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) ); - dib7000m_write_word(state, 104, agc->agc1_max); - dib7000m_write_word(state, 105, agc->agc1_min); - dib7000m_write_word(state, 106, agc->agc2_max); - dib7000m_write_word(state, 107, agc->agc2_min); - dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 ); - dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2); - dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2); - dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2); - - if (state->revision > 0x4000) { // settings for the MC - dib7000m_write_word(state, 71, agc->agc1_pt3); -// dprintk( "929: %x %d %d", -// (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel); - dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); - } else { - // wrong default values - u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 }; - for (i = 0; i < 9; i++) - dib7000m_write_word(state, 88 + i, b[i]); - } - return 0; -} - -static void dib7000m_update_timf(struct dib7000m_state *state) -{ - u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437); - state->timf = timf * 160 / (state->current_bandwidth / 50); - dib7000m_write_word(state, 23, (u16) (timf >> 16)); - dib7000m_write_word(state, 24, (u16) (timf & 0xffff)); - dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default); -} - -static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000m_state *state = demod->demodulator_priv; - u16 cfg_72 = dib7000m_read_word(state, 72); - int ret = -1; - u8 *agc_state = &state->agc_state; - u8 agc_split; - - switch (state->agc_state) { - case 0: - // set power-up level: interf+analog+AGC - dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC); - dib7000m_set_adc_state(state, DIBX000_ADC_ON); - - if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0) - return -1; - - ret = 7; /* ADC power up */ - (*agc_state)++; - break; - - case 1: - /* AGC initialization */ - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 1); - - dib7000m_write_word(state, 75, 32768); - if (!state->current_agc->perform_agc_softsplit) { - /* we are using the wbd - so slow AGC startup */ - dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */ - (*agc_state)++; - ret = 5; - } else { - /* default AGC startup */ - (*agc_state) = 4; - /* wait AGC rough lock time */ - ret = 7; - } - - dib7000m_restart_agc(state); - break; - - case 2: /* fast split search path after 5sec */ - dib7000m_write_word(state, 72, cfg_72 | (1 << 4)); /* freeze AGC loop */ - dib7000m_write_word(state, 103, 2 << 9); /* fast split search 0.25kHz */ - (*agc_state)++; - ret = 14; - break; - - case 3: /* split search ended */ - agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */ - dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */ - - dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4)); /* std AGC loop */ - dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ - - dib7000m_restart_agc(state); - - dprintk( "SPLIT %p: %hd", demod, agc_split); - - (*agc_state)++; - ret = 5; - break; - - case 4: /* LNA startup */ - /* wait AGC accurate lock time */ - ret = 7; - - if (dib7000m_update_lna(state)) - // wait only AGC rough lock time - ret = 5; - else - (*agc_state)++; - break; - - case 5: - dib7000m_agc_soft_split(state); - - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 0); - - (*agc_state)++; - break; - - default: - break; - } - return ret; -} - -static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq) -{ - u16 value, est[4]; - - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - - /* nfft, guard, qam, alpha */ - value = 0; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (0 << 7); break; - case /* 4K MODE */ 255: value |= (2 << 7); break; - default: - case TRANSMISSION_MODE_8K: value |= (1 << 7); break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: value |= (0 << 5); break; - case GUARD_INTERVAL_1_16: value |= (1 << 5); break; - case GUARD_INTERVAL_1_4: value |= (3 << 5); break; - default: - case GUARD_INTERVAL_1_8: value |= (2 << 5); break; - } - switch (ch->u.ofdm.constellation) { - case QPSK: value |= (0 << 3); break; - case QAM_16: value |= (1 << 3); break; - default: - case QAM_64: value |= (2 << 3); break; - } - switch (HIERARCHY_1) { - case HIERARCHY_2: value |= 2; break; - case HIERARCHY_4: value |= 4; break; - default: - case HIERARCHY_1: value |= 1; break; - } - dib7000m_write_word(state, 0, value); - dib7000m_write_word(state, 5, (seq << 4)); - - /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ - value = 0; - if (1 != 0) - value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) - value |= (1 << 4); - if (1 == 1) - value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { - case FEC_2_3: value |= (2 << 1); break; - case FEC_3_4: value |= (3 << 1); break; - case FEC_5_6: value |= (5 << 1); break; - case FEC_7_8: value |= (7 << 1); break; - default: - case FEC_1_2: value |= (1 << 1); break; - } - dib7000m_write_word(state, 267 + state->reg_offs, value); - - /* offset loop parameters */ - - /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */ - dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80); - - /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3)); - - /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */ - dib7000m_write_word(state, 32, (0 << 4) | 0x3); - - /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */ - dib7000m_write_word(state, 33, (0 << 4) | 0x5); - - /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: value = 256; break; - case /* 4K MODE */ 255: value = 128; break; - case TRANSMISSION_MODE_2K: - default: value = 64; break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: value *= 2; break; - case GUARD_INTERVAL_1_8: value *= 4; break; - case GUARD_INTERVAL_1_4: value *= 8; break; - default: - case GUARD_INTERVAL_1_32: value *= 1; break; - } - state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO - - /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */ - /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ - if (1 == 1 || state->revision > 0x4000) - state->div_force_off = 0; - else - state->div_force_off = 1; - dib7000m_set_diversity_in(&state->demod, state->div_state); - - /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { - case QAM_64: - est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ - est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ - break; - case QAM_16: - est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ - est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ - break; - default: - est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ - est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ - est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ - break; - } - for (value = 0; value < 4; value++) - dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]); - - // set power-up level: autosearch - dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD); -} - -static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000m_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; - int ret = 0; - u32 value, factor; - - schan = *ch; - - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; - - dib7000m_set_channel(state, &schan, 7); - - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else - factor = 6; - - // always use the setting for 8MHz here lock_time for 7,6 MHz are longer - value = 30 * state->internal_clk * factor; - ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time - ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time - value = 100 * state->internal_clk * factor; - ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time - ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time - value = 500 * state->internal_clk * factor; - ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time - ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time - - // start search - value = dib7000m_read_word(state, 0); - ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9))); - - /* clear n_irq_pending */ - if (state->revision == 0x4000) - dib7000m_write_word(state, 1793, 0); - else - dib7000m_read_word(state, 537); - - ret |= dib7000m_write_word(state, 0, (u16) value); - - return ret; -} - -static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg) -{ - u16 irq_pending = dib7000m_read_word(state, reg); - - if (irq_pending & 0x1) { // failed - dprintk( "autosearch failed"); - return 1; - } - - if (irq_pending & 0x2) { // succeeded - dprintk( "autosearch succeeded"); - return 2; - } - return 0; // still pending -} - -static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod) -{ - struct dib7000m_state *state = demod->demodulator_priv; - if (state->revision == 0x4000) - return dib7000m_autosearch_irq(state, 1793); - else - return dib7000m_autosearch_irq(state, 537); -} - -static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000m_state *state = demod->demodulator_priv; - int ret = 0; - u16 value; - - // we are already tuned - just resuming from suspend - if (ch != NULL) - dib7000m_set_channel(state, ch, 0); - else - return -EINVAL; - - // restart demod - ret |= dib7000m_write_word(state, 898, 0x4000); - ret |= dib7000m_write_word(state, 898, 0x0000); - msleep(45); - - dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD); - /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3)); - - // never achieved a lock before - wait for timfreq to update - if (state->timf == 0) - msleep(200); - - //dump_reg(state); - /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ - value = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (7 << 12); break; - case /* 4K MODE */ 255: value |= (8 << 12); break; - default: - case TRANSMISSION_MODE_8K: value |= (9 << 12); break; - } - ret |= dib7000m_write_word(state, 26, value); - - /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ - value = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= 0x6; break; - case /* 4K MODE */ 255: value |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: value |= 0x8; break; - } - ret |= dib7000m_write_word(state, 32, value); - - /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ - value = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= 0x6; break; - case /* 4K MODE */ 255: value |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: value |= 0x8; break; - } - ret |= dib7000m_write_word(state, 33, value); - - // we achieved a lock - it's time to update the timf freq - if ((dib7000m_read_word(state, 535) >> 6) & 0x1) - dib7000m_update_timf(state); - - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - return ret; -} - -static int dib7000m_wakeup(struct dvb_frontend *demod) -{ - struct dib7000m_state *state = demod->demodulator_priv; - - dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); - - if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) - dprintk( "could not start Slow ADC"); - - return 0; -} - -static int dib7000m_sleep(struct dvb_frontend *demod) -{ - struct dib7000m_state *st = demod->demodulator_priv; - dib7000m_set_output_mode(st, OUTMODE_HIGH_Z); - dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY); - return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | - dib7000m_set_adc_state(st, DIBX000_ADC_OFF); -} - -static int dib7000m_identify(struct dib7000m_state *state) -{ - u16 value; - - if ((value = dib7000m_read_word(state, 896)) != 0x01b3) { - dprintk( "wrong Vendor ID (0x%x)",value); - return -EREMOTEIO; - } - - state->revision = dib7000m_read_word(state, 897); - if (state->revision != 0x4000 && - state->revision != 0x4001 && - state->revision != 0x4002 && - state->revision != 0x4003) { - dprintk( "wrong Device ID (0x%x)",value); - return -EREMOTEIO; - } - - /* protect this driver to be used with 7000PC */ - if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) { - dprintk( "this driver does not work with DiB7000PC"); - return -EREMOTEIO; - } - - switch (state->revision) { - case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break; - case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break; - case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break; - case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break; - } - - return 0; -} - - -static int dib7000m_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000m_state *state = fe->demodulator_priv; - u16 tps = dib7000m_read_word(state,480); - - fep->inversion = INVERSION_AUTO; - - fep->u.ofdm.bandwidth = state->current_bandwidth; - - switch ((tps >> 8) & 0x3) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ - } - - switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; - } - - switch ((tps >> 14) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; - case 2: - default: fep->u.ofdm.constellation = QAM_64; break; - } - - /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ - /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; - - } - - switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; - } - - /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */ - - return 0; -} - -static int dib7000m_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000m_state *state = fe->demodulator_priv; - int time, ret; - - dib7000m_set_output_mode(state, OUTMODE_HIGH_Z); - - state->current_bandwidth = fep->u.ofdm.bandwidth; - dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth)); - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, fep); - - /* start up the AGC */ - state->agc_state = 0; - do { - time = dib7000m_agc_startup(fe, fep); - if (time != -1) - msleep(time); - } while (time != -1); - - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 800, found; - - dib7000m_autosearch_start(fe, fep); - do { - msleep(1); - found = dib7000m_autosearch_is_irq(fe); - } while (found == 0 && i--); - - dprintk("autosearch returns: %d",found); - if (found == 0 || found == 1) - return 0; // no channel found - - dib7000m_get_frontend(fe, fep); - } - - ret = dib7000m_tune(fe, fep); - - /* make this a config parameter */ - dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO); - return ret; -} - -static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct dib7000m_state *state = fe->demodulator_priv; - u16 lock = dib7000m_read_word(state, 535); - - *stat = 0; - - if (lock & 0x8000) - *stat |= FE_HAS_SIGNAL; - if (lock & 0x3000) - *stat |= FE_HAS_CARRIER; - if (lock & 0x0100) - *stat |= FE_HAS_VITERBI; - if (lock & 0x0010) - *stat |= FE_HAS_SYNC; - if (lock & 0x0008) - *stat |= FE_HAS_LOCK; - - return 0; -} - -static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct dib7000m_state *state = fe->demodulator_priv; - *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527); - return 0; -} - -static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct dib7000m_state *state = fe->demodulator_priv; - *unc = dib7000m_read_word(state, 534); - return 0; -} - -static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dib7000m_state *state = fe->demodulator_priv; - u16 val = dib7000m_read_word(state, 390); - *strength = 65535 - val; - return 0; -} - -static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - *snr = 0x0000; - return 0; -} - -static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void dib7000m_release(struct dvb_frontend *demod) -{ - struct dib7000m_state *st = demod->demodulator_priv; - dibx000_exit_i2c_master(&st->i2c_master); - kfree(st); -} - -struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) -{ - struct dib7000m_state *st = demod->demodulator_priv; - return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); -} -EXPORT_SYMBOL(dib7000m_get_i2c_master); - -#if 0 -/* used with some prototype boards */ -int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, - u8 default_addr, struct dib7000m_config cfg[]) -{ - struct dib7000m_state st = { .i2c_adap = i2c }; - int k = 0; - u8 new_addr = 0; - - for (k = no_of_demods-1; k >= 0; k--) { - st.cfg = cfg[k]; - - /* designated i2c address */ - new_addr = (0x40 + k) << 1; - st.i2c_addr = new_addr; - if (dib7000m_identify(&st) != 0) { - st.i2c_addr = default_addr; - if (dib7000m_identify(&st) != 0) { - dprintk("DiB7000M #%d: not identified", k); - return -EIO; - } - } - - /* start diversity to pull_down div_str - just for i2c-enumeration */ - dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY); - - dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output - - /* set new i2c address and force divstart */ - dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2); - - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); - } - - for (k = 0; k < no_of_demods; k++) { - st.cfg = cfg[k]; - st.i2c_addr = (0x40 + k) << 1; - - // unforce divstr - dib7000m_write_word(&st,1794, st.i2c_addr << 2); - - /* deactivate div - it was just for i2c-enumeration */ - dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z); - } - - return 0; -} -EXPORT_SYMBOL(dib7000m_i2c_enumeration); -#endif - -static struct dvb_frontend_ops dib7000m_ops; -struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) -{ - struct dvb_frontend *demod; - struct dib7000m_state *st; - st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL); - if (st == NULL) - return NULL; - - memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config)); - st->i2c_adap = i2c_adap; - st->i2c_addr = i2c_addr; - - demod = &st->demod; - demod->demodulator_priv = st; - memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops)); - - st->timf_default = cfg->bw->timf; - - if (dib7000m_identify(st) != 0) - goto error; - - if (st->revision == 0x4000) - dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr); - else - dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr); - - dib7000m_demod_reset(st); - - return demod; - -error: - kfree(st); - return NULL; -} -EXPORT_SYMBOL(dib7000m_attach); - -static struct dvb_frontend_ops dib7000m_ops = { - .info = { - .name = "DiBcom 7000MA/MB/PA/PB/MC", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib7000m_release, - - .init = dib7000m_wakeup, - .sleep = dib7000m_sleep, - - .set_frontend = dib7000m_set_frontend, - .get_tune_settings = dib7000m_fe_get_tune_settings, - .get_frontend = dib7000m_get_frontend, - - .read_status = dib7000m_read_status, - .read_ber = dib7000m_read_ber, - .read_signal_strength = dib7000m_read_signal_strength, - .read_snr = dib7000m_read_snr, - .read_ucblocks = dib7000m_read_unc_blocks, -}; - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h deleted file mode 100644 index 597e9cc2da6..00000000000 --- a/drivers/media/dvb/frontends/dib7000m.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef DIB7000M_H -#define DIB7000M_H - -#include "dibx000_common.h" - -struct dib7000m_config { - u8 dvbt_mode; - u8 output_mpeg2_in_188_bytes; - u8 hostbus_diversity; - u8 tuner_is_baseband; - u8 mobile_mode; - int (*update_lna) (struct dvb_frontend *, u16 agc_global); - - u8 agc_config_count; - struct dibx000_agc_config *agc; - - struct dibx000_bandwidth_config *bw; - -#define DIB7000M_GPIO_DEFAULT_DIRECTIONS 0xffff - u16 gpio_dir; -#define DIB7000M_GPIO_DEFAULT_VALUES 0x0000 - u16 gpio_val; -#define DIB7000M_GPIO_PWM_POS0(v) ((v & 0xf) << 12) -#define DIB7000M_GPIO_PWM_POS1(v) ((v & 0xf) << 8 ) -#define DIB7000M_GPIO_PWM_POS2(v) ((v & 0xf) << 4 ) -#define DIB7000M_GPIO_PWM_POS3(v) (v & 0xf) -#define DIB7000M_GPIO_DEFAULT_PWM_POS 0xffff - u16 gpio_pwm_pos; - - u16 pwm_freq_div; - - u8 quartz_direct; - - u8 input_clk_is_div_2; - - int (*agc_control) (struct dvb_frontend *, u8 before); -}; - -#define DEFAULT_DIB7000M_I2C_ADDRESS 18 - -extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg); -extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); - -/* TODO -extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val); -extern INT dib7000m_enable_vbg_voltage(struct dibDemod *demod); -extern void dib7000m_set_hostbus_diversity(struct dibDemod *demod, UCHAR onoff); -extern USHORT dib7000m_get_current_agc_global(struct dibDemod *demod); -*/ - -#endif diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c deleted file mode 100644 index 8217e5b38f4..00000000000 --- a/drivers/media/dvb/frontends/dib7000p.c +++ /dev/null @@ -1,1394 +0,0 @@ -/* - * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC). - * - * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ -#include <linux/kernel.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "dib7000p.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -static int buggy_sfn_workaround; -module_param(buggy_sfn_workaround, int, 0644); -MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) - -struct dib7000p_state { - struct dvb_frontend demod; - struct dib7000p_config cfg; - - u8 i2c_addr; - struct i2c_adapter *i2c_adap; - - struct dibx000_i2c_master i2c_master; - - u16 wbd_ref; - - u8 current_band; - u32 current_bandwidth; - struct dibx000_agc_config *current_agc; - u32 timf; - - u8 div_force_off : 1; - u8 div_state : 1; - u16 div_sync_wait; - - u8 agc_state; - - u16 gpio_dir; - u16 gpio_val; - - u8 sfn_workaround_active :1; -}; - -enum dib7000p_power_mode { - DIB7000P_POWER_ALL = 0, - DIB7000P_POWER_ANALOG_ADC, - DIB7000P_POWER_INTERFACE_ONLY, -}; - -static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) -{ - u8 wb[2] = { reg >> 8, reg & 0xff }; - u8 rb[2]; - struct i2c_msg msg[2] = { - { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, - { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, - }; - - if (i2c_transfer(state->i2c_adap, msg, 2) != 2) - dprintk("i2c read error on %d",reg); - - return (rb[0] << 8) | rb[1]; -} - -static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} -static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf) -{ - u16 l = 0, r, *n; - n = buf; - l = *n++; - while (l) { - r = *n++; - - do { - dib7000p_write_word(state, r, *n++); - r++; - } while (--l); - l = *n++; - } -} - -static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) -{ - int ret = 0; - u16 outreg, fifo_threshold, smo_mode; - - outreg = 0; - fifo_threshold = 1792; - smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1); - - dprintk( "setting output mode for demod %p to %d", - &state->demod, mode); - - switch (mode) { - case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock - outreg = (1 << 10); /* 0x0400 */ - break; - case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock - outreg = (1 << 10) | (1 << 6); /* 0x0440 */ - break; - case OUTMODE_MPEG2_SERIAL: // STBs with serial input - outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */ - break; - case OUTMODE_DIVERSITY: - if (state->cfg.hostbus_diversity) - outreg = (1 << 10) | (4 << 6); /* 0x0500 */ - else - outreg = (1 << 11); - break; - case OUTMODE_MPEG2_FIFO: // e.g. USB feeding - smo_mode |= (3 << 1); - fifo_threshold = 512; - outreg = (1 << 10) | (5 << 6); - break; - case OUTMODE_ANALOG_ADC: - outreg = (1 << 10) | (3 << 6); - break; - case OUTMODE_HIGH_Z: // disable - outreg = 0; - break; - default: - dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); - break; - } - - if (state->cfg.output_mpeg2_in_188_bytes) - smo_mode |= (1 << 5) ; - - ret |= dib7000p_write_word(state, 235, smo_mode); - ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ - ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */ - - return ret; -} - -static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff) -{ - struct dib7000p_state *state = demod->demodulator_priv; - - if (state->div_force_off) { - dprintk( "diversity combination deactivated - forced by COFDM parameters"); - onoff = 0; - } - state->div_state = (u8)onoff; - - if (onoff) { - dib7000p_write_word(state, 204, 6); - dib7000p_write_word(state, 205, 16); - /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ - dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); - } else { - dib7000p_write_word(state, 204, 1); - dib7000p_write_word(state, 205, 0); - dib7000p_write_word(state, 207, 0); - } - - return 0; -} - -static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) -{ - /* by default everything is powered off */ - u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, - reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff); - - /* now, depending on the requested mode, we power on */ - switch (mode) { - /* power up everything in the demod */ - case DIB7000P_POWER_ALL: - reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff; - break; - - case DIB7000P_POWER_ANALOG_ADC: - /* dem, cfg, iqc, sad, agc */ - reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9)); - /* nud */ - reg_776 &= ~((1 << 0)); - /* Dout */ - reg_1280 &= ~((1 << 11)); - /* fall through wanted to enable the interfaces */ - - /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ - case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */ - reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); - break; - -/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ - } - - dib7000p_write_word(state, 774, reg_774); - dib7000p_write_word(state, 775, reg_775); - dib7000p_write_word(state, 776, reg_776); - dib7000p_write_word(state, 899, reg_899); - dib7000p_write_word(state, 1280, reg_1280); - - return 0; -} - -static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) -{ - u16 reg_908 = dib7000p_read_word(state, 908), - reg_909 = dib7000p_read_word(state, 909); - - switch (no) { - case DIBX000_SLOW_ADC_ON: - reg_909 |= (1 << 1) | (1 << 0); - dib7000p_write_word(state, 909, reg_909); - reg_909 &= ~(1 << 1); - break; - - case DIBX000_SLOW_ADC_OFF: - reg_909 |= (1 << 1) | (1 << 0); - break; - - case DIBX000_ADC_ON: - reg_908 &= 0x0fff; - reg_909 &= 0x0003; - break; - - case DIBX000_ADC_OFF: // leave the VBG voltage on - reg_908 |= (1 << 14) | (1 << 13) | (1 << 12); - reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); - break; - - case DIBX000_VBG_ENABLE: - reg_908 &= ~(1 << 15); - break; - - case DIBX000_VBG_DISABLE: - reg_908 |= (1 << 15); - break; - - default: - break; - } - -// dprintk( "908: %x, 909: %x\n", reg_908, reg_909); - - dib7000p_write_word(state, 908, reg_908); - dib7000p_write_word(state, 909, reg_909); -} - -static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw) -{ - u32 timf; - - // store the current bandwidth for later use - state->current_bandwidth = bw; - - if (state->timf == 0) { - dprintk( "using default timf"); - timf = state->cfg.bw->timf; - } else { - dprintk( "using updated timf"); - timf = state->timf; - } - - timf = timf * (bw / 50) / 160; - - dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); - dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff)); - - return 0; -} - -static int dib7000p_sad_calib(struct dib7000p_state *state) -{ -/* internal */ -// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth - dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); - dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096 - - /* do the calibration */ - dib7000p_write_word(state, 73, (1 << 0)); - dib7000p_write_word(state, 73, (0 << 0)); - - msleep(1); - - return 0; -} - -int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value) -{ - struct dib7000p_state *state = demod->demodulator_priv; - if (value > 4095) - value = 4095; - state->wbd_ref = value; - return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value); -} - -EXPORT_SYMBOL(dib7000p_set_wbd_ref); -static void dib7000p_reset_pll(struct dib7000p_state *state) -{ - struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; - u16 clk_cfg0; - - /* force PLL bypass */ - clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) | - (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | - (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0); - - dib7000p_write_word(state, 900, clk_cfg0); - - /* P_pll_cfg */ - dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); - clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff); - dib7000p_write_word(state, 900, clk_cfg0); - - dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff)); - dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff)); - dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff)); - dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff)); - - dib7000p_write_word(state, 72, bw->sad_cfg); -} - -static int dib7000p_reset_gpio(struct dib7000p_state *st) -{ - /* reset the GPIOs */ - dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos); - - dib7000p_write_word(st, 1029, st->gpio_dir); - dib7000p_write_word(st, 1030, st->gpio_val); - - /* TODO 1031 is P_gpio_od */ - - dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos); - - dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div); - return 0; -} - -static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val) -{ - st->gpio_dir = dib7000p_read_word(st, 1029); - st->gpio_dir &= ~(1 << num); /* reset the direction bit */ - st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ - dib7000p_write_word(st, 1029, st->gpio_dir); - - st->gpio_val = dib7000p_read_word(st, 1030); - st->gpio_val &= ~(1 << num); /* reset the direction bit */ - st->gpio_val |= (val & 0x01) << num; /* set the new value */ - dib7000p_write_word(st, 1030, st->gpio_val); - - return 0; -} - -int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val) -{ - struct dib7000p_state *state = demod->demodulator_priv; - return dib7000p_cfg_gpio(state, num, dir, val); -} - -EXPORT_SYMBOL(dib7000p_set_gpio); -static u16 dib7000p_defaults[] = - -{ - // auto search configuration - 3, 2, - 0x0004, - 0x1000, - 0x0814, /* Equal Lock */ - - 12, 6, - 0x001b, - 0x7740, - 0x005b, - 0x8d80, - 0x01c9, - 0xc380, - 0x0000, - 0x0080, - 0x0000, - 0x0090, - 0x0001, - 0xd4c0, - - 1, 26, - 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26 - - /* set ADC level to -16 */ - 11, 79, - (1 << 13) - 825 - 117, - (1 << 13) - 837 - 117, - (1 << 13) - 811 - 117, - (1 << 13) - 766 - 117, - (1 << 13) - 737 - 117, - (1 << 13) - 693 - 117, - (1 << 13) - 648 - 117, - (1 << 13) - 619 - 117, - (1 << 13) - 575 - 117, - (1 << 13) - 531 - 117, - (1 << 13) - 501 - 117, - - 1, 142, - 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16 - - /* disable power smoothing */ - 8, 145, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - - 1, 154, - 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0 - - 1, 168, - 0x0ccd, // P_pha3_thres, default 0x3000 - -// 1, 169, -// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010 - - 1, 183, - 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005 - - 5, 187, - 0x023d, // P_adp_regul_cnt=573, default: 410 - 0x00a4, // P_adp_noise_cnt= - 0x00a4, // P_adp_regul_ext - 0x7ff0, // P_adp_noise_ext - 0x3ccc, // P_adp_fil - - 1, 198, - 0x800, // P_equal_thres_wgn - - 1, 222, - 0x0010, // P_fec_ber_rs_len=2 - - 1, 235, - 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard - - 2, 901, - 0x0006, // P_clk_cfg1 - (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1 - - 1, 905, - 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive - - 0, -}; - -static int dib7000p_demod_reset(struct dib7000p_state *state) -{ - dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); - - dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE); - - /* restart all parts */ - dib7000p_write_word(state, 770, 0xffff); - dib7000p_write_word(state, 771, 0xffff); - dib7000p_write_word(state, 772, 0x001f); - dib7000p_write_word(state, 898, 0x0003); - /* except i2c, sdio, gpio - control interfaces */ - dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) ); - - dib7000p_write_word(state, 770, 0); - dib7000p_write_word(state, 771, 0); - dib7000p_write_word(state, 772, 0); - dib7000p_write_word(state, 898, 0); - dib7000p_write_word(state, 1280, 0); - - /* default */ - dib7000p_reset_pll(state); - - if (dib7000p_reset_gpio(state) != 0) - dprintk( "GPIO reset was not successful."); - - if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) - dprintk( "OUTPUT_MODE could not be reset."); - - /* unforce divstr regardless whether i2c enumeration was done or not */ - dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) ); - - dib7000p_set_bandwidth(state, 8000); - - dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); - dib7000p_sad_calib(state); - dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF); - - // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ... - if(state->cfg.tuner_is_baseband) - dib7000p_write_word(state, 36,0x0755); - else - dib7000p_write_word(state, 36,0x1f55); - - dib7000p_write_tab(state, dib7000p_defaults); - - dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); - - - return 0; -} - -static void dib7000p_pll_clk_cfg(struct dib7000p_state *state) -{ - u16 tmp = 0; - tmp = dib7000p_read_word(state, 903); - dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll - tmp = dib7000p_read_word(state, 900); - dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock -} - -static void dib7000p_restart_agc(struct dib7000p_state *state) -{ - // P_restart_iqc & P_restart_agc - dib7000p_write_word(state, 770, (1 << 11) | (1 << 9)); - dib7000p_write_word(state, 770, 0x0000); -} - -static int dib7000p_update_lna(struct dib7000p_state *state) -{ - u16 dyn_gain; - - // when there is no LNA to program return immediatly - if (state->cfg.update_lna) { - // read dyn_gain here (because it is demod-dependent and not fe) - dyn_gain = dib7000p_read_word(state, 394); - if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed - dib7000p_restart_agc(state); - return 1; - } - } - - return 0; -} - -static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band) -{ - struct dibx000_agc_config *agc = NULL; - int i; - if (state->current_band == band && state->current_agc != NULL) - return 0; - state->current_band = band; - - for (i = 0; i < state->cfg.agc_config_count; i++) - if (state->cfg.agc[i].band_caps & band) { - agc = &state->cfg.agc[i]; - break; - } - - if (agc == NULL) { - dprintk( "no valid AGC configuration found for band 0x%02x",band); - return -EINVAL; - } - - state->current_agc = agc; - - /* AGC */ - dib7000p_write_word(state, 75 , agc->setup ); - dib7000p_write_word(state, 76 , agc->inv_gain ); - dib7000p_write_word(state, 77 , agc->time_stabiliz ); - dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock); - - // Demod AGC loop configuration - dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp); - dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp); - - /* AGC continued */ - dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", - state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); - - if (state->wbd_ref != 0) - dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref); - else - dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref); - - dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); - - dib7000p_write_word(state, 107, agc->agc1_max); - dib7000p_write_word(state, 108, agc->agc1_min); - dib7000p_write_word(state, 109, agc->agc2_max); - dib7000p_write_word(state, 110, agc->agc2_min); - dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2); - dib7000p_write_word(state, 112, agc->agc1_pt3); - dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2); - dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2); - dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); - return 0; -} - -static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000p_state *state = demod->demodulator_priv; - int ret = -1; - u8 *agc_state = &state->agc_state; - u8 agc_split; - - switch (state->agc_state) { - case 0: - // set power-up level: interf+analog+AGC - dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); - dib7000p_set_adc_state(state, DIBX000_ADC_ON); - dib7000p_pll_clk_cfg(state); - - if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0) - return -1; - - ret = 7; - (*agc_state)++; - break; - - case 1: - // AGC initialization - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 1); - - dib7000p_write_word(state, 78, 32768); - if (!state->current_agc->perform_agc_softsplit) { - /* we are using the wbd - so slow AGC startup */ - /* force 0 split on WBD and restart AGC */ - dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8)); - (*agc_state)++; - ret = 5; - } else { - /* default AGC startup */ - (*agc_state) = 4; - /* wait AGC rough lock time */ - ret = 7; - } - - dib7000p_restart_agc(state); - break; - - case 2: /* fast split search path after 5sec */ - dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */ - dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */ - (*agc_state)++; - ret = 14; - break; - - case 3: /* split search ended */ - agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */ - dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */ - - dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */ - dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ - - dib7000p_restart_agc(state); - - dprintk( "SPLIT %p: %hd", demod, agc_split); - - (*agc_state)++; - ret = 5; - break; - - case 4: /* LNA startup */ - // wait AGC accurate lock time - ret = 7; - - if (dib7000p_update_lna(state)) - // wait only AGC rough lock time - ret = 5; - else // nothing was done, go to the next state - (*agc_state)++; - break; - - case 5: - if (state->cfg.agc_control) - state->cfg.agc_control(&state->demod, 0); - (*agc_state)++; - break; - default: - break; - } - return ret; -} - -static void dib7000p_update_timf(struct dib7000p_state *state) -{ - u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428); - state->timf = timf * 160 / (state->current_bandwidth / 50); - dib7000p_write_word(state, 23, (u16) (timf >> 16)); - dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); - dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf); - -} - -static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) -{ - u16 value, est[4]; - - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - - /* nfft, guard, qam, alpha */ - value = 0; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: value |= (0 << 7); break; - case /* 4K MODE */ 255: value |= (2 << 7); break; - default: - case TRANSMISSION_MODE_8K: value |= (1 << 7); break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: value |= (0 << 5); break; - case GUARD_INTERVAL_1_16: value |= (1 << 5); break; - case GUARD_INTERVAL_1_4: value |= (3 << 5); break; - default: - case GUARD_INTERVAL_1_8: value |= (2 << 5); break; - } - switch (ch->u.ofdm.constellation) { - case QPSK: value |= (0 << 3); break; - case QAM_16: value |= (1 << 3); break; - default: - case QAM_64: value |= (2 << 3); break; - } - switch (HIERARCHY_1) { - case HIERARCHY_2: value |= 2; break; - case HIERARCHY_4: value |= 4; break; - default: - case HIERARCHY_1: value |= 1; break; - } - dib7000p_write_word(state, 0, value); - dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ - - /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ - value = 0; - if (1 != 0) - value |= (1 << 6); - if (ch->u.ofdm.hierarchy_information == 1) - value |= (1 << 4); - if (1 == 1) - value |= 1; - switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { - case FEC_2_3: value |= (2 << 1); break; - case FEC_3_4: value |= (3 << 1); break; - case FEC_5_6: value |= (5 << 1); break; - case FEC_7_8: value |= (7 << 1); break; - default: - case FEC_1_2: value |= (1 << 1); break; - } - dib7000p_write_word(state, 208, value); - - /* offset loop parameters */ - dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) - dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) - dib7000p_write_word(state, 29, 0x1273); // isi - dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5) - - /* P_dvsy_sync_wait */ - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: value = 256; break; - case /* 4K MODE */ 255: value = 128; break; - case TRANSMISSION_MODE_2K: - default: value = 64; break; - } - switch (ch->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_16: value *= 2; break; - case GUARD_INTERVAL_1_8: value *= 4; break; - case GUARD_INTERVAL_1_4: value *= 8; break; - default: - case GUARD_INTERVAL_1_32: value *= 1; break; - } - state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO - - /* deactive the possibility of diversity reception if extended interleaver */ - state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; - dib7000p_set_diversity_in(&state->demod, state->div_state); - - /* channel estimation fine configuration */ - switch (ch->u.ofdm.constellation) { - case QAM_64: - est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ - est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ - break; - case QAM_16: - est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ - est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ - est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ - est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ - break; - default: - est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ - est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ - est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ - est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ - break; - } - for (value = 0; value < 4; value++) - dib7000p_write_word(state, 187 + value, est[value]); -} - -static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000p_state *state = demod->demodulator_priv; - struct dvb_frontend_parameters schan; - u32 value, factor; - - schan = *ch; - schan.u.ofdm.constellation = QAM_64; - schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - schan.u.ofdm.code_rate_HP = FEC_2_3; - schan.u.ofdm.code_rate_LP = FEC_3_4; - schan.u.ofdm.hierarchy_information = 0; - - dib7000p_set_channel(state, &schan, 7); - - factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth); - if (factor >= 5000) - factor = 1; - else - factor = 6; - - // always use the setting for 8MHz here lock_time for 7,6 MHz are longer - value = 30 * state->cfg.bw->internal * factor; - dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time - dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time - value = 100 * state->cfg.bw->internal * factor; - dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time - dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time - value = 500 * state->cfg.bw->internal * factor; - dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time - dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time - - value = dib7000p_read_word(state, 0); - dib7000p_write_word(state, 0, (u16) ((1 << 9) | value)); - dib7000p_read_word(state, 1284); - dib7000p_write_word(state, 0, (u16) value); - - return 0; -} - -static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod) -{ - struct dib7000p_state *state = demod->demodulator_priv; - u16 irq_pending = dib7000p_read_word(state, 1284); - - if (irq_pending & 0x1) // failed - return 1; - - if (irq_pending & 0x2) // succeeded - return 2; - - return 0; // still pending -} - -static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw) -{ - static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392}; - static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, - 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, - 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, - 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105, - 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126, - 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, - 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165, - 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224, - 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, - 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243, - 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249, - 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, - 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 255, 255, 255, 255}; - - u32 xtal = state->cfg.bw->xtal_hz / 1000; - int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz; - int k; - int coef_re[8],coef_im[8]; - int bw_khz = bw; - u32 pha; - - dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal); - - - if (f_rel < -bw_khz/2 || f_rel > bw_khz/2) - return; - - bw_khz /= 100; - - dib7000p_write_word(state, 142 ,0x0610); - - for (k = 0; k < 8; k++) { - pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff; - - if (pha==0) { - coef_re[k] = 256; - coef_im[k] = 0; - } else if(pha < 256) { - coef_re[k] = sine[256-(pha&0xff)]; - coef_im[k] = sine[pha&0xff]; - } else if (pha == 256) { - coef_re[k] = 0; - coef_im[k] = 256; - } else if (pha < 512) { - coef_re[k] = -sine[pha&0xff]; - coef_im[k] = sine[256 - (pha&0xff)]; - } else if (pha == 512) { - coef_re[k] = -256; - coef_im[k] = 0; - } else if (pha < 768) { - coef_re[k] = -sine[256-(pha&0xff)]; - coef_im[k] = -sine[pha&0xff]; - } else if (pha == 768) { - coef_re[k] = 0; - coef_im[k] = -256; - } else { - coef_re[k] = sine[pha&0xff]; - coef_im[k] = -sine[256 - (pha&0xff)]; - } - - coef_re[k] *= notch[k]; - coef_re[k] += (1<<14); - if (coef_re[k] >= (1<<24)) - coef_re[k] = (1<<24) - 1; - coef_re[k] /= (1<<15); - - coef_im[k] *= notch[k]; - coef_im[k] += (1<<14); - if (coef_im[k] >= (1<<24)) - coef_im[k] = (1<<24)-1; - coef_im[k] /= (1<<15); - - dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]); - - dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); - dib7000p_write_word(state, 144, coef_im[k] & 0x3ff); - dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); - } - dib7000p_write_word(state,143 ,0); -} - -static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) -{ - struct dib7000p_state *state = demod->demodulator_priv; - u16 tmp = 0; - - if (ch != NULL) - dib7000p_set_channel(state, ch, 0); - else - return -EINVAL; - - // restart demod - dib7000p_write_word(state, 770, 0x4000); - dib7000p_write_word(state, 770, 0x0000); - msleep(45); - - /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ - tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); - if (state->sfn_workaround_active) { - dprintk( "SFN workaround is active"); - tmp |= (1 << 9); - dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift - } else { - dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift - } - dib7000p_write_word(state, 29, tmp); - - // never achieved a lock with that bandwidth so far - wait for osc-freq to update - if (state->timf == 0) - msleep(200); - - /* offset loop parameters */ - - /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ - tmp = (6 << 8) | 0x80; - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break; - case /* 4K MODE */ 255: tmp |= (8 << 12); break; - default: - case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break; - } - dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ - - /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ - tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: tmp |= 0x6; break; - case /* 4K MODE */ 255: tmp |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: tmp |= 0x8; break; - } - dib7000p_write_word(state, 32, tmp); - - /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ - tmp = (0 << 4); - switch (ch->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: tmp |= 0x6; break; - case /* 4K MODE */ 255: tmp |= 0x7; break; - default: - case TRANSMISSION_MODE_8K: tmp |= 0x8; break; - } - dib7000p_write_word(state, 33, tmp); - - tmp = dib7000p_read_word(state,509); - if (!((tmp >> 6) & 0x1)) { - /* restart the fec */ - tmp = dib7000p_read_word(state,771); - dib7000p_write_word(state, 771, tmp | (1 << 1)); - dib7000p_write_word(state, 771, tmp); - msleep(10); - tmp = dib7000p_read_word(state,509); - } - - // we achieved a lock - it's time to update the osc freq - if ((tmp >> 6) & 0x1) - dib7000p_update_timf(state); - - if (state->cfg.spur_protect) - dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - - dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); - return 0; -} - -static int dib7000p_wakeup(struct dvb_frontend *demod) -{ - struct dib7000p_state *state = demod->demodulator_priv; - dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); - dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); - return 0; -} - -static int dib7000p_sleep(struct dvb_frontend *demod) -{ - struct dib7000p_state *state = demod->demodulator_priv; - return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); -} - -static int dib7000p_identify(struct dib7000p_state *st) -{ - u16 value; - dprintk( "checking demod on I2C address: %d (%x)", - st->i2c_addr, st->i2c_addr); - - if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { - dprintk( "wrong Vendor ID (read=0x%x)",value); - return -EREMOTEIO; - } - - if ((value = dib7000p_read_word(st, 769)) != 0x4000) { - dprintk( "wrong Device ID (%x)",value); - return -EREMOTEIO; - } - - return 0; -} - - -static int dib7000p_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000p_state *state = fe->demodulator_priv; - u16 tps = dib7000p_read_word(state,463); - - fep->inversion = INVERSION_AUTO; - - fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); - - switch ((tps >> 8) & 0x3) { - case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; - case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; - /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ - } - - switch (tps & 0x3) { - case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; - case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; - case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; - case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; - } - - switch ((tps >> 14) & 0x3) { - case 0: fep->u.ofdm.constellation = QPSK; break; - case 1: fep->u.ofdm.constellation = QAM_16; break; - case 2: - default: fep->u.ofdm.constellation = QAM_64; break; - } - - /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ - /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */ - - fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; - switch ((tps >> 5) & 0x7) { - case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; - - } - - switch ((tps >> 2) & 0x7) { - case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; - case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; - case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; - case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; - case 7: - default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; - } - - /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */ - - return 0; -} - -static int dib7000p_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fep) -{ - struct dib7000p_state *state = fe->demodulator_priv; - int time, ret; - - dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); - - /* maybe the parameter has been changed */ - state->sfn_workaround_active = buggy_sfn_workaround; - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, fep); - - /* start up the AGC */ - state->agc_state = 0; - do { - time = dib7000p_agc_startup(fe, fep); - if (time != -1) - msleep(time); - } while (time != -1); - - if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || - fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || - fep->u.ofdm.constellation == QAM_AUTO || - fep->u.ofdm.code_rate_HP == FEC_AUTO) { - int i = 800, found; - - dib7000p_autosearch_start(fe, fep); - do { - msleep(1); - found = dib7000p_autosearch_is_irq(fe); - } while (found == 0 && i--); - - dprintk("autosearch returns: %d",found); - if (found == 0 || found == 1) - return 0; // no channel found - - dib7000p_get_frontend(fe, fep); - } - - ret = dib7000p_tune(fe, fep); - - /* make this a config parameter */ - dib7000p_set_output_mode(state, state->cfg.output_mode); - return ret; -} - -static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct dib7000p_state *state = fe->demodulator_priv; - u16 lock = dib7000p_read_word(state, 509); - - *stat = 0; - - if (lock & 0x8000) - *stat |= FE_HAS_SIGNAL; - if (lock & 0x3000) - *stat |= FE_HAS_CARRIER; - if (lock & 0x0100) - *stat |= FE_HAS_VITERBI; - if (lock & 0x0010) - *stat |= FE_HAS_SYNC; - if (lock & 0x0008) - *stat |= FE_HAS_LOCK; - - return 0; -} - -static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct dib7000p_state *state = fe->demodulator_priv; - *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501); - return 0; -} - -static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) -{ - struct dib7000p_state *state = fe->demodulator_priv; - *unc = dib7000p_read_word(state, 506); - return 0; -} - -static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct dib7000p_state *state = fe->demodulator_priv; - u16 val = dib7000p_read_word(state, 394); - *strength = 65535 - val; - return 0; -} - -static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr) -{ - *snr = 0x0000; - return 0; -} - -static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void dib7000p_release(struct dvb_frontend *demod) -{ - struct dib7000p_state *st = demod->demodulator_priv; - dibx000_exit_i2c_master(&st->i2c_master); - kfree(st); -} - -int dib7000pc_detection(struct i2c_adapter *i2c_adap) -{ - u8 tx[2], rx[2]; - struct i2c_msg msg[2] = { - { .addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2 }, - { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 }, - }; - - tx[0] = 0x03; - tx[1] = 0x00; - - if (i2c_transfer(i2c_adap, msg, 2) == 2) - if (rx[0] == 0x01 && rx[1] == 0xb3) { - dprintk("-D- DiB7000PC detected"); - return 1; - } - - msg[0].addr = msg[1].addr = 0x40; - - if (i2c_transfer(i2c_adap, msg, 2) == 2) - if (rx[0] == 0x01 && rx[1] == 0xb3) { - dprintk("-D- DiB7000PC detected"); - return 1; - } - - dprintk("-D- DiB7000PC not detected"); - return 0; -} -EXPORT_SYMBOL(dib7000pc_detection); - -struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) -{ - struct dib7000p_state *st = demod->demodulator_priv; - return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); -} -EXPORT_SYMBOL(dib7000p_get_i2c_master); - -int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]) -{ - struct dib7000p_state st = { .i2c_adap = i2c }; - int k = 0; - u8 new_addr = 0; - - for (k = no_of_demods-1; k >= 0; k--) { - st.cfg = cfg[k]; - - /* designated i2c address */ - new_addr = (0x40 + k) << 1; - st.i2c_addr = new_addr; - if (dib7000p_identify(&st) != 0) { - st.i2c_addr = default_addr; - if (dib7000p_identify(&st) != 0) { - dprintk("DiB7000P #%d: not identified\n", k); - return -EIO; - } - } - - /* start diversity to pull_down div_str - just for i2c-enumeration */ - dib7000p_set_output_mode(&st, OUTMODE_DIVERSITY); - - /* set new i2c address and force divstart */ - dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2); - - dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr); - } - - for (k = 0; k < no_of_demods; k++) { - st.cfg = cfg[k]; - st.i2c_addr = (0x40 + k) << 1; - - // unforce divstr - dib7000p_write_word(&st, 1285, st.i2c_addr << 2); - - /* deactivate div - it was just for i2c-enumeration */ - dib7000p_set_output_mode(&st, OUTMODE_HIGH_Z); - } - - return 0; -} -EXPORT_SYMBOL(dib7000p_i2c_enumeration); - -static struct dvb_frontend_ops dib7000p_ops; -struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) -{ - struct dvb_frontend *demod; - struct dib7000p_state *st; - st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL); - if (st == NULL) - return NULL; - - memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config)); - st->i2c_adap = i2c_adap; - st->i2c_addr = i2c_addr; - st->gpio_val = cfg->gpio_val; - st->gpio_dir = cfg->gpio_dir; - - /* Ensure the output mode remains at the previous default if it's - * not specifically set by the caller. - */ - if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && - (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) - st->cfg.output_mode = OUTMODE_MPEG2_FIFO; - - demod = &st->demod; - demod->demodulator_priv = st; - memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); - - if (dib7000p_identify(st) != 0) - goto error; - - dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); - - dib7000p_demod_reset(st); - - return demod; - -error: - kfree(st); - return NULL; -} -EXPORT_SYMBOL(dib7000p_attach); - -static struct dvb_frontend_ops dib7000p_ops = { - .info = { - .name = "DiBcom 7000PC", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dib7000p_release, - - .init = dib7000p_wakeup, - .sleep = dib7000p_sleep, - - .set_frontend = dib7000p_set_frontend, - .get_tune_settings = dib7000p_fe_get_tune_settings, - .get_frontend = dib7000p_get_frontend, - - .read_status = dib7000p_read_status, - .read_ber = dib7000p_read_ber, - .read_signal_strength = dib7000p_read_signal_strength, - .read_snr = dib7000p_read_snr, - .read_ucblocks = dib7000p_read_unc_blocks, -}; - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h deleted file mode 100644 index aab8112e2db..00000000000 --- a/drivers/media/dvb/frontends/dib7000p.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef DIB7000P_H -#define DIB7000P_H - -#include "dibx000_common.h" - -struct dib7000p_config { - u8 output_mpeg2_in_188_bytes; - u8 hostbus_diversity; - u8 tuner_is_baseband; - int (*update_lna) (struct dvb_frontend *, u16 agc_global); - - u8 agc_config_count; - struct dibx000_agc_config *agc; - struct dibx000_bandwidth_config *bw; - -#define DIB7000P_GPIO_DEFAULT_DIRECTIONS 0xffff - u16 gpio_dir; -#define DIB7000P_GPIO_DEFAULT_VALUES 0x0000 - u16 gpio_val; -#define DIB7000P_GPIO_PWM_POS0(v) ((v & 0xf) << 12) -#define DIB7000P_GPIO_PWM_POS1(v) ((v & 0xf) << 8 ) -#define DIB7000P_GPIO_PWM_POS2(v) ((v & 0xf) << 4 ) -#define DIB7000P_GPIO_PWM_POS3(v) (v & 0xf) -#define DIB7000P_GPIO_DEFAULT_PWM_POS 0xffff - u16 gpio_pwm_pos; - - u16 pwm_freq_div; - - u8 quartz_direct; - - u8 spur_protect; - - int (*agc_control) (struct dvb_frontend *, u8 before); - - u8 output_mode; -}; - -#define DEFAULT_DIB7000P_I2C_ADDRESS 18 - -#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib7000p_config *cfg); -extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, - enum dibx000_i2c_interface, - int); -extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib7000p_config cfg[]); -extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); -extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); -#else -static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib7000p_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline -struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, - enum dibx000_i2c_interface i, int x) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline -int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, - int no_of_demods, u8 default_addr, - struct dib7000p_config cfg[]) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - -static inline -int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} - -static inline -int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return -ENODEV; -} -#endif - -extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); - -#endif diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c deleted file mode 100644 index 315e09e95b0..00000000000 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ /dev/null @@ -1,152 +0,0 @@ -#include <linux/i2c.h> - -#include "dibx000_common.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); - -#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0) - -static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) -{ - u8 b[4] = { - (reg >> 8) & 0xff, reg & 0xff, - (val >> 8) & 0xff, val & 0xff, - }; - struct i2c_msg msg = { - .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4 - }; - return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; -} - - -static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf) -{ - if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { - dprintk("selecting interface: %d\n",intf); - mst->selected_interface = intf; - return dibx000_write_word(mst, mst->base_reg + 4, intf); - } - return 0; -} - -static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff) -{ - u16 val; - - - if (onoff) - val = addr << 8; // bit 7 = use master or not, if 0, the gate is open - else - val = 1 << 7; - - if (mst->device_rev > DIB7000) - val <<= 1; - - tx[0] = (((mst->base_reg + 1) >> 8) & 0xff); - tx[1] = ( (mst->base_reg + 1) & 0xff); - tx[2] = val >> 8; - tx[3] = val & 0xff; - - return 0; -} - -static u32 dibx000_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) -{ - struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); - struct i2c_msg m[2 + num]; - u8 tx_open[4], tx_close[4]; - - memset(m,0, sizeof(struct i2c_msg) * (2 + num)); - - dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); - - dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); - m[0].addr = mst->i2c_addr; - m[0].buf = tx_open; - m[0].len = 4; - - memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); - - dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); - m[num+1].addr = mst->i2c_addr; - m[num+1].buf = tx_close; - m[num+1].len = 4; - - return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO; -} - -static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { - .master_xfer = dibx000_i2c_gated_tuner_xfer, - .functionality = dibx000_i2c_func, -}; - -struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating) -{ - struct i2c_adapter *i2c = NULL; - - switch (intf) { - case DIBX000_I2C_INTERFACE_TUNER: - if (gating) - i2c = &mst->gated_tuner_i2c_adap; - break; - default: - printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); - break; - } - - return i2c; -} -EXPORT_SYMBOL(dibx000_get_i2c_adapter); - -static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst) -{ - strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); - i2c_adap->class = I2C_CLASS_TV_DIGITAL, - i2c_adap->algo = algo; - i2c_adap->algo_data = NULL; - i2c_set_adapdata(i2c_adap, mst); - if (i2c_add_adapter(i2c_adap) < 0) - return -ENODEV; - return 0; -} - -int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr) -{ - u8 tx[4]; - struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 }; - - mst->device_rev = device_rev; - mst->i2c_adap = i2c_adap; - mst->i2c_addr = i2c_addr >> 1; - - if (device_rev == DIB7000P) - mst->base_reg = 1024; - else - mst->base_reg = 768; - - if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0) - printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n"); - - /* initialize the i2c-master by closing the gate */ - dibx000_i2c_gate_ctrl(mst, tx, 0, 0); - - return i2c_transfer(i2c_adap, &m, 1) == 1; -} -EXPORT_SYMBOL(dibx000_init_i2c_master); - -void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) -{ - i2c_del_adapter(&mst->gated_tuner_i2c_adap); -} -EXPORT_SYMBOL(dibx000_exit_i2c_master); - -MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); -MODULE_DESCRIPTION("Common function the DiBcom demodulator family"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h deleted file mode 100644 index 84e4d536292..00000000000 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef DIBX000_COMMON_H -#define DIBX000_COMMON_H - -enum dibx000_i2c_interface { - DIBX000_I2C_INTERFACE_TUNER = 0, - DIBX000_I2C_INTERFACE_GPIO_1_2 = 1, - DIBX000_I2C_INTERFACE_GPIO_3_4 = 2 -}; - -struct dibx000_i2c_master { -#define DIB3000MC 1 -#define DIB7000 2 -#define DIB7000P 11 -#define DIB7000MC 12 - u16 device_rev; - - enum dibx000_i2c_interface selected_interface; - -// struct i2c_adapter tuner_i2c_adap; - struct i2c_adapter gated_tuner_i2c_adap; - - struct i2c_adapter *i2c_adap; - u8 i2c_addr; - - u16 base_reg; -}; - -extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr); -extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating); -extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); - -#define BAND_LBAND 0x01 -#define BAND_UHF 0x02 -#define BAND_VHF 0x04 -#define BAND_SBAND 0x08 -#define BAND_FM 0x10 - -#define BAND_OF_FREQUENCY(freq_kHz) ( (freq_kHz) <= 115000 ? BAND_FM : \ - (freq_kHz) <= 250000 ? BAND_VHF : \ - (freq_kHz) <= 863000 ? BAND_UHF : \ - (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) - -struct dibx000_agc_config { - /* defines the capabilities of this AGC-setting - using the BAND_-defines*/ - u8 band_caps; - - u16 setup; - - u16 inv_gain; - u16 time_stabiliz; - - u8 alpha_level; - u16 thlock; - - u8 wbd_inv; - u16 wbd_ref; - u8 wbd_sel; - u8 wbd_alpha; - - u16 agc1_max; - u16 agc1_min; - u16 agc2_max; - u16 agc2_min; - - u8 agc1_pt1; - u8 agc1_pt2; - u8 agc1_pt3; - - u8 agc1_slope1; - u8 agc1_slope2; - - u8 agc2_pt1; - u8 agc2_pt2; - - u8 agc2_slope1; - u8 agc2_slope2; - - u8 alpha_mant; - u8 alpha_exp; - - u8 beta_mant; - u8 beta_exp; - - u8 perform_agc_softsplit; - - struct { - u16 min; - u16 max; - u16 min_thres; - u16 max_thres; - } split; -}; - -struct dibx000_bandwidth_config { - u32 internal; - u32 sampling; - - u8 pll_prediv; - u8 pll_ratio; - u8 pll_range; - u8 pll_reset; - u8 pll_bypass; - - u8 enable_refdiv; - u8 bypclk_div; - u8 IO_CLK_en_core; - u8 ADClkSrc; - u8 modulo; - - u16 sad_cfg; - - u32 ifreq; - u32 timf; - - u32 xtal_hz; -}; - -enum dibx000_adc_states { - DIBX000_SLOW_ADC_ON = 0, - DIBX000_SLOW_ADC_OFF, - DIBX000_ADC_ON, - DIBX000_ADC_OFF, - DIBX000_VBG_ENABLE, - DIBX000_VBG_DISABLE, -}; - -#define BANDWIDTH_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \ - (v) == BANDWIDTH_7_MHZ ? 7000 : \ - (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 ) - -#define BANDWIDTH_TO_INDEX(v) ( \ - (v) == 8000 ? BANDWIDTH_8_MHZ : \ - (v) == 7000 ? BANDWIDTH_7_MHZ : \ - (v) == 6000 ? BANDWIDTH_6_MHZ : BANDWIDTH_8_MHZ ) - -/* Chip output mode. */ -#define OUTMODE_HIGH_Z 0 -#define OUTMODE_MPEG2_PAR_GATED_CLK 1 -#define OUTMODE_MPEG2_PAR_CONT_CLK 2 -#define OUTMODE_MPEG2_SERIAL 7 -#define OUTMODE_DIVERSITY 4 -#define OUTMODE_MPEG2_FIFO 5 -#define OUTMODE_ANALOG_ADC 6 - -#endif diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c deleted file mode 100644 index ec4e08dbc69..00000000000 --- a/drivers/media/dvb/frontends/drx397xD.c +++ /dev/null @@ -1,1510 +0,0 @@ -/* - * Driver for Micronas drx397xD demodulator - * - * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; If not, see <http://www.gnu.org/licenses/>. - */ - -#define DEBUG /* uncomment if you want debugging output */ -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/firmware.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "drx397xD.h" - -static const char mod_name[] = "drx397xD"; - -#define MAX_CLOCK_DRIFT 200 /* maximal 200 PPM allowed */ - -#define F_SET_0D0h 1 -#define F_SET_0D4h 2 - -enum fw_ix { -#define _FW_ENTRY(a, b, c) b -#include "drx397xD_fw.h" -}; - -/* chip specifics */ -struct drx397xD_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - struct drx397xD_config config; - enum fw_ix chip_rev; - int flags; - u32 bandwidth_parm; /* internal bandwidth conversions */ - u32 f_osc; /* w90: actual osc frequency [Hz] */ -}; - -/* Firmware */ -static const char *blob_name[] = { -#define _BLOB_ENTRY(a, b) a -#include "drx397xD_fw.h" -}; - -enum blob_ix { -#define _BLOB_ENTRY(a, b) b -#include "drx397xD_fw.h" -}; - -static struct { - const char *name; - const struct firmware *file; - rwlock_t lock; - int refcnt; - const u8 *data[ARRAY_SIZE(blob_name)]; -} fw[] = { -#define _FW_ENTRY(a, b, c) { \ - .name = a, \ - .file = 0, \ - .lock = __RW_LOCK_UNLOCKED(fw[c].lock), \ - .refcnt = 0, \ - .data = { } } -#include "drx397xD_fw.h" -}; - -/* use only with writer lock aquired */ -static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix) -{ - memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); - if (fw[ix].file) - release_firmware(fw[ix].file); -} - -static void drx_release_fw(struct drx397xD_state *s) -{ - enum fw_ix ix = s->chip_rev; - - pr_debug("%s\n", __func__); - - write_lock(&fw[ix].lock); - if (fw[ix].refcnt) { - fw[ix].refcnt--; - if (fw[ix].refcnt == 0) - _drx_release_fw(s, ix); - } - write_unlock(&fw[ix].lock); -} - -static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix) -{ - const u8 *data; - size_t size, len; - int i = 0, j, rc = -EINVAL; - - pr_debug("%s\n", __func__); - - if (ix < 0 || ix >= ARRAY_SIZE(fw)) - return -EINVAL; - s->chip_rev = ix; - - write_lock(&fw[ix].lock); - if (fw[ix].file) { - rc = 0; - goto exit_ok; - } - memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); - - if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) { - printk(KERN_ERR "%s: Firmware \"%s\" not available\n", - mod_name, fw[ix].name); - rc = -ENOENT; - goto exit_err; - } - - if (!fw[ix].file->data || fw[ix].file->size < 10) - goto exit_corrupt; - - data = fw[ix].file->data; - size = fw[ix].file->size; - - if (data[i++] != 2) /* check firmware version */ - goto exit_corrupt; - - do { - switch (data[i++]) { - case 0x00: /* bytecode */ - if (i >= size) - break; - i += data[i]; - case 0x01: /* reset */ - case 0x02: /* sleep */ - i++; - break; - case 0xfe: /* name */ - len = strnlen(&data[i], size - i); - if (i + len + 1 >= size) - goto exit_corrupt; - if (data[i + len + 1] != 0) - goto exit_corrupt; - for (j = 0; j < ARRAY_SIZE(blob_name); j++) { - if (strcmp(blob_name[j], &data[i]) == 0) { - fw[ix].data[j] = &data[i + len + 1]; - pr_debug("Loading %s\n", blob_name[j]); - } - } - i += len + 1; - break; - case 0xff: /* file terminator */ - if (i == size) { - rc = 0; - goto exit_ok; - } - default: - goto exit_corrupt; - } - } while (i < size); - -exit_corrupt: - printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); -exit_err: - _drx_release_fw(s, ix); - fw[ix].refcnt--; -exit_ok: - fw[ix].refcnt++; - write_unlock(&fw[ix].lock); - - return rc; -} - -/* i2c bus IO */ -static int write_fw(struct drx397xD_state *s, enum blob_ix ix) -{ - const u8 *data; - int len, rc = 0, i = 0; - struct i2c_msg msg = { - .addr = s->config.demod_address, - .flags = 0 - }; - - if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { - pr_debug("%s drx_fw_ix_t out of range\n", __func__); - return -EINVAL; - } - pr_debug("%s %s\n", __func__, blob_name[ix]); - - read_lock(&fw[s->chip_rev].lock); - data = fw[s->chip_rev].data[ix]; - if (!data) { - rc = -EINVAL; - goto exit_rc; - } - - for (;;) { - switch (data[i++]) { - case 0: /* bytecode */ - len = data[i++]; - msg.len = len; - msg.buf = (__u8 *) &data[i]; - if (i2c_transfer(s->i2c, &msg, 1) != 1) { - rc = -EIO; - goto exit_rc; - } - i += len; - break; - case 1: /* reset */ - case 2: /* sleep */ - i++; - break; - default: - goto exit_rc; - } - } -exit_rc: - read_unlock(&fw[s->chip_rev].lock); - - return 0; -} - -/* Function is not endian safe, use the RD16 wrapper below */ -static int _read16(struct drx397xD_state *s, __le32 i2c_adr) -{ - int rc; - u8 a[4]; - __le16 v; - struct i2c_msg msg[2] = { - { - .addr = s->config.demod_address, - .flags = 0, - .buf = a, - .len = sizeof(a) - }, { - .addr = s->config.demod_address, - .flags = I2C_M_RD, - .buf = (u8 *)&v, - .len = sizeof(v) - } - }; - - *(__le32 *) a = i2c_adr; - - rc = i2c_transfer(s->i2c, msg, 2); - if (rc != 2) - return -EIO; - - return le16_to_cpu(v); -} - -/* Function is not endian safe, use the WR16.. wrappers below */ -static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val) -{ - u8 a[6]; - int rc; - struct i2c_msg msg = { - .addr = s->config.demod_address, - .flags = 0, - .buf = a, - .len = sizeof(a) - }; - - *(__le32 *)a = i2c_adr; - *(__le16 *)&a[4] = val; - - rc = i2c_transfer(s->i2c, &msg, 1); - if (rc != 1) - return -EIO; - - return 0; -} - -#define WR16(ss, adr, val) \ - _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) -#define WR16_E0(ss, adr, val) \ - _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) -#define RD16(ss, adr) \ - _read16(ss, I2C_ADR_C0(adr)) - -#define EXIT_RC(cmd) \ - if ((rc = (cmd)) < 0) \ - goto exit_rc - -/* Tuner callback */ -static int PLL_Set(struct drx397xD_state *s, - struct dvb_frontend_parameters *fep, int *df_tuner) -{ - struct dvb_frontend *fe = &s->frontend; - u32 f_tuner, f = fep->frequency; - int rc; - - pr_debug("%s\n", __func__); - - if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || - (f < s->frontend.ops.tuner_ops.info.frequency_min)) - return -EINVAL; - - *df_tuner = 0; - if (!s->frontend.ops.tuner_ops.set_params || - !s->frontend.ops.tuner_ops.get_frequency) - return -ENOSYS; - - rc = s->frontend.ops.tuner_ops.set_params(fe, fep); - if (rc < 0) - return rc; - - rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner); - if (rc < 0) - return rc; - - *df_tuner = f_tuner - f; - pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f, - f_tuner); - - return 0; -} - -/* Demodulator helper functions */ -static int SC_WaitForReady(struct drx397xD_state *s) -{ - int cnt = 1000; - int rc; - - pr_debug("%s\n", __func__); - - while (cnt--) { - rc = RD16(s, 0x820043); - if (rc == 0) - return 0; - } - - return -1; -} - -static int SC_SendCommand(struct drx397xD_state *s, int cmd) -{ - int rc; - - pr_debug("%s\n", __func__); - - WR16(s, 0x820043, cmd); - SC_WaitForReady(s); - rc = RD16(s, 0x820042); - if ((rc & 0xffff) == 0xffff) - return -1; - - return 0; -} - -static int HI_Command(struct drx397xD_state *s, u16 cmd) -{ - int rc, cnt = 1000; - - pr_debug("%s\n", __func__); - - rc = WR16(s, 0x420032, cmd); - if (rc < 0) - return rc; - - do { - rc = RD16(s, 0x420032); - if (rc == 0) { - rc = RD16(s, 0x420031); - return rc; - } - if (rc < 0) - return rc; - } while (--cnt); - - return rc; -} - -static int HI_CfgCommand(struct drx397xD_state *s) -{ - - pr_debug("%s\n", __func__); - - WR16(s, 0x420033, 0x3973); - WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */ - WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */ - WR16(s, 0x420036, s->config.demod_address << 1); - WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */ - /* WR16(s, 0x420033, 0x3973); */ - if ((s->config.w56 & 8) == 0) - return HI_Command(s, 3); - - return WR16(s, 0x420032, 0x3); -} - -static const u8 fastIncrDecLUT_15273[] = { - 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f -}; - -static const u8 slowIncrDecLUT_15272[] = { - 3, 4, 4, 5, 6 -}; - -static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc) -{ - u16 w06 = agc->w06; - u16 w08 = agc->w08; - u16 w0A = agc->w0A; - u16 w0C = agc->w0C; - int quot, rem, i, rc = -EINVAL; - - pr_debug("%s\n", __func__); - - if (agc->w04 > 0x3ff) - goto exit_rc; - - if (agc->d00 == 1) { - EXIT_RC(RD16(s, 0x0c20010)); - rc &= ~0x10; - EXIT_RC(WR16(s, 0x0c20010, rc)); - return WR16(s, 0x0c20030, agc->w04 & 0x7ff); - } - - if (agc->d00 != 0) - goto exit_rc; - if (w0A < w08) - goto exit_rc; - if (w0A > 0x3ff) - goto exit_rc; - if (w0C > 0x3ff) - goto exit_rc; - if (w06 > 0x3ff) - goto exit_rc; - - EXIT_RC(RD16(s, 0x0c20010)); - rc |= 0x10; - EXIT_RC(WR16(s, 0x0c20010, rc)); - - EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff)); - EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1)); - EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff)); - - quot = w0C / 113; - rem = w0C % 113; - if (quot <= 8) { - quot = 8 - quot; - } else { - quot = 0; - rem += 113; - } - - EXIT_RC(WR16(s, 0x0c20024, quot)); - - i = fastIncrDecLUT_15273[rem / 8]; - EXIT_RC(WR16(s, 0x0c2002d, i)); - EXIT_RC(WR16(s, 0x0c2002e, i)); - - i = slowIncrDecLUT_15272[rem / 28]; - EXIT_RC(WR16(s, 0x0c2002b, i)); - rc = WR16(s, 0x0c2002c, i); -exit_rc: - return rc; -} - -static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc) -{ - u16 w04 = agc->w04; - u16 w06 = agc->w06; - int rc = -1; - - pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06); - - if (w04 > 0x3ff) - goto exit_rc; - - switch (agc->d00) { - case 1: - if (w04 == 0x3ff) - w04 = 0x400; - - EXIT_RC(WR16(s, 0x0c20036, w04)); - s->config.w9C &= ~2; - EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); - EXIT_RC(RD16(s, 0x0c20010)); - rc &= 0xbfdf; - EXIT_RC(WR16(s, 0x0c20010, rc)); - EXIT_RC(RD16(s, 0x0c20013)); - rc &= ~2; - break; - case 0: - /* loc_8000659 */ - s->config.w9C &= ~2; - EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); - EXIT_RC(RD16(s, 0x0c20010)); - rc &= 0xbfdf; - rc |= 0x4000; - EXIT_RC(WR16(s, 0x0c20010, rc)); - EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f)); - EXIT_RC(RD16(s, 0x0c20013)); - rc &= ~2; - break; - default: - s->config.w9C |= 2; - EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); - EXIT_RC(RD16(s, 0x0c20010)); - rc &= 0xbfdf; - EXIT_RC(WR16(s, 0x0c20010, rc)); - - EXIT_RC(WR16(s, 0x0c20036, 0)); - - EXIT_RC(RD16(s, 0x0c20013)); - rc |= 2; - } - rc = WR16(s, 0x0c20013, rc); - -exit_rc: - return rc; -} - -static int GetLockStatus(struct drx397xD_state *s, int *lockstat) -{ - int rc; - - *lockstat = 0; - - rc = RD16(s, 0x082004b); - if (rc < 0) - return rc; - - if (s->config.d60 != 2) - return 0; - - if ((rc & 7) == 7) - *lockstat |= 1; - if ((rc & 3) == 3) - *lockstat |= 2; - if (rc & 1) - *lockstat |= 4; - return 0; -} - -static int CorrectSysClockDeviation(struct drx397xD_state *s) -{ - int rc = -EINVAL; - int lockstat; - u32 clk, clk_limit; - - pr_debug("%s\n", __func__); - - if (s->config.d5C == 0) { - EXIT_RC(WR16(s, 0x08200e8, 0x010)); - EXIT_RC(WR16(s, 0x08200e9, 0x113)); - s->config.d5C = 1; - return rc; - } - if (s->config.d5C != 1) - goto exit_rc; - - rc = RD16(s, 0x0820048); - - rc = GetLockStatus(s, &lockstat); - if (rc < 0) - goto exit_rc; - if ((lockstat & 1) == 0) - goto exit_rc; - - EXIT_RC(WR16(s, 0x0420033, 0x200)); - EXIT_RC(WR16(s, 0x0420034, 0xc5)); - EXIT_RC(WR16(s, 0x0420035, 0x10)); - EXIT_RC(WR16(s, 0x0420036, 0x1)); - EXIT_RC(WR16(s, 0x0420037, 0xa)); - EXIT_RC(HI_Command(s, 6)); - EXIT_RC(RD16(s, 0x0420040)); - clk = rc; - EXIT_RC(RD16(s, 0x0420041)); - clk |= rc << 16; - - if (clk <= 0x26ffff) - goto exit_rc; - if (clk > 0x610000) - goto exit_rc; - - if (!s->bandwidth_parm) - return -EINVAL; - - /* round & convert to Hz */ - clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21; - clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000; - - if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { - s->f_osc = clk; - pr_debug("%s: osc %d %d [Hz]\n", __func__, - s->config.f_osc * 1000, clk - s->config.f_osc * 1000); - } - rc = WR16(s, 0x08200e8, 0); - -exit_rc: - return rc; -} - -static int ConfigureMPEGOutput(struct drx397xD_state *s, int type) -{ - int rc, si, bp; - - pr_debug("%s\n", __func__); - - si = s->config.wA0; - if (s->config.w98 == 0) { - si |= 1; - bp = 0; - } else { - si &= ~1; - bp = 0x200; - } - if (s->config.w9A == 0) - si |= 0x80; - else - si &= ~0x80; - - EXIT_RC(WR16(s, 0x2150045, 0)); - EXIT_RC(WR16(s, 0x2150010, si)); - EXIT_RC(WR16(s, 0x2150011, bp)); - rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); - -exit_rc: - return rc; -} - -static int drx_tune(struct drx397xD_state *s, - struct dvb_frontend_parameters *fep) -{ - u16 v22 = 0; - u16 v1C = 0; - u16 v1A = 0; - u16 v18 = 0; - u32 edi = 0, ebx = 0, ebp = 0, edx = 0; - u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0; - - int rc, df_tuner; - int a, b, c, d; - pr_debug("%s %d\n", __func__, s->config.d60); - - if (s->config.d60 != 2) - goto set_tuner; - rc = CorrectSysClockDeviation(s); - if (rc < 0) - goto set_tuner; - - s->config.d60 = 1; - rc = ConfigureMPEGOutput(s, 0); - if (rc < 0) - goto set_tuner; -set_tuner: - - rc = PLL_Set(s, fep, &df_tuner); - if (rc < 0) { - printk(KERN_ERR "Error in pll_set\n"); - goto exit_rc; - } - msleep(200); - - a = rc = RD16(s, 0x2150016); - if (rc < 0) - goto exit_rc; - b = rc = RD16(s, 0x2150010); - if (rc < 0) - goto exit_rc; - c = rc = RD16(s, 0x2150034); - if (rc < 0) - goto exit_rc; - d = rc = RD16(s, 0x2150035); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2150014, c); - rc = WR16(s, 0x2150015, d); - rc = WR16(s, 0x2150010, 0); - rc = WR16(s, 0x2150000, 2); - rc = WR16(s, 0x2150036, 0x0fff); - rc = WR16(s, 0x2150016, a); - - rc = WR16(s, 0x2150010, 2); - rc = WR16(s, 0x2150007, 0); - rc = WR16(s, 0x2150000, 1); - rc = WR16(s, 0x2110000, 0); - rc = WR16(s, 0x0800000, 0); - rc = WR16(s, 0x2800000, 0); - rc = WR16(s, 0x2110010, 0x664); - - rc = write_fw(s, DRXD_ResetECRAM); - rc = WR16(s, 0x2110000, 1); - - rc = write_fw(s, DRXD_InitSC); - if (rc < 0) - goto exit_rc; - - rc = SetCfgIfAgc(s, &s->config.ifagc); - if (rc < 0) - goto exit_rc; - - rc = SetCfgRfAgc(s, &s->config.rfagc); - if (rc < 0) - goto exit_rc; - - if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K) - v22 = 1; - switch (fep->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_8K: - edi = 1; - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x2010010, 0); - if (rc < 0) - break; - v1C = 0x63; - v1A = 0x53; - v18 = 0x43; - break; - default: - edi = 0; - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x2010010, 1); - if (rc < 0) - break; - - v1C = 0x61; - v1A = 0x47; - v18 = 0x41; - } - - switch (fep->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_4: - edi |= 0x0c; - break; - case GUARD_INTERVAL_1_8: - edi |= 0x08; - break; - case GUARD_INTERVAL_1_16: - edi |= 0x04; - break; - case GUARD_INTERVAL_1_32: - break; - default: - v22 |= 2; - } - - ebx = 0; - ebp = 0; - v20 = 0; - v1E = 0; - v16 = 0; - v14 = 0; - v12 = 0; - v10 = 0; - v0E = 0; - - switch (fep->u.ofdm.hierarchy_information) { - case HIERARCHY_1: - edi |= 0x40; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 1); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 1); - if (rc < 0) - goto exit_rc; - ebx = 0x19f; - ebp = 0x1fb; - v20 = 0x0c0; - v1E = 0x195; - v16 = 0x1d6; - v14 = 0x1ef; - v12 = 4; - v10 = 5; - v0E = 5; - break; - case HIERARCHY_2: - edi |= 0x80; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 2); - if (rc < 0) - goto exit_rc; - ebx = 0x08f; - ebp = 0x12f; - v20 = 0x0c0; - v1E = 0x11e; - v16 = 0x1d6; - v14 = 0x15e; - v12 = 4; - v10 = 5; - v0E = 5; - break; - case HIERARCHY_4: - edi |= 0xc0; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 3); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 3); - if (rc < 0) - goto exit_rc; - ebx = 0x14d; - ebp = 0x197; - v20 = 0x0c0; - v1E = 0x1ce; - v16 = 0x1d6; - v14 = 0x11a; - v12 = 4; - v10 = 6; - v0E = 5; - break; - default: - v22 |= 8; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x1c10047, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010012, 0); - if (rc < 0) - goto exit_rc; - /* QPSK QAM16 QAM64 */ - ebx = 0x19f; /* 62 */ - ebp = 0x1fb; /* 15 */ - v20 = 0x16a; /* 62 */ - v1E = 0x195; /* 62 */ - v16 = 0x1bb; /* 15 */ - v14 = 0x1ef; /* 15 */ - v12 = 5; /* 16 */ - v10 = 5; /* 16 */ - v0E = 5; /* 16 */ - } - - switch (fep->u.ofdm.constellation) { - default: - v22 |= 4; - case QPSK: - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x1c10046, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010011, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001a, 0x10); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001b, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001c, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10062, v20); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c1002a, v1C); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10015, v16); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10016, v12); - if (rc < 0) - goto exit_rc; - break; - case QAM_16: - edi |= 0x10; - if (s->chip_rev == DRXD_FW_B1) - break; - - rc = WR16(s, 0x1c10046, 1); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010011, 1); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001a, 0x10); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001b, 4); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001c, 0); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10062, v1E); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c1002a, v1A); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10015, v14); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10016, v10); - if (rc < 0) - goto exit_rc; - break; - case QAM_64: - edi |= 0x20; - rc = WR16(s, 0x1c10046, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x2010011, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001a, 0x20); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001b, 8); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x201001c, 2); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10062, ebx); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c1002a, v18); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10015, ebp); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x1c10016, v0E); - if (rc < 0) - goto exit_rc; - break; - } - - if (s->config.s20d24 == 1) { - rc = WR16(s, 0x2010013, 0); - } else { - rc = WR16(s, 0x2010013, 1); - edi |= 0x1000; - } - - switch (fep->u.ofdm.code_rate_HP) { - default: - v22 |= 0x10; - case FEC_1_2: - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 0); - break; - case FEC_2_3: - edi |= 0x200; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 1); - break; - case FEC_3_4: - edi |= 0x400; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 2); - break; - case FEC_5_6: /* 5 */ - edi |= 0x600; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 3); - break; - case FEC_7_8: /* 7 */ - edi |= 0x800; - if (s->chip_rev == DRXD_FW_B1) - break; - rc = WR16(s, 0x2090011, 4); - break; - }; - if (rc < 0) - goto exit_rc; - - switch (fep->u.ofdm.bandwidth) { - default: - rc = -EINVAL; - goto exit_rc; - case BANDWIDTH_8_MHZ: /* 0 */ - case BANDWIDTH_AUTO: - rc = WR16(s, 0x0c2003f, 0x32); - s->bandwidth_parm = ebx = 0x8b8249; - edx = 0; - break; - case BANDWIDTH_7_MHZ: - rc = WR16(s, 0x0c2003f, 0x3b); - s->bandwidth_parm = ebx = 0x7a1200; - edx = 0x4807; - break; - case BANDWIDTH_6_MHZ: - rc = WR16(s, 0x0c2003f, 0x47); - s->bandwidth_parm = ebx = 0x68a1b6; - edx = 0x0f07; - break; - }; - - if (rc < 0) - goto exit_rc; - - rc = WR16(s, 0x08200ec, edx); - if (rc < 0) - goto exit_rc; - - rc = RD16(s, 0x0820050); - if (rc < 0) - goto exit_rc; - rc = WR16(s, 0x0820050, rc); - - { - /* Configure bandwidth specific factor */ - ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1), - (u64)ebx) - 0x800000; - EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff)); - EXIT_RC(WR16(s, 0x0c50011, ebx >> 16)); - - /* drx397xD oscillator calibration */ - ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) + - (s->f_osc >> 1), (u64)s->f_osc); - } - ebx &= 0xfffffff; - if (fep->inversion == INVERSION_ON) - ebx = 0x10000000 - ebx; - - EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff)); - EXIT_RC(WR16(s, 0x0c30011, ebx >> 16)); - - EXIT_RC(WR16(s, 0x0800000, 1)); - EXIT_RC(RD16(s, 0x0800000)); - - - EXIT_RC(SC_WaitForReady(s)); - EXIT_RC(WR16(s, 0x0820042, 0)); - EXIT_RC(WR16(s, 0x0820041, v22)); - EXIT_RC(WR16(s, 0x0820040, edi)); - EXIT_RC(SC_SendCommand(s, 3)); - - rc = RD16(s, 0x0800000); - - SC_WaitForReady(s); - WR16(s, 0x0820042, 0); - WR16(s, 0x0820041, 1); - WR16(s, 0x0820040, 1); - SC_SendCommand(s, 1); - - - rc = WR16(s, 0x2150000, 2); - rc = WR16(s, 0x2150016, a); - rc = WR16(s, 0x2150010, 4); - rc = WR16(s, 0x2150036, 0); - rc = WR16(s, 0x2150000, 1); - s->config.d60 = 2; - -exit_rc: - return rc; -} - -/******************************************************************************* - * DVB interface - ******************************************************************************/ - -static int drx397x_init(struct dvb_frontend *fe) -{ - struct drx397xD_state *s = fe->demodulator_priv; - int rc; - - pr_debug("%s\n", __func__); - - s->config.rfagc.d00 = 2; /* 0x7c */ - s->config.rfagc.w04 = 0; - s->config.rfagc.w06 = 0x3ff; - - s->config.ifagc.d00 = 0; /* 0x68 */ - s->config.ifagc.w04 = 0; - s->config.ifagc.w06 = 140; - s->config.ifagc.w08 = 0; - s->config.ifagc.w0A = 0x3ff; - s->config.ifagc.w0C = 0x388; - - /* for signal strenght calculations */ - s->config.ss76 = 820; - s->config.ss78 = 2200; - s->config.ss7A = 150; - - /* HI_CfgCommand */ - s->config.w50 = 4; - s->config.w52 = 9; - - s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ - s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ - s->config.w92 = 12000; - - s->config.w9C = 0x000e; - s->config.w9E = 0x0000; - - /* ConfigureMPEGOutput params */ - s->config.wA0 = 4; - s->config.w98 = 1; - s->config.w9A = 1; - - /* get chip revision */ - rc = RD16(s, 0x2410019); - if (rc < 0) - return -ENODEV; - - if (rc == 0) { - printk(KERN_INFO "%s: chip revision A2\n", mod_name); - rc = drx_load_fw(s, DRXD_FW_A2); - } else { - - rc = (rc >> 12) - 3; - switch (rc) { - case 1: - s->flags |= F_SET_0D4h; - case 0: - case 4: - s->flags |= F_SET_0D0h; - break; - case 2: - case 5: - break; - case 3: - s->flags |= F_SET_0D4h; - break; - default: - return -ENODEV; - }; - printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc); - rc = drx_load_fw(s, DRXD_FW_B1); - } - if (rc < 0) - goto error; - - rc = WR16(s, 0x0420033, 0x3973); - if (rc < 0) - goto error; - - rc = HI_Command(s, 2); - - msleep(1); - - if (s->chip_rev == DRXD_FW_A2) { - rc = WR16(s, 0x043012d, 0x47F); - if (rc < 0) - goto error; - } - rc = WR16_E0(s, 0x0400000, 0); - if (rc < 0) - goto error; - - if (s->config.w92 > 20000 || s->config.w92 % 4000) { - printk(KERN_ERR "%s: invalid osc frequency\n", mod_name); - rc = -1; - goto error; - } - - rc = WR16(s, 0x2410010, 1); - if (rc < 0) - goto error; - rc = WR16(s, 0x2410011, 0x15); - if (rc < 0) - goto error; - rc = WR16(s, 0x2410012, s->config.w92 / 4000); - if (rc < 0) - goto error; -#ifdef ORIG_FW - rc = WR16(s, 0x2410015, 2); - if (rc < 0) - goto error; -#endif - rc = WR16(s, 0x2410017, 0x3973); - if (rc < 0) - goto error; - - s->f_osc = s->config.f_osc * 1000; /* initial estimator */ - - s->config.w56 = 1; - - rc = HI_CfgCommand(s); - if (rc < 0) - goto error; - - rc = write_fw(s, DRXD_InitAtomicRead); - if (rc < 0) - goto error; - - if (s->chip_rev == DRXD_FW_A2) { - rc = WR16(s, 0x2150013, 0); - if (rc < 0) - goto error; - } - - rc = WR16_E0(s, 0x0400002, 0); - if (rc < 0) - goto error; - rc = WR16(s, 0x0400002, 0); - if (rc < 0) - goto error; - - if (s->chip_rev == DRXD_FW_A2) { - rc = write_fw(s, DRXD_ResetCEFR); - if (rc < 0) - goto error; - } - rc = write_fw(s, DRXD_microcode); - if (rc < 0) - goto error; - - s->config.w9C = 0x0e; - if (s->flags & F_SET_0D0h) { - s->config.w9C = 0; - rc = RD16(s, 0x0c20010); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc &= ~0x1000; - rc = WR16(s, 0x0c20010, rc); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc = RD16(s, 0x0c20011); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc &= ~0x8; - rc = WR16(s, 0x0c20011, rc); - if (rc < 0) - goto write_DRXD_InitFE_1; - - rc = WR16(s, 0x0c20012, 1); - } - -write_DRXD_InitFE_1: - - rc = write_fw(s, DRXD_InitFE_1); - if (rc < 0) - goto error; - - rc = 1; - if (s->chip_rev == DRXD_FW_B1) { - if (s->flags & F_SET_0D0h) - rc = 0; - } else { - if (s->flags & F_SET_0D0h) - rc = 4; - } - - rc = WR16(s, 0x0C20012, rc); - if (rc < 0) - goto error; - - rc = WR16(s, 0x0C20013, s->config.w9E); - if (rc < 0) - goto error; - rc = WR16(s, 0x0C20015, s->config.w9C); - if (rc < 0) - goto error; - - rc = write_fw(s, DRXD_InitFE_2); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitFT); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitCP); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitCE); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitEQ); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitEC); - if (rc < 0) - goto error; - rc = write_fw(s, DRXD_InitSC); - if (rc < 0) - goto error; - - rc = SetCfgIfAgc(s, &s->config.ifagc); - if (rc < 0) - goto error; - - rc = SetCfgRfAgc(s, &s->config.rfagc); - if (rc < 0) - goto error; - - rc = ConfigureMPEGOutput(s, 1); - rc = WR16(s, 0x08201fe, 0x0017); - rc = WR16(s, 0x08201ff, 0x0101); - - s->config.d5C = 0; - s->config.d60 = 1; - s->config.d48 = 1; - -error: - return rc; -} - -static int drx397x_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - return 0; -} - -static int drx397x_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct drx397xD_state *s = fe->demodulator_priv; - - s->config.s20d24 = 1; - - return drx_tune(s, params); -} - -static int drx397x_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings - *fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 10000; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct drx397xD_state *s = fe->demodulator_priv; - int lockstat; - - GetLockStatus(s, &lockstat); - - *status = 0; - if (lockstat & 2) { - CorrectSysClockDeviation(s); - ConfigureMPEGOutput(s, 1); - *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; - } - if (lockstat & 4) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - - return 0; -} - -static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) -{ - *ber = 0; - - return 0; -} - -static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - *snr = 0; - - return 0; -} - -static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct drx397xD_state *s = fe->demodulator_priv; - int rc; - - if (s->config.ifagc.d00 == 2) { - *strength = 0xffff; - return 0; - } - rc = RD16(s, 0x0c20035); - if (rc < 0) { - *strength = 0; - return 0; - } - rc &= 0x3ff; - /* Signal strength is calculated using the following formula: - * - * a = 2200 * 150 / (2200 + 150); - * a = a * 3300 / (a + 820); - * b = 2200 * 3300 / (2200 + 820); - * c = (((b-a) * rc) >> 10 + a) << 4; - * strength = ~c & 0xffff; - * - * The following does the same but with less rounding errors: - */ - *strength = ~(7720 + (rc * 30744 >> 10)); - - return 0; -} - -static int drx397x_read_ucblocks(struct dvb_frontend *fe, - unsigned int *ucblocks) -{ - *ucblocks = 0; - - return 0; -} - -static int drx397x_sleep(struct dvb_frontend *fe) -{ - return 0; -} - -static void drx397x_release(struct dvb_frontend *fe) -{ - struct drx397xD_state *s = fe->demodulator_priv; - printk(KERN_INFO "%s: release demodulator\n", mod_name); - if (s) { - drx_release_fw(s); - kfree(s); - } - -} - -static struct dvb_frontend_ops drx397x_ops = { - - .info = { - .name = "Micronas DRX397xD DVB-T Frontend", - .type = FE_OFDM, - .frequency_min = 47125000, - .frequency_max = 855250000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = /* 0x0C01B2EAE */ - FE_CAN_FEC_1_2 | /* = 0x2, */ - FE_CAN_FEC_2_3 | /* = 0x4, */ - FE_CAN_FEC_3_4 | /* = 0x8, */ - FE_CAN_FEC_5_6 | /* = 0x20, */ - FE_CAN_FEC_7_8 | /* = 0x80, */ - FE_CAN_FEC_AUTO | /* = 0x200, */ - FE_CAN_QPSK | /* = 0x400, */ - FE_CAN_QAM_16 | /* = 0x800, */ - FE_CAN_QAM_64 | /* = 0x2000, */ - FE_CAN_QAM_AUTO | /* = 0x10000, */ - FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */ - FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */ - FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */ - FE_CAN_RECOVER | /* = 0x40000000, */ - FE_CAN_MUTE_TS /* = 0x80000000 */ - }, - - .release = drx397x_release, - .init = drx397x_init, - .sleep = drx397x_sleep, - - .set_frontend = drx397x_set_frontend, - .get_tune_settings = drx397x_get_tune_settings, - .get_frontend = drx397x_get_frontend, - - .read_status = drx397x_read_status, - .read_snr = drx397x_read_snr, - .read_signal_strength = drx397x_read_signal_strength, - .read_ber = drx397x_read_ber, - .read_ucblocks = drx397x_read_ucblocks, -}; - -struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, - struct i2c_adapter *i2c) -{ - struct drx397xD_state *state; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); - if (!state) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct drx397xD_config)); - - /* check if the demod is there */ - if (RD16(state, 0x2410019) < 0) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &drx397x_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(drx397xD_attach); - -MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); -MODULE_AUTHOR("Henk Vergonet"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h deleted file mode 100644 index ba05d17290c..00000000000 --- a/drivers/media/dvb/frontends/drx397xD.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Driver for Micronas DVB-T drx397xD demodulator - * - * Copyright (C) 2007 Henk vergonet <Henk.Vergonet@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef _DRX397XD_H_INCLUDED -#define _DRX397XD_H_INCLUDED - -#include <linux/dvb/frontend.h> - -#define DRX_F_STEPSIZE 166667 -#define DRX_F_OFFSET 36000000 - -#define I2C_ADR_C0(x) \ -( cpu_to_le32( \ - (u32)( \ - (((u32)(x) & (u32)0x000000ffUL) ) | \ - (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ - (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \ - ( (u32)0x00c00000UL) \ - )) \ -) - -#define I2C_ADR_E0(x) \ -( cpu_to_le32( \ - (u32)( \ - (((u32)(x) & (u32)0x000000ffUL) ) | \ - (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ - (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \ - ( (u32)0x00e00000UL) \ - )) \ -) - -struct drx397xD_CfgRfAgc /* 0x7c */ -{ - int d00; /* 2 */ - u16 w04; - u16 w06; -}; - -struct drx397xD_CfgIfAgc /* 0x68 */ -{ - int d00; /* 0 */ - u16 w04; /* 0 */ - u16 w06; - u16 w08; - u16 w0A; - u16 w0C; -}; - -struct drx397xD_s20 { - int d04; - u32 d18; - u32 d1C; - u32 d20; - u32 d14; - u32 d24; - u32 d0C; - u32 d08; -}; - -struct drx397xD_config -{ - /* demodulator's I2C address */ - u8 demod_address; /* 0x0f */ - - struct drx397xD_CfgIfAgc ifagc; /* 0x68 */ - struct drx397xD_CfgRfAgc rfagc; /* 0x7c */ - u32 s20d24; - - /* HI_CfgCommand parameters */ - u16 w50, w52, /* w54, */ w56; - - int d5C; - int d60; - int d48; - int d28; - - u32 f_if; /* d14: intermediate frequency [Hz] */ - /* 36000000 on Cinergy 2400i DT */ - /* 42800000 on Pinnacle Hybrid PRO 330e */ - - u16 f_osc; /* s66: 48000 oscillator frequency [kHz] */ - - u16 w92; /* 20000 */ - - u16 wA0; - u16 w98; - u16 w9A; - - u16 w9C; /* 0xe0 */ - u16 w9E; /* 0x00 */ - - /* used for signal strength calculations in - drx397x_read_signal_strength - */ - u16 ss78; // 2200 - u16 ss7A; // 150 - u16 ss76; // 820 -}; - -#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE)) -extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_DRX397XD */ - -#endif /* _DRX397XD_H_INCLUDED */ diff --git a/drivers/media/dvb/frontends/drx397xD_fw.h b/drivers/media/dvb/frontends/drx397xD_fw.h deleted file mode 100644 index c8b44c1e807..00000000000 --- a/drivers/media/dvb/frontends/drx397xD_fw.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Firmware definitions for Micronas drx397xD - * - * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; If not, see <http://www.gnu.org/licenses/>. - */ - -#ifdef _FW_ENTRY - _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0, DRXD_FW_A2 ), - _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1, DRXD_FW_B1 ), -#undef _FW_ENTRY -#endif /* _FW_ENTRY */ - -#ifdef _BLOB_ENTRY - _BLOB_ENTRY("InitAtomicRead", DRXD_InitAtomicRead = 0 ), - _BLOB_ENTRY("InitCE", DRXD_InitCE ), - _BLOB_ENTRY("InitCP", DRXD_InitCP ), - _BLOB_ENTRY("InitEC", DRXD_InitEC ), - _BLOB_ENTRY("InitEQ", DRXD_InitEQ ), - _BLOB_ENTRY("InitFE_1", DRXD_InitFE_1 ), - _BLOB_ENTRY("InitFE_2", DRXD_InitFE_2 ), - _BLOB_ENTRY("InitFT", DRXD_InitFT ), - _BLOB_ENTRY("InitSC", DRXD_InitSC ), - _BLOB_ENTRY("ResetCEFR", DRXD_ResetCEFR ), - _BLOB_ENTRY("ResetECRAM", DRXD_ResetECRAM ), - _BLOB_ENTRY("microcode", DRXD_microcode ), -#undef _BLOB_ENTRY -#endif /* _BLOB_ENTRY */ diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c deleted file mode 100644 index 9f6349964cd..00000000000 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * descriptions + helper functions for simple dvb plls. - * - * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "dvb-pll.h" - -struct dvb_pll_priv { - /* pll number */ - int nr; - - /* i2c details */ - int pll_i2c_address; - struct i2c_adapter *i2c; - - /* the PLL descriptor */ - struct dvb_pll_desc *pll_desc; - - /* cached frequency/bandwidth */ - u32 frequency; - u32 bandwidth; -}; - -#define DVB_PLL_MAX 64 - -static unsigned int dvb_pll_devcount; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable verbose debug messages"); - -static unsigned int id[DVB_PLL_MAX] = - { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED }; -module_param_array(id, int, NULL, 0644); -MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)"); - -/* ----------------------------------------------------------- */ - -struct dvb_pll_desc { - char *name; - u32 min; - u32 max; - u32 iffreq; - void (*set)(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params); - u8 *initdata; - u8 *sleepdata; - int count; - struct { - u32 limit; - u32 stepsize; - u8 config; - u8 cb; - } entries[12]; -}; - -/* ----------------------------------------------------------- */ -/* descriptions */ - -static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { - .name = "Thomson dtt7579", - .min = 177000000, - .max = 858000000, - .iffreq= 36166667, - .sleepdata = (u8[]){ 2, 0xb4, 0x03 }, - .count = 4, - .entries = { - { 443250000, 166667, 0xb4, 0x02 }, - { 542000000, 166667, 0xb4, 0x08 }, - { 771000000, 166667, 0xbc, 0x08 }, - { 999999999, 166667, 0xf4, 0x08 }, - }, -}; - -static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) - buf[3] |= 0x10; -} - -static struct dvb_pll_desc dvb_pll_thomson_dtt759x = { - .name = "Thomson dtt759x", - .min = 177000000, - .max = 896000000, - .set = thomson_dtt759x_bw, - .iffreq= 36166667, - .sleepdata = (u8[]){ 2, 0x84, 0x03 }, - .count = 5, - .entries = { - { 264000000, 166667, 0xb4, 0x02 }, - { 470000000, 166667, 0xbc, 0x02 }, - { 735000000, 166667, 0xbc, 0x08 }, - { 835000000, 166667, 0xf4, 0x08 }, - { 999999999, 166667, 0xfc, 0x08 }, - }, -}; - -static struct dvb_pll_desc dvb_pll_lg_z201 = { - .name = "LG z201", - .min = 174000000, - .max = 862000000, - .iffreq= 36166667, - .sleepdata = (u8[]){ 2, 0xbc, 0x03 }, - .count = 5, - .entries = { - { 157500000, 166667, 0xbc, 0x01 }, - { 443250000, 166667, 0xbc, 0x02 }, - { 542000000, 166667, 0xbc, 0x04 }, - { 830000000, 166667, 0xf4, 0x04 }, - { 999999999, 166667, 0xfc, 0x04 }, - }, -}; - -static struct dvb_pll_desc dvb_pll_unknown_1 = { - .name = "unknown 1", /* used by dntv live dvb-t */ - .min = 174000000, - .max = 862000000, - .iffreq= 36166667, - .count = 9, - .entries = { - { 150000000, 166667, 0xb4, 0x01 }, - { 173000000, 166667, 0xbc, 0x01 }, - { 250000000, 166667, 0xb4, 0x02 }, - { 400000000, 166667, 0xbc, 0x02 }, - { 420000000, 166667, 0xf4, 0x02 }, - { 470000000, 166667, 0xfc, 0x02 }, - { 600000000, 166667, 0xbc, 0x08 }, - { 730000000, 166667, 0xf4, 0x08 }, - { 999999999, 166667, 0xfc, 0x08 }, - }, -}; - -/* Infineon TUA6010XS - * used in Thomson Cable Tuner - */ -static struct dvb_pll_desc dvb_pll_tua6010xs = { - .name = "Infineon TUA6010XS", - .min = 44250000, - .max = 858000000, - .iffreq= 36125000, - .count = 3, - .entries = { - { 115750000, 62500, 0x8e, 0x03 }, - { 403250000, 62500, 0x8e, 0x06 }, - { 999999999, 62500, 0x8e, 0x85 }, - }, -}; - -/* Panasonic env57h1xd5 (some Philips PLL ?) */ -static struct dvb_pll_desc dvb_pll_env57h1xd5 = { - .name = "Panasonic ENV57H1XD5", - .min = 44250000, - .max = 858000000, - .iffreq= 36125000, - .count = 4, - .entries = { - { 153000000, 166667, 0xc2, 0x41 }, - { 470000000, 166667, 0xc2, 0x42 }, - { 526000000, 166667, 0xc2, 0x84 }, - { 999999999, 166667, 0xc2, 0xa4 }, - }, -}; - -/* Philips TDA6650/TDA6651 - * used in Panasonic ENV77H11D5 - */ -static void tda665x_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x08; -} - -static struct dvb_pll_desc dvb_pll_tda665x = { - .name = "Philips TDA6650/TDA6651", - .min = 44250000, - .max = 858000000, - .set = tda665x_bw, - .iffreq= 36166667, - .initdata = (u8[]){ 4, 0x0b, 0xf5, 0x85, 0xab }, - .count = 12, - .entries = { - { 93834000, 166667, 0xca, 0x61 /* 011 0 0 0 01 */ }, - { 123834000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, - { 161000000, 166667, 0xca, 0xa1 /* 101 0 0 0 01 */ }, - { 163834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 253834000, 166667, 0xca, 0x62 /* 011 0 0 0 10 */ }, - { 383834000, 166667, 0xca, 0xa2 /* 101 0 0 0 10 */ }, - { 443834000, 166667, 0xca, 0xc2 /* 110 0 0 0 10 */ }, - { 444000000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, - { 583834000, 166667, 0xca, 0x64 /* 011 0 0 1 00 */ }, - { 793834000, 166667, 0xca, 0xa4 /* 101 0 0 1 00 */ }, - { 444834000, 166667, 0xca, 0xc4 /* 110 0 0 1 00 */ }, - { 861000000, 166667, 0xca, 0xe4 /* 111 0 0 1 00 */ }, - } -}; - -/* Infineon TUA6034 - * used in LG TDTP E102P - */ -static void tua6034_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) - buf[3] |= 0x08; -} - -static struct dvb_pll_desc dvb_pll_tua6034 = { - .name = "Infineon TUA6034", - .min = 44250000, - .max = 858000000, - .iffreq= 36166667, - .count = 3, - .set = tua6034_bw, - .entries = { - { 174500000, 62500, 0xce, 0x01 }, - { 230000000, 62500, 0xce, 0x02 }, - { 999999999, 62500, 0xce, 0x04 }, - }, -}; - -/* ALPS TDED4 - * used in Nebula-Cards and USB boxes - */ -static void tded4_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x04; -} - -static struct dvb_pll_desc dvb_pll_tded4 = { - .name = "ALPS TDED4", - .min = 47000000, - .max = 863000000, - .iffreq= 36166667, - .set = tded4_bw, - .count = 4, - .entries = { - { 153000000, 166667, 0x85, 0x01 }, - { 470000000, 166667, 0x85, 0x02 }, - { 823000000, 166667, 0x85, 0x08 }, - { 999999999, 166667, 0x85, 0x88 }, - } -}; - -/* ALPS TDHU2 - * used in AverTVHD MCE A180 - */ -static struct dvb_pll_desc dvb_pll_tdhu2 = { - .name = "ALPS TDHU2", - .min = 54000000, - .max = 864000000, - .iffreq= 44000000, - .count = 4, - .entries = { - { 162000000, 62500, 0x85, 0x01 }, - { 426000000, 62500, 0x85, 0x02 }, - { 782000000, 62500, 0x85, 0x08 }, - { 999999999, 62500, 0x85, 0x88 }, - } -}; - -/* Samsung TBMV30111IN / TBMV30712IN1 - * used in Air2PC ATSC - 2nd generation (nxt2002) - */ -static struct dvb_pll_desc dvb_pll_samsung_tbmv = { - .name = "Samsung TBMV30111IN / TBMV30712IN1", - .min = 54000000, - .max = 860000000, - .iffreq= 44000000, - .count = 6, - .entries = { - { 172000000, 166667, 0xb4, 0x01 }, - { 214000000, 166667, 0xb4, 0x02 }, - { 467000000, 166667, 0xbc, 0x02 }, - { 721000000, 166667, 0xbc, 0x08 }, - { 841000000, 166667, 0xf4, 0x08 }, - { 999999999, 166667, 0xfc, 0x02 }, - } -}; - -/* - * Philips SD1878 Tuner. - */ -static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { - .name = "Philips SD1878", - .min = 950000, - .max = 2150000, - .iffreq= 249, /* zero-IF, offset 249 is to round up */ - .count = 4, - .entries = { - { 1250000, 500, 0xc4, 0x00}, - { 1450000, 500, 0xc4, 0x40}, - { 2050000, 500, 0xc4, 0x80}, - { 2150000, 500, 0xc4, 0xc0}, - }, -}; - -static void opera1_bw(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[2] |= 0x08; -} - -static struct dvb_pll_desc dvb_pll_opera1 = { - .name = "Opera Tuner", - .min = 900000, - .max = 2250000, - .iffreq= 0, - .set = opera1_bw, - .count = 8, - .entries = { - { 1064000, 500, 0xe5, 0xc6 }, - { 1169000, 500, 0xe5, 0xe6 }, - { 1299000, 500, 0xe5, 0x24 }, - { 1444000, 500, 0xe5, 0x44 }, - { 1606000, 500, 0xe5, 0x64 }, - { 1777000, 500, 0xe5, 0x84 }, - { 1941000, 500, 0xe5, 0xa4 }, - { 2250000, 500, 0xe5, 0xc4 }, - } -}; - -static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - struct i2c_msg msg = { - .addr = priv->pll_i2c_address, - .flags = 0, - .buf = buf, - .len = 4 - }; - int result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - result = i2c_transfer(priv->i2c, &msg, 1); - if (result != 1) - printk(KERN_ERR "%s: i2c_transfer failed:%d", - __func__, result); - - buf[2] = 0x9e; - buf[3] = 0x90; - - return; -} - -/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */ -static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = { - .name = "Samsung DTOS403IH102A", - .min = 44250000, - .max = 858000000, - .iffreq = 36125000, - .count = 8, - .set = samsung_dtos403ih102a_set, - .entries = { - { 135000000, 62500, 0xbe, 0x01 }, - { 177000000, 62500, 0xf6, 0x01 }, - { 370000000, 62500, 0xbe, 0x02 }, - { 450000000, 62500, 0xf6, 0x02 }, - { 466000000, 62500, 0xfe, 0x02 }, - { 538000000, 62500, 0xbe, 0x08 }, - { 826000000, 62500, 0xf6, 0x08 }, - { 999999999, 62500, 0xfe, 0x08 }, - } -}; - -/* ----------------------------------------------------------- */ - -static struct dvb_pll_desc *pll_list[] = { - [DVB_PLL_UNDEFINED] = NULL, - [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579, - [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x, - [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201, - [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1, - [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs, - [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5, - [DVB_PLL_TUA6034] = &dvb_pll_tua6034, - [DVB_PLL_TDA665X] = &dvb_pll_tda665x, - [DVB_PLL_TDED4] = &dvb_pll_tded4, - [DVB_PLL_TDHU2] = &dvb_pll_tdhu2, - [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, - [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, - [DVB_PLL_OPERA1] = &dvb_pll_opera1, - [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a, -}; - -/* ----------------------------------------------------------- */ -/* code */ - -static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, - const struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - struct dvb_pll_desc *desc = priv->pll_desc; - u32 div; - int i; - - if (params->frequency != 0 && (params->frequency < desc->min || - params->frequency > desc->max)) - return -EINVAL; - - for (i = 0; i < desc->count; i++) { - if (params->frequency > desc->entries[i].limit) - continue; - break; - } - - if (debug) - printk("pll: %s: freq=%d | i=%d/%d\n", desc->name, - params->frequency, i, desc->count); - if (i == desc->count) - return -EINVAL; - - div = (params->frequency + desc->iffreq + - desc->entries[i].stepsize/2) / desc->entries[i].stepsize; - buf[0] = div >> 8; - buf[1] = div & 0xff; - buf[2] = desc->entries[i].config; - buf[3] = desc->entries[i].cb; - - if (desc->set) - desc->set(fe, buf, params); - - if (debug) - printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", - desc->name, div, buf[0], buf[1], buf[2], buf[3]); - - // calculate the frequency we set it to - return (div * desc->entries[i].stepsize) - desc->iffreq; -} - -static int dvb_pll_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int dvb_pll_sleep(struct dvb_frontend *fe) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - - if (priv->i2c == NULL) - return -EINVAL; - - if (priv->pll_desc->sleepdata) { - struct i2c_msg msg = { .flags = 0, - .addr = priv->pll_i2c_address, - .buf = priv->pll_desc->sleepdata + 1, - .len = priv->pll_desc->sleepdata[0] }; - - int result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - return 0; - } - /* Shouldn't be called when initdata is NULL, maybe BUG()? */ - return -EINVAL; -} - -static int dvb_pll_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - u8 buf[4]; - struct i2c_msg msg = - { .addr = priv->pll_i2c_address, .flags = 0, - .buf = buf, .len = sizeof(buf) }; - int result; - u32 frequency = 0; - - if (priv->i2c == NULL) - return -EINVAL; - - if ((result = dvb_pll_configure(fe, buf, params)) < 0) - return result; - else - frequency = result; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - - priv->frequency = frequency; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; - - return 0; -} - -static int dvb_pll_calc_regs(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params, - u8 *buf, int buf_len) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - int result; - u32 frequency = 0; - - if (buf_len < 5) - return -EINVAL; - - if ((result = dvb_pll_configure(fe, buf+1, params)) < 0) - return result; - else - frequency = result; - - buf[0] = priv->pll_i2c_address; - - priv->frequency = frequency; - priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; - - return 5; -} - -static int dvb_pll_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static int dvb_pll_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - *bandwidth = priv->bandwidth; - return 0; -} - -static int dvb_pll_init(struct dvb_frontend *fe) -{ - struct dvb_pll_priv *priv = fe->tuner_priv; - - if (priv->i2c == NULL) - return -EINVAL; - - if (priv->pll_desc->initdata) { - struct i2c_msg msg = { .flags = 0, - .addr = priv->pll_i2c_address, - .buf = priv->pll_desc->initdata + 1, - .len = priv->pll_desc->initdata[0] }; - - int result; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { - return result; - } - return 0; - } - /* Shouldn't be called when initdata is NULL, maybe BUG()? */ - return -EINVAL; -} - -static struct dvb_tuner_ops dvb_pll_tuner_ops = { - .release = dvb_pll_release, - .sleep = dvb_pll_sleep, - .init = dvb_pll_init, - .set_params = dvb_pll_set_params, - .calc_regs = dvb_pll_calc_regs, - .get_frequency = dvb_pll_get_frequency, - .get_bandwidth = dvb_pll_get_bandwidth, -}; - -struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, - struct i2c_adapter *i2c, - unsigned int pll_desc_id) -{ - u8 b1 [] = { 0 }; - struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, - .buf = b1, .len = 1 }; - struct dvb_pll_priv *priv = NULL; - int ret; - struct dvb_pll_desc *desc; - - if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) && - (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list))) - pll_desc_id = id[dvb_pll_devcount]; - - BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list)); - - desc = pll_list[pll_desc_id]; - - if (i2c != NULL) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer (i2c, &msg, 1); - if (ret != 1) - return NULL; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->pll_i2c_address = pll_addr; - priv->i2c = i2c; - priv->pll_desc = desc; - priv->nr = dvb_pll_devcount++; - - memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - strncpy(fe->ops.tuner_ops.info.name, desc->name, - sizeof(fe->ops.tuner_ops.info.name)); - fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_max = desc->max; - if (!desc->initdata) - fe->ops.tuner_ops.init = NULL; - if (!desc->sleepdata) - fe->ops.tuner_ops.sleep = NULL; - - fe->tuner_priv = priv; - - if ((debug) || (id[priv->nr] == pll_desc_id)) { - printk("dvb-pll[%d]", priv->nr); - if (i2c != NULL) - printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); - printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name, - id[priv->nr] == pll_desc_id ? - "insmod option" : "autodetected"); - } - - return fe; -} -EXPORT_SYMBOL(dvb_pll_attach); - -MODULE_DESCRIPTION("dvb pll library"); -MODULE_AUTHOR("Gerd Knorr"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h deleted file mode 100644 index 05239f579cc..00000000000 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * descriptions + helper functions for simple dvb plls. - */ - -#ifndef __DVB_PLL_H__ -#define __DVB_PLL_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -#define DVB_PLL_UNDEFINED 0 -#define DVB_PLL_THOMSON_DTT7579 1 -#define DVB_PLL_THOMSON_DTT759X 2 -#define DVB_PLL_LG_Z201 3 -#define DVB_PLL_UNKNOWN_1 4 -#define DVB_PLL_TUA6010XS 5 -#define DVB_PLL_ENV57H1XD5 6 -#define DVB_PLL_TUA6034 7 -#define DVB_PLL_TDA665X 8 -#define DVB_PLL_TDED4 9 -#define DVB_PLL_TDHU2 10 -#define DVB_PLL_SAMSUNG_TBMV 11 -#define DVB_PLL_PHILIPS_SD1878_TDA8261 12 -#define DVB_PLL_OPERA1 13 -#define DVB_PLL_SAMSUNG_DTOS403IH102A 14 - -/** - * Attach a dvb-pll to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param pll_addr i2c address of the PLL (if used). - * @param i2c i2c adapter to use (set to NULL if not used). - * @param pll_desc_id dvb_pll_desc to use. - * @return Frontend pointer on success, NULL on failure - */ -#if defined(CONFIG_DVB_PLL) || (defined(CONFIG_DVB_PLL_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, - int pll_addr, - struct i2c_adapter *i2c, - unsigned int pll_desc_id); -#else -static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, - int pll_addr, - struct i2c_adapter *i2c, - unsigned int pll_desc_id) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c deleted file mode 100644 index db8a937cc63..00000000000 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Driver for Dummy Frontend - * - * Written by Emard <emard@softhome.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "dvb_dummy_fe.h" - - -struct dvb_dummy_fe_state { - struct dvb_frontend frontend; -}; - - -static int dvb_dummy_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - *status = FE_HAS_SIGNAL - | FE_HAS_CARRIER - | FE_HAS_VITERBI - | FE_HAS_SYNC - | FE_HAS_LOCK; - - return 0; -} - -static int dvb_dummy_fe_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; - return 0; -} - -static int dvb_dummy_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - *strength = 0; - return 0; -} - -static int dvb_dummy_fe_read_snr(struct dvb_frontend* fe, u16* snr) -{ - *snr = 0; - return 0; -} - -static int dvb_dummy_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - return 0; -} - -static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - return 0; -} - -static int dvb_dummy_fe_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int dvb_dummy_fe_init(struct dvb_frontend* fe) -{ - return 0; -} - -static int dvb_dummy_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - return 0; -} - -static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - return 0; -} - -static void dvb_dummy_fe_release(struct dvb_frontend* fe) -{ - struct dvb_dummy_fe_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops; - -struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) -{ - struct dvb_dummy_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_ofdm_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; - -struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) -{ - struct dvb_dummy_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_qpsk_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dvb_dummy_fe_qam_ops; - -struct dvb_frontend *dvb_dummy_fe_qam_attach(void) -{ - struct dvb_dummy_fe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &dvb_dummy_fe_qam_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops dvb_dummy_fe_ofdm_ops = { - - .info = { - .name = "Dummy DVB-T", - .type = FE_OFDM, - .frequency_min = 0, - .frequency_max = 863250000, - .frequency_stepsize = 62500, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = dvb_dummy_fe_release, - - .init = dvb_dummy_fe_init, - .sleep = dvb_dummy_fe_sleep, - - .set_frontend = dvb_dummy_fe_set_frontend, - .get_frontend = dvb_dummy_fe_get_frontend, - - .read_status = dvb_dummy_fe_read_status, - .read_ber = dvb_dummy_fe_read_ber, - .read_signal_strength = dvb_dummy_fe_read_signal_strength, - .read_snr = dvb_dummy_fe_read_snr, - .read_ucblocks = dvb_dummy_fe_read_ucblocks, -}; - -static struct dvb_frontend_ops dvb_dummy_fe_qam_ops = { - - .info = { - .name = "Dummy DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 51000000, - .frequency_max = 858000000, - .symbol_rate_min = (57840000/2)/64, /* SACLK/64 == (XIN/2)/64 */ - .symbol_rate_max = (57840000/2)/4, /* SACLK/4 */ - .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO - }, - - .release = dvb_dummy_fe_release, - - .init = dvb_dummy_fe_init, - .sleep = dvb_dummy_fe_sleep, - - .set_frontend = dvb_dummy_fe_set_frontend, - .get_frontend = dvb_dummy_fe_get_frontend, - - .read_status = dvb_dummy_fe_read_status, - .read_ber = dvb_dummy_fe_read_ber, - .read_signal_strength = dvb_dummy_fe_read_signal_strength, - .read_snr = dvb_dummy_fe_read_snr, - .read_ucblocks = dvb_dummy_fe_read_ucblocks, -}; - -static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops = { - - .info = { - .name = "Dummy DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 250, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = dvb_dummy_fe_release, - - .init = dvb_dummy_fe_init, - .sleep = dvb_dummy_fe_sleep, - - .set_frontend = dvb_dummy_fe_set_frontend, - .get_frontend = dvb_dummy_fe_get_frontend, - - .read_status = dvb_dummy_fe_read_status, - .read_ber = dvb_dummy_fe_read_ber, - .read_signal_strength = dvb_dummy_fe_read_signal_strength, - .read_snr = dvb_dummy_fe_read_snr, - .read_ucblocks = dvb_dummy_fe_read_ucblocks, - - .set_voltage = dvb_dummy_fe_set_voltage, - .set_tone = dvb_dummy_fe_set_tone, -}; - -MODULE_DESCRIPTION("DVB DUMMY Frontend"); -MODULE_AUTHOR("Emard"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(dvb_dummy_fe_ofdm_attach); -EXPORT_SYMBOL(dvb_dummy_fe_qam_attach); -EXPORT_SYMBOL(dvb_dummy_fe_qpsk_attach); diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h deleted file mode 100644 index 8210f19d56c..00000000000 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Driver for Dummy Frontend - * - * Written by Emard <emard@softhome.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef DVB_DUMMY_FE_H -#define DVB_DUMMY_FE_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void); -extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void); -extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void); - -#endif // DVB_DUMMY_FE_H diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h deleted file mode 100644 index fa79b7c83dd..00000000000 --- a/drivers/media/dvb/frontends/eds1547.h +++ /dev/null @@ -1,133 +0,0 @@ -/* eds1547.h Earda EDS-1547 tuner support -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ - -#ifndef EDS1547 -#define EDS1547 - -static u8 stv0288_earda_inittab[] = { - 0x01, 0x57, - 0x02, 0x20, - 0x03, 0x8e, - 0x04, 0x8e, - 0x05, 0x12, - 0x06, 0x00, - 0x07, 0x00, - 0x09, 0x00, - 0x0a, 0x04, - 0x0b, 0x00, - 0x0c, 0x00, - 0x0d, 0x00, - 0x0e, 0xd4, - 0x0f, 0x30, - 0x11, 0x44, - 0x12, 0x03, - 0x13, 0x48, - 0x14, 0x84, - 0x15, 0x45, - 0x16, 0xb7, - 0x17, 0x9c, - 0x18, 0x00, - 0x19, 0xa6, - 0x1a, 0x88, - 0x1b, 0x8f, - 0x1c, 0xf0, - 0x20, 0x0b, - 0x21, 0x54, - 0x22, 0x00, - 0x23, 0x00, - 0x2b, 0xff, - 0x2c, 0xf7, - 0x30, 0x00, - 0x31, 0x1e, - 0x32, 0x14, - 0x33, 0x0f, - 0x34, 0x09, - 0x35, 0x0c, - 0x36, 0x05, - 0x37, 0x2f, - 0x38, 0x16, - 0x39, 0xbd, - 0x3a, 0x00, - 0x3b, 0x13, - 0x3c, 0x11, - 0x3d, 0x30, - 0x40, 0x63, - 0x41, 0x04, - 0x42, 0x60, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x4a, 0x00, - 0x50, 0x10, - 0x51, 0x36, - 0x52, 0x09, - 0x53, 0x94, - 0x54, 0x62, - 0x55, 0x29, - 0x56, 0x64, - 0x57, 0x2b, - 0x58, 0x54, - 0x59, 0x86, - 0x5a, 0x00, - 0x5b, 0x9b, - 0x5c, 0x08, - 0x5d, 0x7f, - 0x5e, 0x00, - 0x5f, 0xff, - 0x70, 0x00, - 0x71, 0x00, - 0x72, 0x00, - 0x74, 0x00, - 0x75, 0x00, - 0x76, 0x00, - 0x81, 0x00, - 0x82, 0x3f, - 0x83, 0x3f, - 0x84, 0x00, - 0x85, 0x00, - 0x88, 0x00, - 0x89, 0x00, - 0x8a, 0x00, - 0x8b, 0x00, - 0x8c, 0x00, - 0x90, 0x00, - 0x91, 0x00, - 0x92, 0x00, - 0x93, 0x00, - 0x94, 0x1c, - 0x97, 0x00, - 0xa0, 0x48, - 0xa1, 0x00, - 0xb0, 0xb8, - 0xb1, 0x3a, - 0xb2, 0x10, - 0xb3, 0x82, - 0xb4, 0x80, - 0xb5, 0x82, - 0xb6, 0x82, - 0xb7, 0x82, - 0xb8, 0x20, - 0xb9, 0x00, - 0xf0, 0x00, - 0xf1, 0x00, - 0xf2, 0xc0, - 0xff,0xff, -}; - -static struct stv0288_config earda_config = { - .demod_address = 0x68, - .min_delay_ms = 100, - .inittab = stv0288_earda_inittab, -}; - -#endif diff --git a/drivers/media/dvb/frontends/isl6405.c b/drivers/media/dvb/frontends/isl6405.c deleted file mode 100644 index 33d33f4d886..00000000000 --- a/drivers/media/dvb/frontends/isl6405.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * isl6405.c - driver for dual lnb supply and control ic ISL6405 - * - * Copyright (C) 2008 Hartmut Hackmann - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "isl6405.h" - -struct isl6405 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - u8 i2c_addr; -}; - -static int isl6405_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0, - .buf = &isl6405->config, - .len = sizeof(isl6405->config) }; - - if (isl6405->override_or & 0x80) { - isl6405->config &= ~(ISL6405_VSEL2 | ISL6405_EN2); - switch (voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6405->config |= ISL6405_EN2; - break; - case SEC_VOLTAGE_18: - isl6405->config |= (ISL6405_EN2 | ISL6405_VSEL2); - break; - default: - return -EINVAL; - } - } else { - isl6405->config &= ~(ISL6405_VSEL1 | ISL6405_EN1); - switch (voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6405->config |= ISL6405_EN1; - break; - case SEC_VOLTAGE_18: - isl6405->config |= (ISL6405_EN1 | ISL6405_VSEL1); - break; - default: - return -EINVAL; - }; - } - isl6405->config |= isl6405->override_or; - isl6405->config &= isl6405->override_and; - - return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int isl6405_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct isl6405 *isl6405 = (struct isl6405 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6405->i2c_addr, .flags = 0, - .buf = &isl6405->config, - .len = sizeof(isl6405->config) }; - - if (isl6405->override_or & 0x80) { - if (arg) - isl6405->config |= ISL6405_LLC2; - else - isl6405->config &= ~ISL6405_LLC2; - } else { - if (arg) - isl6405->config |= ISL6405_LLC1; - else - isl6405->config &= ~ISL6405_LLC1; - } - isl6405->config |= isl6405->override_or; - isl6405->config &= isl6405->override_and; - - return (i2c_transfer(isl6405->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void isl6405_release(struct dvb_frontend *fe) -{ - /* power off */ - isl6405_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free */ - kfree(fe->sec_priv); - fe->sec_priv = NULL; -} - -struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - u8 i2c_addr, u8 override_set, u8 override_clear) -{ - struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL); - if (!isl6405) - return NULL; - - /* default configuration */ - if (override_set & 0x80) - isl6405->config = ISL6405_ISEL2; - else - isl6405->config = ISL6405_ISEL1; - isl6405->i2c = i2c; - isl6405->i2c_addr = i2c_addr; - fe->sec_priv = isl6405; - - /* bits which should be forced to '1' */ - isl6405->override_or = override_set; - - /* bits which should be forced to '0' */ - isl6405->override_and = ~override_clear; - - /* detect if it is present or not */ - if (isl6405_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(isl6405); - fe->sec_priv = NULL; - return NULL; - } - - /* install release callback */ - fe->ops.release_sec = isl6405_release; - - /* override frontend ops */ - fe->ops.set_voltage = isl6405_set_voltage; - fe->ops.enable_high_lnb_voltage = isl6405_enable_high_lnb_voltage; - - return fe; -} -EXPORT_SYMBOL(isl6405_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405"); -MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/isl6405.h b/drivers/media/dvb/frontends/isl6405.h deleted file mode 100644 index 1c793d37576..00000000000 --- a/drivers/media/dvb/frontends/isl6405.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * isl6405.h - driver for dual lnb supply and control ic ISL6405 - * - * Copyright (C) 2008 Hartmut Hackmann - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _ISL6405_H -#define _ISL6405_H - -#include <linux/dvb/frontend.h> - -/* system register bits */ - -/* this bit selects register (control) 1 or 2 - note that the bit maps are different */ - -#define ISL6405_SR 0x80 - -/* SR = 0 */ -#define ISL6405_OLF1 0x01 -#define ISL6405_EN1 0x02 -#define ISL6405_VSEL1 0x04 -#define ISL6405_LLC1 0x08 -#define ISL6405_ENT1 0x10 -#define ISL6405_ISEL1 0x20 -#define ISL6405_DCL 0x40 - -/* SR = 1 */ -#define ISL6405_OLF2 0x01 -#define ISL6405_OTF 0x02 -#define ISL6405_EN2 0x04 -#define ISL6405_VSEL2 0x08 -#define ISL6405_LLC2 0x10 -#define ISL6405_ENT2 0x20 -#define ISL6405_ISEL2 0x40 - -#if defined(CONFIG_DVB_ISL6405) || (defined(CONFIG_DVB_ISL6405_MODULE) && defined(MODULE)) -/* override_set and override_clear control which system register bits (above) - * to always set & clear - */ -extern struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, - u8 i2c_addr, u8 override_set, u8 override_clear); -#else -static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_ISL6405 */ - -#endif diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c deleted file mode 100644 index 684c8ec166c..00000000000 --- a/drivers/media/dvb/frontends/isl6421.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * isl6421.h - driver for lnb supply and control ic ISL6421 - * - * Copyright (C) 2006 Andrew de Quincey - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "isl6421.h" - -struct isl6421 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; - u8 i2c_addr; -}; - -static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; - - isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - isl6421->config |= ISL6421_EN1; - break; - case SEC_VOLTAGE_18: - isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); - break; - default: - return -EINVAL; - }; - - isl6421->config |= isl6421->override_or; - isl6421->config &= isl6421->override_and; - - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; - struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, - .buf = &isl6421->config, - .len = sizeof(isl6421->config) }; - - if (arg) - isl6421->config |= ISL6421_LLC1; - else - isl6421->config &= ~ISL6421_LLC1; - - isl6421->config |= isl6421->override_or; - isl6421->config &= isl6421->override_and; - - return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void isl6421_release(struct dvb_frontend *fe) -{ - /* power off */ - isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free */ - kfree(fe->sec_priv); - fe->sec_priv = NULL; -} - -struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); - if (!isl6421) - return NULL; - - /* default configuration */ - isl6421->config = ISL6421_ISEL1; - isl6421->i2c = i2c; - isl6421->i2c_addr = i2c_addr; - fe->sec_priv = isl6421; - - /* bits which should be forced to '1' */ - isl6421->override_or = override_set; - - /* bits which should be forced to '0' */ - isl6421->override_and = ~override_clear; - - /* detect if it is present or not */ - if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(isl6421); - fe->sec_priv = NULL; - return NULL; - } - - /* install release callback */ - fe->ops.release_sec = isl6421_release; - - /* override frontend ops */ - fe->ops.set_voltage = isl6421_set_voltage; - fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; - - return fe; -} -EXPORT_SYMBOL(isl6421_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); -MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h deleted file mode 100644 index 47e4518a042..00000000000 --- a/drivers/media/dvb/frontends/isl6421.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * isl6421.h - driver for lnb supply and control ic ISL6421 - * - * Copyright (C) 2006 Andrew de Quincey - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _ISL6421_H -#define _ISL6421_H - -#include <linux/dvb/frontend.h> - -/* system register bits */ -#define ISL6421_OLF1 0x01 -#define ISL6421_EN1 0x02 -#define ISL6421_VSEL1 0x04 -#define ISL6421_LLC1 0x08 -#define ISL6421_ENT1 0x10 -#define ISL6421_ISEL1 0x20 -#define ISL6421_DCL 0x40 - -#if defined(CONFIG_DVB_ISL6421) || (defined(CONFIG_DVB_ISL6421_MODULE) && defined(MODULE)) -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear); -#else -static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, - u8 override_set, u8 override_clear) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_ISL6421 - -#endif diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c deleted file mode 100644 index 600dad6b41e..00000000000 --- a/drivers/media/dvb/frontends/itd1000.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" - * - * Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/delay.h> -#include <linux/dvb/frontend.h> -#include <linux/i2c.h> - -#include "dvb_frontend.h" - -#include "itd1000.h" -#include "itd1000_priv.h" - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); - -#define deb(args...) do { \ - if (debug) { \ - printk(KERN_DEBUG "ITD1000: " args);\ - printk("\n"); \ - } \ -} while (0) - -#define warn(args...) do { \ - printk(KERN_WARNING "ITD1000: " args); \ - printk("\n"); \ -} while (0) - -#define info(args...) do { \ - printk(KERN_INFO "ITD1000: " args); \ - printk("\n"); \ -} while (0) - -/* don't write more than one byte with flexcop behind */ -static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len) -{ - u8 buf[1+len]; - struct i2c_msg msg = { - .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1 - }; - buf[0] = reg; - memcpy(&buf[1], v, len); - - /* deb("wr %02x: %02x", reg, v[0]); */ - - if (i2c_transfer(state->i2c, &msg, 1) != 1) { - printk(KERN_WARNING "itd1000 I2C write failed\n"); - return -EREMOTEIO; - } - return 0; -} - -static int itd1000_read_reg(struct itd1000_state *state, u8 reg) -{ - u8 val; - struct i2c_msg msg[2] = { - { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 }, - }; - - /* ugly flexcop workaround */ - 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"); - return -EREMOTEIO; - } - return val; -} - -static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v) -{ - int ret = itd1000_write_regs(state, r, &v, 1); - state->shadow[r] = v; - return ret; -} - - -static struct { - u32 symbol_rate; - u8 pgaext : 4; /* PLLFH */ - u8 bbgvmin : 4; /* BBGVMIN */ -} itd1000_lpf_pga[] = { - { 0, 0x8, 0x3 }, - { 5200000, 0x8, 0x3 }, - { 12200000, 0x4, 0x3 }, - { 15400000, 0x2, 0x3 }, - { 19800000, 0x2, 0x3 }, - { 21500000, 0x2, 0x3 }, - { 24500000, 0x2, 0x3 }, - { 28400000, 0x2, 0x3 }, - { 33400000, 0x2, 0x3 }, - { 34400000, 0x1, 0x4 }, - { 34400000, 0x1, 0x4 }, - { 38400000, 0x1, 0x4 }, - { 38400000, 0x1, 0x4 }, - { 40400000, 0x1, 0x4 }, - { 45400000, 0x1, 0x4 }, -}; - -static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate) -{ - u8 i; - u8 con1 = itd1000_read_reg(state, CON1) & 0xfd; - u8 pllfh = itd1000_read_reg(state, PLLFH) & 0x0f; - u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0; - u8 bw = itd1000_read_reg(state, BW) & 0xf0; - - deb("symbol_rate = %d", 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); - 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)); - break; - } - - itd1000_write_reg(state, CON1, con1 | (0 << 1)); -} - -static struct { - u8 vcorg; - u32 fmax_rg; -} itd1000_vcorg[] = { - { 1, 920000 }, - { 2, 971000 }, - { 3, 1031000 }, - { 4, 1091000 }, - { 5, 1171000 }, - { 6, 1281000 }, - { 7, 1381000 }, - { 8, 500000 }, /* this is intentional. */ - { 9, 1451000 }, - { 10, 1531000 }, - { 11, 1631000 }, - { 12, 1741000 }, - { 13, 1891000 }, - { 14, 2071000 }, - { 15, 2250000 }, -}; - -static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz) -{ - u8 i; - u8 gvbb_i2c = itd1000_read_reg(state, GVBB_I2C) & 0xbf; - u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f; - u8 adcout; - - /* reserved bit again (reset ?) */ - itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6)); - - for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) { - if (freq_khz < itd1000_vcorg[i].fmax_rg) { - itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4)); - msleep(1); - - adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f; - - deb("VCO: %dkHz: %d -> ADCOUT: %d %02x", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c); - - if (adcout > 13) { - if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15)) - itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4)); - } else if (adcout < 2) { - if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9)) - itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4)); - } - break; - } - } -} - -static const struct { - u32 freq; - u8 values[10]; /* RFTR, RFST1 - RFST9 */ -} itd1000_fre_values[] = { - { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } }, - { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } }, - { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } }, - { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } }, - { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } }, - { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } } -}; - - -#define FREF 16 - -static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz) -{ - int i, j; - u32 plln, pllf; - u64 tmp; - - plln = (freq_khz * 1000) / 2 / FREF; - - /* Compute the factional part times 1000 */ - tmp = plln % 1000000; - plln /= 1000000; - - tmp *= 1048576; - do_div(tmp, 1000000); - 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); - - itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */; - itd1000_write_reg(state, PLLNL, plln & 0xff); - itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f)); - itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff); - itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff); - - for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) { - if (freq_khz <= itd1000_fre_values[i].freq) { - deb("fre_values: %d", 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]); - break; - } - } - - itd1000_set_vco(state, freq_khz); -} - -static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct itd1000_state *state = fe->tuner_priv; - u8 pllcon1; - - itd1000_set_lo(state, p->frequency); - itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate); - - pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f; - itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7)); - itd1000_write_reg(state, PLLCON1, pllcon1); - - return 0; -} - -static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct itd1000_state *state = fe->tuner_priv; - *frequency = state->frequency; - return 0; -} - -static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - return 0; -} - -static u8 itd1000_init_tab[][2] = { - { PLLCON1, 0x65 }, /* Register does not change */ - { PLLNH, 0x80 }, /* Bits [7:6] do not change */ - { RESERVED_0X6D, 0x3b }, - { VCO_CHP2_I2C, 0x12 }, - { 0x72, 0xf9 }, /* No such regsister defined */ - { RESERVED_0X73, 0xff }, - { RESERVED_0X74, 0xb2 }, - { RESERVED_0X75, 0xc7 }, - { EXTGVBBRF, 0xf0 }, - { DIVAGCCK, 0x80 }, - { BBTR, 0xa0 }, - { RESERVED_0X7E, 0x4f }, - { 0x82, 0x88 }, /* No such regsister defined */ - { 0x83, 0x80 }, /* No such regsister defined */ - { 0x84, 0x80 }, /* No such regsister defined */ - { RESERVED_0X85, 0x74 }, - { RESERVED_0X86, 0xff }, - { RESERVED_0X88, 0x02 }, - { RESERVED_0X89, 0x16 }, - { RFST0, 0x1f }, - { RESERVED_0X94, 0x66 }, - { RESERVED_0X95, 0x66 }, - { RESERVED_0X96, 0x77 }, - { RESERVED_0X97, 0x99 }, - { RESERVED_0X98, 0xff }, - { RESERVED_0X99, 0xfc }, - { RESERVED_0X9A, 0xba }, - { RESERVED_0X9B, 0xaa }, -}; - -static u8 itd1000_reinit_tab[][2] = { - { VCO_CHP1_I2C, 0x8a }, - { BW, 0x87 }, - { GVBB_I2C, 0x03 }, - { BBGVMIN, 0x03 }, - { CON1, 0x2e }, -}; - - -static int itd1000_init(struct dvb_frontend *fe) -{ - struct itd1000_state *state = fe->tuner_priv; - int i; - - for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++) - itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]); - - for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++) - itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]); - - return 0; -} - -static int itd1000_sleep(struct dvb_frontend *fe) -{ - return 0; -} - -static int itd1000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static const struct dvb_tuner_ops itd1000_tuner_ops = { - .info = { - .name = "Integrant ITD1000", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 125, /* kHz for QPSK frontends */ - }, - - .release = itd1000_release, - - .init = itd1000_init, - .sleep = itd1000_sleep, - - .set_params = itd1000_set_parameters, - .get_frequency = itd1000_get_frequency, - .get_bandwidth = itd1000_get_bandwidth -}; - - -struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) -{ - struct itd1000_state *state = NULL; - u8 i = 0; - - state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - state->cfg = cfg; - state->i2c = i2c; - - i = itd1000_read_reg(state, 0); - if (i != 0) { - kfree(state); - return NULL; - } - info("successfully identified (ID: %d)", i); - - memset(state->shadow, 0xff, sizeof(state->shadow)); - for (i = 0x65; i < 0x9c; i++) - state->shadow[i] = itd1000_read_reg(state, i); - - memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = state; - - return fe; -} -EXPORT_SYMBOL(itd1000_attach); - -MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>"); -MODULE_DESCRIPTION("Integrant ITD1000 driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/itd1000.h b/drivers/media/dvb/frontends/itd1000.h deleted file mode 100644 index 5e18df071b8..00000000000 --- a/drivers/media/dvb/frontends/itd1000.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" - * - * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef ITD1000_H -#define ITD1000_H - -struct dvb_frontend; -struct i2c_adapter; - -struct itd1000_config { - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE)) -extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg); -#else -static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -#endif diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h deleted file mode 100644 index 8cdc54e5790..00000000000 --- a/drivers/media/dvb/frontends/itd1000_priv.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite" - * - * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef ITD1000_PRIV_H -#define ITD1000_PRIV_H - -struct itd1000_state { - struct itd1000_config *cfg; - struct i2c_adapter *i2c; - - u32 frequency; /* contains the value resulting from the LO-setting */ - - /* ugly workaround for flexcop's incapable i2c-controller - * FIXME, if possible - */ - u8 shadow[255]; -}; - -enum itd1000_register { - VCO_CHP1 = 0x65, - VCO_CHP2, - PLLCON1, - PLLNH, - PLLNL, - PLLFH, - PLLFM, - PLLFL, - RESERVED_0X6D, - PLLLOCK, - VCO_CHP2_I2C, - VCO_CHP1_I2C, - BW, - RESERVED_0X73 = 0x73, - RESERVED_0X74, - RESERVED_0X75, - GVBB, - GVRF, - GVBB_I2C, - EXTGVBBRF, - DIVAGCCK, - BBTR, - RFTR, - BBGVMIN, - RESERVED_0X7E, - RESERVED_0X85 = 0x85, - RESERVED_0X86, - CON1, - RESERVED_0X88, - RESERVED_0X89, - RFST0, - RFST1, - RFST2, - RFST3, - RFST4, - RFST5, - RFST6, - RFST7, - RFST8, - RFST9, - RESERVED_0X94, - RESERVED_0X95, - RESERVED_0X96, - RESERVED_0X97, - RESERVED_0X98, - RESERVED_0X99, - RESERVED_0X9A, - RESERVED_0X9B, -}; - -#endif diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c deleted file mode 100644 index e1e70e9e0cb..00000000000 --- a/drivers/media/dvb/frontends/l64781.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - driver for LSI L64781 COFDM demodulator - - Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH - Marko Kohtala <marko.kohtala@luukku.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "dvb_frontend.h" -#include "l64781.h" - - -struct l64781_state { - struct i2c_adapter* i2c; - const struct l64781_config* config; - struct dvb_frontend frontend; - - /* private demodulator data */ - unsigned int first:1; -}; - -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "l64781: " args); \ - } while (0) - -static int debug; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - - -static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) - dprintk ("%s: write_reg error (reg == %02x) = %02x!\n", - __func__, reg, ret); - - return (ret != 1) ? -1 : 0; -} - -static int l64781_readreg (struct l64781_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) return ret; - - return b1[0]; -} - -static void apply_tps (struct l64781_state* state) -{ - l64781_writereg (state, 0x2a, 0x00); - l64781_writereg (state, 0x2a, 0x01); - - /* This here is a little bit questionable because it enables - the automatic update of TPS registers. I think we'd need to - handle the IRQ from FE to update some other registers as - well, or at least implement some magic to tuning to correct - to the TPS received from transmission. */ - l64781_writereg (state, 0x2a, 0x02); -} - - -static void reset_afc (struct l64781_state* state) -{ - /* Set AFC stall for the AFC_INIT_FRQ setting, TIM_STALL for - timing offset */ - l64781_writereg (state, 0x07, 0x9e); /* stall AFC */ - l64781_writereg (state, 0x08, 0); /* AFC INIT FREQ */ - l64781_writereg (state, 0x09, 0); - l64781_writereg (state, 0x0a, 0); - l64781_writereg (state, 0x07, 0x8e); - l64781_writereg (state, 0x0e, 0); /* AGC gain to zero in beginning */ - l64781_writereg (state, 0x11, 0x80); /* stall TIM */ - l64781_writereg (state, 0x10, 0); /* TIM_OFFSET_LSB */ - l64781_writereg (state, 0x12, 0); - l64781_writereg (state, 0x13, 0); - l64781_writereg (state, 0x11, 0x00); -} - -static int reset_and_configure (struct l64781_state* state) -{ - u8 buf [] = { 0x06 }; - struct i2c_msg msg = { .addr = 0x00, .flags = 0, .buf = buf, .len = 1 }; - // NOTE: this is correct in writing to address 0x00 - - return (i2c_transfer(state->i2c, &msg, 1) == 1) ? 0 : -ENODEV; -} - -static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param) -{ - struct l64781_state* state = fe->demodulator_priv; - /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */ - static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 }; - /* QPSK, QAM_16, QAM_64 */ - static const u8 qam_tab [] = { 2, 4, 0, 6 }; - static const u8 bw_tab [] = { 8, 7, 6 }; /* 8Mhz, 7MHz, 6MHz */ - static const u8 guard_tab [] = { 1, 2, 4, 8 }; - /* The Grundig 29504-401.04 Tuner comes with 18.432MHz crystal. */ - static const u32 ppm = 8000; - struct dvb_ofdm_parameters *p = ¶m->u.ofdm; - u32 ddfs_offset_fixed; -/* u32 ddfs_offset_variable = 0x6000-((1000000UL+ppm)/ */ -/* bw_tab[p->bandWidth]<<10)/15625; */ - u32 init_freq; - u32 spi_bias; - u8 val0x04; - u8 val0x05; - u8 val0x06; - int bw = p->bandwidth - BANDWIDTH_8_MHZ; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - if (param->inversion != INVERSION_ON && - param->inversion != INVERSION_OFF) - return -EINVAL; - - if (bw < 0 || bw > 2) - return -EINVAL; - - if (p->code_rate_HP != FEC_1_2 && p->code_rate_HP != FEC_2_3 && - p->code_rate_HP != FEC_3_4 && p->code_rate_HP != FEC_5_6 && - p->code_rate_HP != FEC_7_8) - return -EINVAL; - - if (p->hierarchy_information != HIERARCHY_NONE && - (p->code_rate_LP != FEC_1_2 && p->code_rate_LP != FEC_2_3 && - p->code_rate_LP != FEC_3_4 && p->code_rate_LP != FEC_5_6 && - p->code_rate_LP != FEC_7_8)) - return -EINVAL; - - if (p->constellation != QPSK && p->constellation != QAM_16 && - p->constellation != QAM_64) - return -EINVAL; - - if (p->transmission_mode != TRANSMISSION_MODE_2K && - p->transmission_mode != TRANSMISSION_MODE_8K) - return -EINVAL; - - if (p->guard_interval < GUARD_INTERVAL_1_32 || - p->guard_interval > GUARD_INTERVAL_1_4) - return -EINVAL; - - if (p->hierarchy_information < HIERARCHY_NONE || - p->hierarchy_information > HIERARCHY_4) - return -EINVAL; - - ddfs_offset_fixed = 0x4000-(ppm<<16)/bw_tab[p->bandwidth]/1000000; - - /* This works up to 20000 ppm, it overflows if too large ppm! */ - init_freq = (((8UL<<25) + (8UL<<19) / 25*ppm / (15625/25)) / - bw_tab[p->bandwidth] & 0xFFFFFF); - - /* SPI bias calculation is slightly modified to fit in 32bit */ - /* will work for high ppm only... */ - spi_bias = 378 * (1 << 10); - spi_bias *= 16; - spi_bias *= bw_tab[p->bandwidth]; - spi_bias *= qam_tab[p->constellation]; - spi_bias /= p->code_rate_HP + 1; - spi_bias /= (guard_tab[p->guard_interval] + 32); - spi_bias *= 1000ULL; - spi_bias /= 1000ULL + ppm/1000; - spi_bias *= p->code_rate_HP; - - val0x04 = (p->transmission_mode << 2) | p->guard_interval; - val0x05 = fec_tab[p->code_rate_HP]; - - if (p->hierarchy_information != HIERARCHY_NONE) - val0x05 |= (p->code_rate_LP - FEC_1_2) << 3; - - val0x06 = (p->hierarchy_information << 2) | p->constellation; - - l64781_writereg (state, 0x04, val0x04); - l64781_writereg (state, 0x05, val0x05); - l64781_writereg (state, 0x06, val0x06); - - reset_afc (state); - - /* Technical manual section 2.6.1, TIM_IIR_GAIN optimal values */ - l64781_writereg (state, 0x15, - p->transmission_mode == TRANSMISSION_MODE_2K ? 1 : 3); - l64781_writereg (state, 0x16, init_freq & 0xff); - l64781_writereg (state, 0x17, (init_freq >> 8) & 0xff); - l64781_writereg (state, 0x18, (init_freq >> 16) & 0xff); - - l64781_writereg (state, 0x1b, spi_bias & 0xff); - l64781_writereg (state, 0x1c, (spi_bias >> 8) & 0xff); - l64781_writereg (state, 0x1d, ((spi_bias >> 16) & 0x7f) | - (param->inversion == INVERSION_ON ? 0x80 : 0x00)); - - l64781_writereg (state, 0x22, ddfs_offset_fixed & 0xff); - l64781_writereg (state, 0x23, (ddfs_offset_fixed >> 8) & 0x3f); - - l64781_readreg (state, 0x00); /* clear interrupt registers... */ - l64781_readreg (state, 0x01); /* dto. */ - - apply_tps (state); - - return 0; -} - -static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param) -{ - struct l64781_state* state = fe->demodulator_priv; - int tmp; - - - tmp = l64781_readreg(state, 0x04); - switch(tmp & 3) { - case 0: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - param->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - switch((tmp >> 2) & 3) { - case 0: - param->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - param->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - break; - default: - printk("Unexpected value for transmission_mode\n"); - } - - - - tmp = l64781_readreg(state, 0x05); - switch(tmp & 7) { - case 0: - param->u.ofdm.code_rate_HP = FEC_1_2; - break; - case 1: - param->u.ofdm.code_rate_HP = FEC_2_3; - break; - case 2: - param->u.ofdm.code_rate_HP = FEC_3_4; - break; - case 3: - param->u.ofdm.code_rate_HP = FEC_5_6; - break; - case 4: - param->u.ofdm.code_rate_HP = FEC_7_8; - break; - default: - printk("Unexpected value for code_rate_HP\n"); - } - switch((tmp >> 3) & 7) { - case 0: - param->u.ofdm.code_rate_LP = FEC_1_2; - break; - case 1: - param->u.ofdm.code_rate_LP = FEC_2_3; - break; - case 2: - param->u.ofdm.code_rate_LP = FEC_3_4; - break; - case 3: - param->u.ofdm.code_rate_LP = FEC_5_6; - break; - case 4: - param->u.ofdm.code_rate_LP = FEC_7_8; - break; - default: - printk("Unexpected value for code_rate_LP\n"); - } - - - tmp = l64781_readreg(state, 0x06); - switch(tmp & 3) { - case 0: - param->u.ofdm.constellation = QPSK; - break; - case 1: - param->u.ofdm.constellation = QAM_16; - break; - case 2: - param->u.ofdm.constellation = QAM_64; - break; - default: - printk("Unexpected value for constellation\n"); - } - switch((tmp >> 2) & 7) { - case 0: - param->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - param->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - param->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - param->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - default: - printk("Unexpected value for hierarchy\n"); - } - - - tmp = l64781_readreg (state, 0x1d); - param->inversion = (tmp & 0x80) ? INVERSION_ON : INVERSION_OFF; - - tmp = (int) (l64781_readreg (state, 0x08) | - (l64781_readreg (state, 0x09) << 8) | - (l64781_readreg (state, 0x0a) << 16)); - param->frequency += tmp; - - return 0; -} - -static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct l64781_state* state = fe->demodulator_priv; - int sync = l64781_readreg (state, 0x32); - int gain = l64781_readreg (state, 0x0e); - - l64781_readreg (state, 0x00); /* clear interrupt registers... */ - l64781_readreg (state, 0x01); /* dto. */ - - *status = 0; - - if (gain > 5) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x02) /* VCXO locked, this criteria should be ok */ - *status |= FE_HAS_CARRIER; - - if (sync & 0x20) - *status |= FE_HAS_VITERBI; - - if (sync & 0x40) - *status |= FE_HAS_SYNC; - - if (sync == 0x7f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int l64781_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct l64781_state* state = fe->demodulator_priv; - - /* XXX FIXME: set up counting period (reg 0x26...0x28) - */ - *ber = l64781_readreg (state, 0x39) - | (l64781_readreg (state, 0x3a) << 8); - - return 0; -} - -static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct l64781_state* state = fe->demodulator_priv; - - u8 gain = l64781_readreg (state, 0x0e); - *signal_strength = (gain << 8) | gain; - - return 0; -} - -static int l64781_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct l64781_state* state = fe->demodulator_priv; - - u8 avg_quality = 0xff - l64781_readreg (state, 0x33); - *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/ - - return 0; -} - -static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct l64781_state* state = fe->demodulator_priv; - - *ucblocks = l64781_readreg (state, 0x37) - | (l64781_readreg (state, 0x38) << 8); - - return 0; -} - -static int l64781_sleep(struct dvb_frontend* fe) -{ - struct l64781_state* state = fe->demodulator_priv; - - /* Power down */ - return l64781_writereg (state, 0x3e, 0x5a); -} - -static int l64781_init(struct dvb_frontend* fe) -{ - struct l64781_state* state = fe->demodulator_priv; - - reset_and_configure (state); - - /* Power up */ - l64781_writereg (state, 0x3e, 0xa5); - - /* Reset hard */ - l64781_writereg (state, 0x2a, 0x04); - l64781_writereg (state, 0x2a, 0x00); - - /* Set tuner specific things */ - /* AFC_POL, set also in reset_afc */ - l64781_writereg (state, 0x07, 0x8e); - - /* Use internal ADC */ - l64781_writereg (state, 0x0b, 0x81); - - /* AGC loop gain, and polarity is positive */ - l64781_writereg (state, 0x0c, 0x84); - - /* Internal ADC outputs two's complement */ - l64781_writereg (state, 0x0d, 0x8c); - - /* With ppm=8000, it seems the DTR_SENSITIVITY will result in - value of 2 with all possible bandwidths and guard - intervals, which is the initial value anyway. */ - /*l64781_writereg (state, 0x19, 0x92);*/ - - /* Everything is two's complement, soft bit and CSI_OUT too */ - l64781_writereg (state, 0x1e, 0x09); - - /* delay a bit after first init attempt */ - if (state->first) { - state->first = 0; - msleep(200); - } - - return 0; -} - -static int l64781_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 4000; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void l64781_release(struct dvb_frontend* fe) -{ - struct l64781_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops l64781_ops; - -struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c) -{ - struct l64781_state* state = NULL; - int reg0x3e = -1; - u8 b0 [] = { 0x1a }; - u8 b1 [] = { 0x00 }; - struct i2c_msg msg [] = { { .addr = config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct l64781_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->first = 1; - - /** - * the L64781 won't show up before we send the reset_and_configure() - * broadcast. If nothing responds there is no L64781 on the bus... - */ - if (reset_and_configure(state) < 0) { - dprintk("No response to reset and configure broadcast...\n"); - goto error; - } - - /* The chip always responds to reads */ - if (i2c_transfer(state->i2c, msg, 2) != 2) { - dprintk("No response to read on I2C bus\n"); - goto error; - } - - /* Save current register contents for bailout */ - reg0x3e = l64781_readreg(state, 0x3e); - - /* Reading the POWER_DOWN register always returns 0 */ - if (reg0x3e != 0) { - dprintk("Device doesn't look like L64781\n"); - goto error; - } - - /* Turn the chip off */ - l64781_writereg (state, 0x3e, 0x5a); - - /* Responds to all reads with 0 */ - if (l64781_readreg(state, 0x1a) != 0) { - dprintk("Read 1 returned unexpcted value\n"); - goto error; - } - - /* Turn the chip on */ - l64781_writereg (state, 0x3e, 0xa5); - - /* Responds with register default value */ - if (l64781_readreg(state, 0x1a) != 0xa1) { - dprintk("Read 2 returned unexpcted value\n"); - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &l64781_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - if (reg0x3e >= 0) - l64781_writereg (state, 0x3e, reg0x3e); /* restore reg 0x3e */ - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops l64781_ops = { - - .info = { - .name = "LSI L64781 DVB-T", - .type = FE_OFDM, - /* .frequency_min = ???,*/ - /* .frequency_max = ???,*/ - .frequency_stepsize = 166666, - /* .frequency_tolerance = ???,*/ - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_MUTE_TS - }, - - .release = l64781_release, - - .init = l64781_init, - .sleep = l64781_sleep, - - .set_frontend = apply_frontend_param, - .get_frontend = get_frontend, - .get_tune_settings = l64781_get_tune_settings, - - .read_status = l64781_read_status, - .read_ber = l64781_read_ber, - .read_signal_strength = l64781_read_signal_strength, - .read_snr = l64781_read_snr, - .read_ucblocks = l64781_read_ucblocks, -}; - -MODULE_DESCRIPTION("LSI L64781 DVB-T Demodulator driver"); -MODULE_AUTHOR("Holger Waechtler, Marko Kohtala"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(l64781_attach); diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h deleted file mode 100644 index 1305a9e7fb0..00000000000 --- a/drivers/media/dvb/frontends/l64781.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - driver for LSI L64781 COFDM demodulator - - Copyright (C) 2001 Holger Waechtler for Convergence Integrated Media GmbH - Marko Kohtala <marko.kohtala@luukku.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef L64781_H -#define L64781_H - -#include <linux/dvb/frontend.h> - -struct l64781_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_L64781) || (defined(CONFIG_DVB_L64781_MODULE) && defined(MODULE)) -extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_L64781 - -#endif // L64781_H diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c deleted file mode 100644 index 3bb0c4394f8..00000000000 --- a/drivers/media/dvb/frontends/lgdt3304.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Driver for LG ATSC lgdt3304 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "lgdt3304.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("lgdt3304 debug: " fmt, ##args); } while (0) - -struct lgdt3304_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct i2c_adapter *i2c; -}; - -static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf = buf - }; - int i; - int err; - - for (i=0; i<len-1; i+=3){ - if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __func__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - i2cmsgs.buf += 3; - } - return 0; -} - -static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs[2]; - int ret; - __u8 buf; - - __u8 regbuf[2] = { reg>>8, reg&0xff }; - - i2cmsgs[0].addr = state->addr; - i2cmsgs[0].flags = 0; - i2cmsgs[0].len = 2; - i2cmsgs[0].buf = regbuf; - - i2cmsgs[1].addr = state->addr; - i2cmsgs[1].flags = I2C_M_RD; - i2cmsgs[1].len = 1; - i2cmsgs[1].buf = &buf; - - if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { - printk("%s i2c_transfer error %d\n", __func__, ret); - return ret; - } - - return buf; -} - -static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - char buffer[3] = { reg>>8, reg&0xff, val }; - int ret; - - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf=buffer - }; - ret = i2c_transfer(state->i2c, &i2cmsgs, 1); - if (ret != 1) { - printk("%s i2c_transfer error %d\n", __func__, ret); - return ret; - } - - return 0; -} - - -static int lgdt3304_soft_Reset(struct dvb_frontend *fe) -{ - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); - mdelay(200); - return 0; -} - -static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - int err = 0; - - static __u8 lgdt3304_vsb8_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x02, - 0x00, 0x00, 0x13, - 0x00, 0x0d, 0x02, - 0x00, 0x0e, 0x02, - 0x00, 0x12, 0x32, - 0x00, 0x13, 0xc4, - 0x01, 0x12, 0x17, - 0x01, 0x13, 0x15, - 0x01, 0x14, 0x18, - 0x01, 0x15, 0xff, - 0x01, 0x16, 0x2c, - 0x02, 0x14, 0x67, - 0x02, 0x24, 0x8d, - 0x04, 0x27, 0x12, - 0x04, 0x28, 0x4f, - 0x03, 0x08, 0x80, - 0x03, 0x09, 0x00, - 0x03, 0x0d, 0x00, - 0x03, 0x0e, 0x1c, - 0x03, 0x14, 0xe1, - 0x05, 0x0e, 0x5b, - }; - - /* not yet tested .. */ - static __u8 lgdt3304_qam64_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x18, - 0x00, 0x0d, 0x02, - //0x00, 0x0e, 0x02, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x00, - 0x03, 0x14, 0xe3, - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - 0x05, 0x0e, 0x5b, - }; - - - /* tested with KWorld a340 */ - static __u8 lgdt3304_qam256_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x01, //0x19, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - //0x05, 0x0e, 0x5b, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - - 0x05, 0x0e, 0x5b, - - 0x00, 0x02, 0x9a, - - 0x00, 0x02, 0x9b, - - 0x00, 0x00, 0x01, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - }; - - struct lgdt3304_state *state = fe->demodulator_priv; - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: - err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, - sizeof(lgdt3304_vsb8_data)); - break; - case QAM_64: - err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, - sizeof(lgdt3304_qam64_data)); - break; - case QAM_256: - err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, - sizeof(lgdt3304_qam256_data)); - break; - default: - break; - } - - if (err) { - printk("%s error setting modulation\n", __func__); - } else { - state->current_modulation = param->u.vsb.modulation; - } - } - state->current_frequency = param->frequency; - - lgdt3304_soft_Reset(fe); - - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, param); - - return 0; -} - -static int lgdt3304_init(struct dvb_frontend *fe) { - return 0; -} - -static int lgdt3304_sleep(struct dvb_frontend *fe) { - return 0; -} - - -static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - int r011d; - int qam_lck; - - *status = 0; - dprintk("lgdt read status\n"); - - r011d = lgdt3304_i2c_read_reg(fe, 0x011d); - - dprintk("%02x\n", r011d); - - switch(state->current_modulation) { - case VSB_8: - if (r011d & 0x80) { - dprintk("VSB Locked\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - break; - case QAM_64: - case QAM_256: - qam_lck = r011d & 0x7; - switch(qam_lck) { - case 0x0: dprintk("Unlock\n"); - break; - case 0x4: dprintk("1st Lock in acquisition state\n"); - break; - case 0x6: dprintk("2nd Lock in acquisition state\n"); - break; - case 0x7: dprintk("Final Lock in good reception state\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - break; - } - break; - default: - printk("%s unhandled modulation\n", __func__); - } - - - return 0; -} - -static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void lgdt3304_release(struct dvb_frontend *fe) -{ - struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_lgdt3304={ - .info = { - .name = "LG 3304", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 5056941, - .symbol_rate_max = 10762000, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt3304_init, - .sleep = lgdt3304_sleep, - .set_frontend = lgdt3304_set_parameters, - .read_snr = lgdt3304_read_snr, - .read_ber = lgdt3304_read_ber, - .read_status = lgdt3304_read_status, - .read_ucblocks = lgdt3304_read_ucblocks, - .release = lgdt3304_release, -}; - -struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - - struct lgdt3304_state *state; - state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct lgdt3304_state)); - state->addr = config->i2c_address; - state->i2c = i2c; - - memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(lgdt3304_attach); -MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); -MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lgdt3304.h b/drivers/media/dvb/frontends/lgdt3304.h deleted file mode 100644 index fc409fe59ac..00000000000 --- a/drivers/media/dvb/frontends/lgdt3304.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Driver for DVB-T lgdt3304 demodulator - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef LGDT3304_H -#define LGDT3304_H - -#include <linux/dvb/frontend.h> - -struct lgdt3304_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) -extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGDT */ - -#endif /* LGDT3304_H */ diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c deleted file mode 100644 index 056387b41a8..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ /dev/null @@ -1,820 +0,0 @@ -/* - * Support for LGDT3302 and LGDT3303 - VSB/QAM - * - * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* - * NOTES ABOUT THIS DRIVER - * - * This Linux driver supports: - * DViCO FusionHDTV 3 Gold-Q - * DViCO FusionHDTV 3 Gold-T - * DViCO FusionHDTV 5 Gold - * DViCO FusionHDTV 5 Lite - * DViCO FusionHDTV 5 USB Gold - * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) - * pcHDTV HD5500 - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.h> - -#include "dvb_frontend.h" -#include "dvb_math.h" -#include "lgdt330x_priv.h" -#include "lgdt330x.h" - -/* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */ -/* #define USE_EQMSE */ - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"Turn on/off lgdt330x frontend debugging (default:off)."); -#define dprintk(args...) \ -do { \ -if (debug) printk(KERN_DEBUG "lgdt330x: " args); \ -} while (0) - -struct lgdt330x_state -{ - struct i2c_adapter* i2c; - - /* Configuration settings */ - const struct lgdt330x_config* config; - - struct dvb_frontend frontend; - - /* Demodulator private data */ - fe_modulation_t current_modulation; - u32 snr; /* Result of last SNR calculation */ - - /* Tuner private data */ - u32 current_frequency; -}; - -static int i2c_write_demod_bytes (struct lgdt330x_state* state, - u8 *buf, /* data bytes to send */ - int len /* number of bytes to send */ ) -{ - struct i2c_msg msg = - { .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 }; - int i; - int err; - - for (i=0; i<len-1; i+=2){ - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - msg.buf += 2; - } - return 0; -} - -/* - * This routine writes the register (reg) to the demod bus - * then reads the data returned for (len) bytes. - */ - -static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, - enum I2C_REG reg, u8* buf, int len) -{ - u8 wr [] = { reg }; - struct i2c_msg msg [] = { - { .addr = state->config->demod_address, - .flags = 0, .buf = wr, .len = 1 }, - { .addr = state->config->demod_address, - .flags = I2C_M_RD, .buf = buf, .len = len }, - }; - int ret; - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) { - printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret); - } else { - ret = 0; - } - return ret; -} - -/* Software reset */ -static int lgdt3302_SwReset(struct lgdt330x_state* state) -{ - u8 ret; - u8 reset[] = { - IRQ_MASK, - 0x00 /* bit 6 is active low software reset - * bits 5-0 are 1 to mask interrupts */ - }; - - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - if (ret == 0) { - - /* force reset high (inactive) and unmask interrupts */ - reset[1] = 0x7f; - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - } - return ret; -} - -static int lgdt3303_SwReset(struct lgdt330x_state* state) -{ - u8 ret; - u8 reset[] = { - 0x02, - 0x00 /* bit 0 is active low software reset */ - }; - - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - if (ret == 0) { - - /* force reset high (inactive) */ - reset[1] = 0x01; - ret = i2c_write_demod_bytes(state, - reset, sizeof(reset)); - } - return ret; -} - -static int lgdt330x_SwReset(struct lgdt330x_state* state) -{ - switch (state->config->demod_chip) { - case LGDT3302: - return lgdt3302_SwReset(state); - case LGDT3303: - return lgdt3303_SwReset(state); - default: - return -ENODEV; - } -} - -static int lgdt330x_init(struct dvb_frontend* fe) -{ - /* Hardware reset is done using gpio[0] of cx23880x chip. - * I'd like to do it here, but don't know how to find chip address. - * cx88-cards.c arranges for the reset bit to be inactive (high). - * Maybe there needs to be a callable function in cx88-core or - * the caller of this function needs to do it. */ - - /* - * Array of byte pairs <address, value> - * to initialize each different chip - */ - static u8 lgdt3302_init_data[] = { - /* Use 50MHz parameter values from spec sheet since xtal is 50 */ - /* Change the value of NCOCTFV[25:0] of carrier - recovery center frequency register */ - VSB_CARRIER_FREQ0, 0x00, - VSB_CARRIER_FREQ1, 0x87, - VSB_CARRIER_FREQ2, 0x8e, - VSB_CARRIER_FREQ3, 0x01, - /* Change the TPCLK pin polarity - data is valid on falling clock */ - DEMUX_CONTROL, 0xfb, - /* Change the value of IFBW[11:0] of - AGC IF/RF loop filter bandwidth register */ - AGC_RF_BANDWIDTH0, 0x40, - AGC_RF_BANDWIDTH1, 0x93, - AGC_RF_BANDWIDTH2, 0x00, - /* Change the value of bit 6, 'nINAGCBY' and - 'NSSEL[1:0] of ACG function control register 2 */ - AGC_FUNC_CTRL2, 0xc6, - /* Change the value of bit 6 'RFFIX' - of AGC function control register 3 */ - AGC_FUNC_CTRL3, 0x40, - /* Set the value of 'INLVTHD' register 0x2a/0x2c - to 0x7fe */ - AGC_DELAY0, 0x07, - AGC_DELAY2, 0xfe, - /* Change the value of IAGCBW[15:8] - of inner AGC loop filter bandwidth */ - AGC_LOOP_BANDWIDTH0, 0x08, - AGC_LOOP_BANDWIDTH1, 0x9a - }; - - static u8 lgdt3303_init_data[] = { - 0x4c, 0x14 - }; - - static u8 flip_1_lgdt3303_init_data[] = { - 0x4c, 0x14, - 0x87, 0xf3 - }; - - static u8 flip_2_lgdt3303_init_data[] = { - 0x4c, 0x14, - 0x87, 0xda - }; - - struct lgdt330x_state* state = fe->demodulator_priv; - char *chip_name; - int err; - - switch (state->config->demod_chip) { - case LGDT3302: - chip_name = "LGDT3302"; - err = i2c_write_demod_bytes(state, lgdt3302_init_data, - sizeof(lgdt3302_init_data)); - break; - case LGDT3303: - chip_name = "LGDT3303"; - switch (state->config->clock_polarity_flip) { - case 2: - err = i2c_write_demod_bytes(state, - flip_2_lgdt3303_init_data, - sizeof(flip_2_lgdt3303_init_data)); - break; - case 1: - err = i2c_write_demod_bytes(state, - flip_1_lgdt3303_init_data, - sizeof(flip_1_lgdt3303_init_data)); - break; - case 0: - default: - err = i2c_write_demod_bytes(state, lgdt3303_init_data, - sizeof(lgdt3303_init_data)); - } - break; - default: - chip_name = "undefined"; - printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n"); - err = -ENODEV; - } - dprintk("%s entered as %s\n", __func__, chip_name); - if (err < 0) - return err; - return lgdt330x_SwReset(state); -} - -static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; /* Not supplied by the demod chips */ - return 0; -} - -static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct lgdt330x_state* state = fe->demodulator_priv; - int err; - u8 buf[2]; - - switch (state->config->demod_chip) { - case LGDT3302: - err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1, - buf, sizeof(buf)); - break; - case LGDT3303: - err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1, - buf, sizeof(buf)); - break; - default: - printk(KERN_WARNING - "Only LGDT3302 and LGDT3303 are supported chips.\n"); - err = -ENODEV; - } - - *ucblocks = (buf[0] << 8) | buf[1]; - return 0; -} - -static int lgdt330x_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - /* - * Array of byte pairs <address, value> - * to initialize 8VSB for lgdt3303 chip 50 MHz IF - */ - static u8 lgdt3303_8vsb_44_data[] = { - 0x04, 0x00, - 0x0d, 0x40, - 0x0e, 0x87, - 0x0f, 0x8e, - 0x10, 0x01, - 0x47, 0x8b }; - - /* - * Array of byte pairs <address, value> - * to initialize QAM for lgdt3303 chip - */ - static u8 lgdt3303_qam_data[] = { - 0x04, 0x00, - 0x0d, 0x00, - 0x0e, 0x00, - 0x0f, 0x00, - 0x10, 0x00, - 0x51, 0x63, - 0x47, 0x66, - 0x48, 0x66, - 0x4d, 0x1a, - 0x49, 0x08, - 0x4a, 0x9b }; - - struct lgdt330x_state* state = fe->demodulator_priv; - - static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 }; - - int err; - /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: - dprintk("%s: VSB_8 MODE\n", __func__); - - /* Select VSB mode */ - top_ctrl_cfg[1] = 0x03; - - /* Select ANT connector if supported by card */ - if (state->config->pll_rf_set) - state->config->pll_rf_set(fe, 1); - - if (state->config->demod_chip == LGDT3303) { - err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data, - sizeof(lgdt3303_8vsb_44_data)); - } - break; - - case QAM_64: - dprintk("%s: QAM_64 MODE\n", __func__); - - /* Select QAM_64 mode */ - top_ctrl_cfg[1] = 0x00; - - /* Select CABLE connector if supported by card */ - if (state->config->pll_rf_set) - state->config->pll_rf_set(fe, 0); - - if (state->config->demod_chip == LGDT3303) { - err = i2c_write_demod_bytes(state, lgdt3303_qam_data, - sizeof(lgdt3303_qam_data)); - } - break; - - case QAM_256: - dprintk("%s: QAM_256 MODE\n", __func__); - - /* Select QAM_256 mode */ - top_ctrl_cfg[1] = 0x01; - - /* Select CABLE connector if supported by card */ - if (state->config->pll_rf_set) - state->config->pll_rf_set(fe, 0); - - if (state->config->demod_chip == LGDT3303) { - err = i2c_write_demod_bytes(state, lgdt3303_qam_data, - sizeof(lgdt3303_qam_data)); - } - break; - default: - printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, param->u.vsb.modulation); - return -1; - } - /* - * select serial or parallel MPEG harware interface - * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303 - * Parallel: 0x00 - */ - top_ctrl_cfg[1] |= state->config->serial_mpeg; - - /* Select the requested mode */ - i2c_write_demod_bytes(state, top_ctrl_cfg, - sizeof(top_ctrl_cfg)); - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - state->current_modulation = param->u.vsb.modulation; - } - - /* Tune to the specified frequency */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Keep track of the new frequency */ - /* FIXME this is the wrong way to do this... */ - /* The tuner is shared with the video4linux analog API */ - state->current_frequency = param->frequency; - - lgdt330x_SwReset(state); - return 0; -} - -static int lgdt330x_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters* param) -{ - struct lgdt330x_state *state = fe->demodulator_priv; - param->frequency = state->current_frequency; - return 0; -} - -static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct lgdt330x_state* state = fe->demodulator_priv; - u8 buf[3]; - - *status = 0; /* Reset status result */ - - /* AGC status register */ - i2c_read_demod_bytes(state, AGC_STATUS, buf, 1); - dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]); - if ((buf[0] & 0x0c) == 0x8){ - /* Test signal does not exist flag */ - /* as well as the AGC lock flag. */ - *status |= FE_HAS_SIGNAL; - } - - /* - * You must set the Mask bits to 1 in the IRQ_MASK in order - * to see that status bit in the IRQ_STATUS register. - * This is done in SwReset(); - */ - /* signal status */ - i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf)); - dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]); - - - /* sync status */ - if ((buf[2] & 0x03) == 0x01) { - *status |= FE_HAS_SYNC; - } - - /* FEC error status */ - if ((buf[2] & 0x0c) == 0x08) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - } - - /* Carrier Recovery Lock Status Register */ - i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]); - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - /* Need to undestand why there are 3 lock levels here */ - if ((buf[0] & 0x07) == 0x07) - *status |= FE_HAS_CARRIER; - break; - case VSB_8: - if ((buf[0] & 0x80) == 0x80) - *status |= FE_HAS_CARRIER; - break; - default: - printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__); - } - - return 0; -} - -static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct lgdt330x_state* state = fe->demodulator_priv; - int err; - u8 buf[3]; - - *status = 0; /* Reset status result */ - - /* lgdt3303 AGC status register */ - err = i2c_read_demod_bytes(state, 0x58, buf, 1); - if (err < 0) - return err; - - dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]); - if ((buf[0] & 0x21) == 0x01){ - /* Test input signal does not exist flag */ - /* as well as the AGC lock flag. */ - *status |= FE_HAS_SIGNAL; - } - - /* Carrier Recovery Lock Status Register */ - i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); - dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]); - switch (state->current_modulation) { - case QAM_256: - case QAM_64: - /* Need to undestand why there are 3 lock levels here */ - if ((buf[0] & 0x07) == 0x07) - *status |= FE_HAS_CARRIER; - else - break; - i2c_read_demod_bytes(state, 0x8a, buf, 1); - if ((buf[0] & 0x04) == 0x04) - *status |= FE_HAS_SYNC; - if ((buf[0] & 0x01) == 0x01) - *status |= FE_HAS_LOCK; - if ((buf[0] & 0x08) == 0x08) - *status |= FE_HAS_VITERBI; - break; - case VSB_8: - if ((buf[0] & 0x80) == 0x80) - *status |= FE_HAS_CARRIER; - else - break; - i2c_read_demod_bytes(state, 0x38, buf, 1); - if ((buf[0] & 0x02) == 0x00) - *status |= FE_HAS_SYNC; - if ((buf[0] & 0x01) == 0x01) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - } - break; - default: - printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__); - } - return 0; -} - -/* Calculate SNR estimation (scaled by 2^24) - - 8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM - equations from LGDT3303 datasheet. VSB is the same between the '02 - and '03, so maybe QAM is too? Perhaps someone with a newer datasheet - that has QAM information could verify? - - For 8-VSB: (two ways, take your pick) - LGDT3302: - SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE) - LGDT3303: - SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE) - LGDT3302 & LGDT3303: - SNR_PT = 10 * log10(25 * 32^2 / PT_MSE) (we use this one) - For 64-QAM: - SNR = 10 * log10( 688128 / MSEQAM) - For 256-QAM: - SNR = 10 * log10( 696320 / MSEQAM) - - We re-write the snr equation as: - SNR * 2^24 = 10*(c - intlog10(MSE)) - Where for 256-QAM, c = log10(696320) * 2^24, and so on. */ - -static u32 calculate_snr(u32 mse, u32 c) -{ - if (mse == 0) /* No signal */ - return 0; - - mse = intlog10(mse); - if (mse > c) { - /* Negative SNR, which is possible, but realisticly the - demod will lose lock before the signal gets this bad. The - API only allows for unsigned values, so just return 0 */ - return 0; - } - return 10*(c - mse); -} - -static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - u8 buf[5]; /* read data buffer */ - u32 noise; /* noise value */ - u32 c; /* per-modulation SNR calculation constant */ - - switch(state->current_modulation) { - case VSB_8: - i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5); -#ifdef USE_EQMSE - /* Use Equalizer Mean-Square Error Register */ - /* SNR for ranges from -15.61 to +41.58 */ - noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2]; - c = 69765745; /* log10(25*24^2)*2^24 */ -#else - /* Use Phase Tracker Mean-Square Error Register */ - /* SNR for ranges from -13.11 to +44.08 */ - noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4]; - c = 73957994; /* log10(25*32^2)*2^24 */ -#endif - break; - case QAM_64: - case QAM_256: - i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2); - noise = ((buf[0] & 3) << 8) | buf[1]; - c = state->current_modulation == QAM_64 ? 97939837 : 98026066; - /* log10(688128)*2^24 and log10(696320)*2^24 */ - break; - default: - printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n", - __func__); - return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ - } - - state->snr = calculate_snr(noise, c); - *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ - - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, - state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - u8 buf[5]; /* read data buffer */ - u32 noise; /* noise value */ - u32 c; /* per-modulation SNR calculation constant */ - - switch(state->current_modulation) { - case VSB_8: - i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5); -#ifdef USE_EQMSE - /* Use Equalizer Mean-Square Error Register */ - /* SNR for ranges from -16.12 to +44.08 */ - noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2]; - c = 73957994; /* log10(25*32^2)*2^24 */ -#else - /* Use Phase Tracker Mean-Square Error Register */ - /* SNR for ranges from -13.11 to +44.08 */ - noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; - c = 73957994; /* log10(25*32^2)*2^24 */ -#endif - break; - case QAM_64: - case QAM_256: - i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2); - noise = (buf[0] << 8) | buf[1]; - c = state->current_modulation == QAM_64 ? 97939837 : 98026066; - /* log10(688128)*2^24 and log10(696320)*2^24 */ - break; - default: - printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n", - __func__); - return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */ - } - - state->snr = calculate_snr(noise, c); - *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */ - - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, - state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* Calculate Strength from SNR up to 35dB */ - /* Even though the SNR can go higher than 35dB, there is some comfort */ - /* factor in having a range of strong signals that can show at 100% */ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - u16 snr; - int ret; - - ret = fe->ops.read_snr(fe, &snr); - if (ret != 0) - return ret; - /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ - /* scale the range 0 - 35*2^24 into 0 - 65535 */ - if (state->snr >= 8960 * 0x10000) - *strength = 0xffff; - else - *strength = state->snr / 8960; - - return 0; -} - -static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) -{ - /* I have no idea about this - it may not be needed */ - fe_tune_settings->min_delay_ms = 500; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - return 0; -} - -static void lgdt330x_release(struct dvb_frontend* fe) -{ - struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops lgdt3302_ops; -static struct dvb_frontend_ops lgdt3303_ops; - -struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c) -{ - struct lgdt330x_state* state = NULL; - u8 buf[1]; - - /* Allocate memory for the internal state */ - state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - - /* Create dvb_frontend */ - switch (config->demod_chip) { - case LGDT3302: - memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); - break; - case LGDT3303: - memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); - break; - default: - goto error; - } - state->frontend.demodulator_priv = state; - - /* Verify communication with demod chip */ - if (i2c_read_demod_bytes(state, 2, buf, 1)) - goto error; - - state->current_frequency = -1; - state->current_modulation = -1; - - return &state->frontend; - -error: - kfree(state); - dprintk("%s: ERROR\n",__func__); - return NULL; -} - -static struct dvb_frontend_ops lgdt3302_ops = { - .info = { - .name= "LG Electronics LGDT3302 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min= 54000000, - .frequency_max= 858000000, - .frequency_stepsize= 62500, - .symbol_rate_min = 5056941, /* QAM 64 */ - .symbol_rate_max = 10762000, /* VSB 8 */ - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt330x_init, - .set_frontend = lgdt330x_set_parameters, - .get_frontend = lgdt330x_get_frontend, - .get_tune_settings = lgdt330x_get_tune_settings, - .read_status = lgdt3302_read_status, - .read_ber = lgdt330x_read_ber, - .read_signal_strength = lgdt330x_read_signal_strength, - .read_snr = lgdt3302_read_snr, - .read_ucblocks = lgdt330x_read_ucblocks, - .release = lgdt330x_release, -}; - -static struct dvb_frontend_ops lgdt3303_ops = { - .info = { - .name= "LG Electronics LGDT3303 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min= 54000000, - .frequency_max= 858000000, - .frequency_stepsize= 62500, - .symbol_rate_min = 5056941, /* QAM 64 */ - .symbol_rate_max = 10762000, /* VSB 8 */ - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt330x_init, - .set_frontend = lgdt330x_set_parameters, - .get_frontend = lgdt330x_get_frontend, - .get_tune_settings = lgdt330x_get_tune_settings, - .read_status = lgdt3303_read_status, - .read_ber = lgdt330x_read_ber, - .read_signal_strength = lgdt330x_read_signal_strength, - .read_snr = lgdt3303_read_snr, - .read_ucblocks = lgdt330x_read_ucblocks, - .release = lgdt330x_release, -}; - -MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); -MODULE_AUTHOR("Wilson Michaels"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(lgdt330x_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h deleted file mode 100644 index 9012504f0f2..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Support for LGDT3302 and LGDT3303 - VSB/QAM - * - * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef LGDT330X_H -#define LGDT330X_H - -#include <linux/dvb/frontend.h> - -typedef enum lg_chip_t { - UNDEFINED, - LGDT3302, - LGDT3303 -}lg_chip_type; - -struct lgdt330x_config -{ - /* The demodulator's i2c address */ - u8 demod_address; - - /* LG demodulator chip LGDT3302 or LGDT3303 */ - lg_chip_type demod_chip; - - /* MPEG hardware interface - 0:parallel 1:serial */ - int serial_mpeg; - - /* PLL interface */ - int (*pll_rf_set) (struct dvb_frontend* fe, int index); - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); - - /* Flip the polarity of the mpeg data transfer clock using alternate init data - * This option applies ONLY to LGDT3303 - 0:disabled (default) 1:enabled */ - int clock_polarity_flip; -}; - -#if defined(CONFIG_DVB_LGDT330X) || (defined(CONFIG_DVB_LGDT330X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_LGDT330X - -#endif /* LGDT330X_H */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h deleted file mode 100644 index 38c76695abf..00000000000 --- a/drivers/media/dvb/frontends/lgdt330x_priv.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Support for LGDT3302 and LGDT3303 - VSB/QAM - * - * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _LGDT330X_PRIV_ -#define _LGDT330X_PRIV_ - -/* i2c control register addresses */ -enum I2C_REG { - TOP_CONTROL= 0x00, - IRQ_MASK= 0x01, - IRQ_STATUS= 0x02, - VSB_CARRIER_FREQ0= 0x16, - VSB_CARRIER_FREQ1= 0x17, - VSB_CARRIER_FREQ2= 0x18, - VSB_CARRIER_FREQ3= 0x19, - CARRIER_MSEQAM1= 0x1a, - CARRIER_MSEQAM2= 0x1b, - CARRIER_LOCK= 0x1c, - TIMING_RECOVERY= 0x1d, - AGC_DELAY0= 0x2a, - AGC_DELAY1= 0x2b, - AGC_DELAY2= 0x2c, - AGC_RF_BANDWIDTH0= 0x2d, - AGC_RF_BANDWIDTH1= 0x2e, - AGC_RF_BANDWIDTH2= 0x2f, - AGC_LOOP_BANDWIDTH0= 0x30, - AGC_LOOP_BANDWIDTH1= 0x31, - AGC_FUNC_CTRL1= 0x32, - AGC_FUNC_CTRL2= 0x33, - AGC_FUNC_CTRL3= 0x34, - AGC_RFIF_ACC0= 0x39, - AGC_RFIF_ACC1= 0x3a, - AGC_RFIF_ACC2= 0x3b, - AGC_STATUS= 0x3f, - SYNC_STATUS_VSB= 0x43, - DEMUX_CONTROL= 0x66, - LGDT3302_EQPH_ERR0= 0x47, - LGDT3302_EQ_ERR1= 0x48, - LGDT3302_EQ_ERR2= 0x49, - LGDT3302_PH_ERR1= 0x4a, - LGDT3302_PH_ERR2= 0x4b, - LGDT3302_PACKET_ERR_COUNTER1= 0x6a, - LGDT3302_PACKET_ERR_COUNTER2= 0x6b, - LGDT3303_EQPH_ERR0= 0x6e, - LGDT3303_EQ_ERR1= 0x6f, - LGDT3303_EQ_ERR2= 0x70, - LGDT3303_PH_ERR1= 0x71, - LGDT3303_PH_ERR2= 0x72, - LGDT3303_PACKET_ERR_COUNTER1= 0x8b, - LGDT3303_PACKET_ERR_COUNTER2= 0x8c, -}; - -#endif /* _LGDT330X_PRIV_ */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c deleted file mode 100644 index 855852fddf2..00000000000 --- a/drivers/media/dvb/frontends/lgs8gl5.c +++ /dev/null @@ -1,454 +0,0 @@ -/* - Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver - - Copyright (C) 2008 Sirius International (Hong Kong) Limited - Timothy Lee <timothy.lee@siriushk.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include "dvb_frontend.h" -#include "lgs8gl5.h" - - -#define REG_RESET 0x02 -#define REG_RESET_OFF 0x01 -#define REG_03 0x03 -#define REG_04 0x04 -#define REG_07 0x07 -#define REG_09 0x09 -#define REG_0A 0x0a -#define REG_0B 0x0b -#define REG_0C 0x0c -#define REG_37 0x37 -#define REG_STRENGTH 0x4b -#define REG_STRENGTH_MASK 0x7f -#define REG_STRENGTH_CARRIER 0x80 -#define REG_INVERSION 0x7c -#define REG_INVERSION_ON 0x80 -#define REG_7D 0x7d -#define REG_7E 0x7e -#define REG_A2 0xa2 -#define REG_STATUS 0xa4 -#define REG_STATUS_SYNC 0x04 -#define REG_STATUS_LOCK 0x01 - - -struct lgs8gl5_state { - struct i2c_adapter *i2c; - const struct lgs8gl5_config *config; - struct dvb_frontend frontend; -}; - - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "lgs8gl5: " args); \ - } while (0) - - -/* Writes into demod's register */ -static int -lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = {reg, data}; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n", - __func__, reg, data, ret); - return (ret != 1) ? -1 : 0; -} - - -/* Reads from demod's register */ -static int -lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg) -{ - int ret; - u8 b0[] = {reg}; - u8 b1[] = {0}; - struct i2c_msg msg[2] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, - { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - return -EIO; - - return b1[0]; -} - - -static int -lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - lgs8gl5_read_reg(state, reg); - lgs8gl5_write_reg(state, reg, data); - return 0; -} - - -/* Writes into alternate device's register */ -/* TODO: Find out what that device is for! */ -static int -lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data) -{ - int ret; - u8 b0[] = {reg}; - u8 b1[] = {0}; - u8 b2[] = {reg, data}; - struct i2c_msg msg[3] = { - { - .addr = state->config->demod_address + 2, - .flags = 0, - .buf = b0, - .len = 1 - }, - { - .addr = state->config->demod_address + 2, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - }, - { - .addr = state->config->demod_address + 2, - .flags = 0, - .buf = b2, - .len = 2 - }, - }; - - ret = i2c_transfer(state->i2c, msg, 3); - return (ret != 3) ? -1 : 0; -} - - -static void -lgs8gl5_soft_reset(struct lgs8gl5_state *state) -{ - u8 val; - - dprintk("%s\n", __func__); - - val = lgs8gl5_read_reg(state, REG_RESET); - lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF); - lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF); - msleep(5); -} - - -/* Starts demodulation */ -static void -lgs8gl5_start_demod(struct lgs8gl5_state *state) -{ - u8 val; - int n; - - dprintk("%s\n", __func__); - - lgs8gl5_update_alt_reg(state, 0xc2, 0x28); - lgs8gl5_soft_reset(state); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_write_reg(state, REG_09, 0x0e); - lgs8gl5_write_reg(state, REG_0A, 0xe5); - lgs8gl5_write_reg(state, REG_0B, 0x35); - lgs8gl5_write_reg(state, REG_0C, 0x30); - - lgs8gl5_update_reg(state, REG_03, 0x00); - lgs8gl5_update_reg(state, REG_7E, 0x01); - lgs8gl5_update_alt_reg(state, 0xc5, 0x00); - lgs8gl5_update_reg(state, REG_04, 0x02); - lgs8gl5_update_reg(state, REG_37, 0x01); - lgs8gl5_soft_reset(state); - - /* Wait for carrier */ - for (n = 0; n < 10; n++) { - val = lgs8gl5_read_reg(state, REG_STRENGTH); - dprintk("Wait for carrier[%d] 0x%02X\n", n, val); - if (val & REG_STRENGTH_CARRIER) - break; - msleep(4); - } - if (!(val & REG_STRENGTH_CARRIER)) - return; - - /* Wait for lock */ - for (n = 0; n < 20; n++) { - val = lgs8gl5_read_reg(state, REG_STATUS); - dprintk("Wait for lock[%d] 0x%02X\n", n, val); - if (val & REG_STATUS_LOCK) - break; - msleep(12); - } - if (!(val & REG_STATUS_LOCK)) - return; - - lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2)); - lgs8gl5_soft_reset(state); -} - - -static int -lgs8gl5_init(struct dvb_frontend *fe) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - lgs8gl5_update_alt_reg(state, 0xc2, 0x28); - lgs8gl5_soft_reset(state); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_update_reg(state, REG_07, 0x10); - lgs8gl5_write_reg(state, REG_09, 0x0e); - lgs8gl5_write_reg(state, REG_0A, 0xe5); - lgs8gl5_write_reg(state, REG_0B, 0x35); - lgs8gl5_write_reg(state, REG_0C, 0x30); - - return 0; -} - - -static int -lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - u8 flags = lgs8gl5_read_reg(state, REG_STATUS); - - *status = 0; - - if ((level & REG_STRENGTH_MASK) > 0) - *status |= FE_HAS_SIGNAL; - if (level & REG_STRENGTH_CARRIER) - *status |= FE_HAS_CARRIER; - if (flags & REG_STATUS_SYNC) - *status |= FE_HAS_SYNC; - if (flags & REG_STATUS_LOCK) - *status |= FE_HAS_LOCK; - - return 0; -} - - -static int -lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - *ber = 0; - - return 0; -} - - -static int -lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - *signal_strength = (level & REG_STRENGTH_MASK) << 8; - - return 0; -} - - -static int -lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 level = lgs8gl5_read_reg(state, REG_STRENGTH); - *snr = (level & REG_STRENGTH_MASK) << 8; - - return 0; -} - - -static int -lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - *ucblocks = 0; - - return 0; -} - - -static int -lgs8gl5_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* lgs8gl5_set_inversion(state, p->inversion); */ - - lgs8gl5_start_demod(state); - - return 0; -} - - -static int -lgs8gl5_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - u8 inv = lgs8gl5_read_reg(state, REG_INVERSION); - struct dvb_ofdm_parameters *o = &p->u.ofdm; - - p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF; - - o->code_rate_HP = FEC_1_2; - o->code_rate_LP = FEC_7_8; - o->guard_interval = GUARD_INTERVAL_1_32; - o->transmission_mode = TRANSMISSION_MODE_2K; - o->constellation = QAM_64; - o->hierarchy_information = HIERARCHY_NONE; - o->bandwidth = BANDWIDTH_8_MHZ; - - return 0; -} - - -static int -lgs8gl5_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 240; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - - -static void -lgs8gl5_release(struct dvb_frontend *fe) -{ - struct lgs8gl5_state *state = fe->demodulator_priv; - kfree(state); -} - - -static struct dvb_frontend_ops lgs8gl5_ops; - - -struct dvb_frontend* -lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c) -{ - struct lgs8gl5_state *state = NULL; - - dprintk("%s\n", __func__); - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - - /* Check if the demod is there */ - if (lgs8gl5_read_reg(state, REG_RESET) < 0) - goto error; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &lgs8gl5_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(lgs8gl5_attach); - - -static struct dvb_frontend_ops lgs8gl5_ops = { - .info = { - .name = "Legend Silicon LGS-8GL5 DMB-TH", - .type = FE_OFDM, - .frequency_min = 474000000, - .frequency_max = 858000000, - .frequency_stepsize = 10000, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_BANDWIDTH_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | - FE_CAN_RECOVER - }, - - .release = lgs8gl5_release, - - .init = lgs8gl5_init, - - .set_frontend = lgs8gl5_set_frontend, - .get_frontend = lgs8gl5_get_frontend, - .get_tune_settings = lgs8gl5_get_tune_settings, - - .read_status = lgs8gl5_read_status, - .read_ber = lgs8gl5_read_ber, - .read_signal_strength = lgs8gl5_read_signal_strength, - .read_snr = lgs8gl5_read_snr, - .read_ucblocks = lgs8gl5_read_ucblocks, -}; - - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver"); -MODULE_AUTHOR("Timothy Lee"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb/frontends/lgs8gl5.h deleted file mode 100644 index d14176787a7..00000000000 --- a/drivers/media/dvb/frontends/lgs8gl5.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver - - Copyright (C) 2008 Sirius International (Hong Kong) Limited - Timothy Lee <timothy.lee@siriushk.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef LGS8GL5_H -#define LGS8GL5_H - -#include <linux/dvb/frontend.h> - -struct lgs8gl5_config { - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_LGS8GL5) || \ - (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE)) -extern struct dvb_frontend *lgs8gl5_attach( - const struct lgs8gl5_config *config, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *lgs8gl5_attach( - const struct lgs8gl5_config *config, struct i2c_adapter *i2c) { - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGS8GL5 */ - -#endif /* LGS8GL5_H */ diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c deleted file mode 100644 index 76f935d9755..00000000000 --- a/drivers/media/dvb/frontends/lnbp21.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * lnbp21.h - driver for lnb supply and control ic lnbp21 - * - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "lnbp21.h" - -struct lnbp21 { - u8 config; - u8 override_or; - u8 override_and; - struct i2c_adapter *i2c; -}; - -static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); - - switch(voltage) { - case SEC_VOLTAGE_OFF: - break; - case SEC_VOLTAGE_13: - lnbp21->config |= LNBP21_EN; - break; - case SEC_VOLTAGE_18: - lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); - break; - default: - return -EINVAL; - }; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) -{ - struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; - struct i2c_msg msg = { .addr = 0x08, .flags = 0, - .buf = &lnbp21->config, - .len = sizeof(lnbp21->config) }; - - if (arg) - lnbp21->config |= LNBP21_LLC; - else - lnbp21->config &= ~LNBP21_LLC; - - lnbp21->config |= lnbp21->override_or; - lnbp21->config &= lnbp21->override_and; - - return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; -} - -static void lnbp21_release(struct dvb_frontend *fe) -{ - /* LNBP power off */ - lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); - - /* free data */ - kfree(fe->sec_priv); - fe->sec_priv = NULL; -} - -struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) -{ - struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); - if (!lnbp21) - return NULL; - - /* default configuration */ - lnbp21->config = LNBP21_ISEL; - lnbp21->i2c = i2c; - fe->sec_priv = lnbp21; - - /* bits which should be forced to '1' */ - lnbp21->override_or = override_set; - - /* bits which should be forced to '0' */ - lnbp21->override_and = ~override_clear; - - /* detect if it is present or not */ - if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { - kfree(lnbp21); - return NULL; - } - - /* install release callback */ - fe->ops.release_sec = lnbp21_release; - - /* override frontend ops */ - fe->ops.set_voltage = lnbp21_set_voltage; - fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - - return fe; -} -EXPORT_SYMBOL(lnbp21_attach); - -MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21"); -MODULE_AUTHOR("Oliver Endriss"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h deleted file mode 100644 index 8fe094bd968..00000000000 --- a/drivers/media/dvb/frontends/lnbp21.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * lnbp21.h - driver for lnb supply and control ic lnbp21 - * - * Copyright (C) 2006 Oliver Endriss - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org - */ - -#ifndef _LNBP21_H -#define _LNBP21_H - -/* system register bits */ -#define LNBP21_OLF 0x01 -#define LNBP21_OTF 0x02 -#define LNBP21_EN 0x04 -#define LNBP21_VSEL 0x08 -#define LNBP21_LLC 0x10 -#define LNBP21_TEN 0x20 -#define LNBP21_ISEL 0x40 -#define LNBP21_PCL 0x80 - -#include <linux/dvb/frontend.h> - -#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE)) -/* override_set and override_clear control which system register bits (above) to always set & clear */ -extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); -#else -static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_LNBP21 - -#endif // _LNBP21_H diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c deleted file mode 100644 index 5ac9b15920f..00000000000 --- a/drivers/media/dvb/frontends/mt312.c +++ /dev/null @@ -1,839 +0,0 @@ -/* - Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder - - Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> - Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - References: - http://products.zarlink.com/product_profiles/MT312.htm - http://products.zarlink.com/product_profiles/SL1935.htm -*/ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "mt312_priv.h" -#include "mt312.h" - - -struct mt312_state { - struct i2c_adapter *i2c; - /* configuration settings */ - const struct mt312_config *config; - struct dvb_frontend frontend; - - u8 id; - unsigned long xtal; - u8 freq_mult; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "mt312: " args); \ - } while (0) - -#define MT312_PLL_CLK 10000000UL /* 10 MHz */ -#define MT312_PLL_CLK_10_111 10111000UL /* 10.111 MHz */ - -static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, - u8 *buf, const size_t count) -{ - int ret; - struct i2c_msg msg[2]; - u8 regbuf[1] = { reg }; - - msg[0].addr = state->config->demod_address; - msg[0].flags = 0; - msg[0].buf = regbuf; - msg[0].len = 1; - msg[1].addr = state->config->demod_address; - msg[1].flags = I2C_M_RD; - msg[1].buf = buf; - msg[1].len = count; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk(KERN_ERR "%s: ret == %d\n", __func__, ret); - return -EREMOTEIO; - } - - if (debug) { - int i; - dprintk("R(%d):", reg & 0x7f); - for (i = 0; i < count; i++) - printk(" %02x", buf[i]); - printk("\n"); - } - - return 0; -} - -static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg, - const u8 *src, const size_t count) -{ - int ret; - u8 buf[count + 1]; - struct i2c_msg msg; - - if (debug) { - int i; - dprintk("W(%d):", reg & 0x7f); - for (i = 0; i < count; i++) - printk(" %02x", src[i]); - printk("\n"); - } - - buf[0] = reg; - memcpy(&buf[1], src, count); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = count + 1; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) { - dprintk("%s: ret == %d\n", __func__, ret); - return -EREMOTEIO; - } - - return 0; -} - -static inline int mt312_readreg(struct mt312_state *state, - const enum mt312_reg_addr reg, u8 *val) -{ - return mt312_read(state, reg, val, 1); -} - -static inline int mt312_writereg(struct mt312_state *state, - const enum mt312_reg_addr reg, const u8 val) -{ - return mt312_write(state, reg, &val, 1); -} - -static inline u32 mt312_div(u32 a, u32 b) -{ - return (a + (b / 2)) / b; -} - -static int mt312_reset(struct mt312_state *state, const u8 full) -{ - return mt312_writereg(state, RESET, full ? 0x80 : 0x40); -} - -static int mt312_get_inversion(struct mt312_state *state, - fe_spectral_inversion_t *i) -{ - int ret; - u8 vit_mode; - - ret = mt312_readreg(state, VIT_MODE, &vit_mode); - if (ret < 0) - return ret; - - if (vit_mode & 0x80) /* auto inversion was used */ - *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF; - - return 0; -} - -static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr) -{ - int ret; - u8 sym_rate_h; - u8 dec_ratio; - u16 sym_rat_op; - u16 monitor; - u8 buf[2]; - - ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h); - if (ret < 0) - return ret; - - if (sym_rate_h & 0x80) { - /* symbol rate search was used */ - ret = mt312_writereg(state, MON_CTRL, 0x03); - if (ret < 0) - return ret; - - ret = mt312_read(state, MONITOR_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - monitor = (buf[0] << 8) | buf[1]; - - dprintk("sr(auto) = %u\n", - mt312_div(monitor * 15625, 4)); - } else { - ret = mt312_writereg(state, MON_CTRL, 0x05); - if (ret < 0) - return ret; - - ret = mt312_read(state, MONITOR_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - dec_ratio = ((buf[0] >> 5) & 0x07) * 32; - - ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - sym_rat_op = (buf[0] << 8) | buf[1]; - - dprintk("sym_rat_op=%d dec_ratio=%d\n", - sym_rat_op, dec_ratio); - dprintk("*sr(manual) = %lu\n", - (((state->xtal * 8192) / (sym_rat_op + 8192)) * - 2) - dec_ratio); - } - - return 0; -} - -static int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr) -{ - const fe_code_rate_t fec_tab[8] = - { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8, - FEC_AUTO, FEC_AUTO }; - - int ret; - u8 fec_status; - - ret = mt312_readreg(state, FEC_STATUS, &fec_status); - if (ret < 0) - return ret; - - *cr = fec_tab[(fec_status >> 4) & 0x07]; - - return 0; -} - -static int mt312_initfe(struct dvb_frontend *fe) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[2]; - - /* wake up */ - ret = mt312_writereg(state, CONFIG, - (state->freq_mult == 6 ? 0x88 : 0x8c)); - if (ret < 0) - return ret; - - /* wait at least 150 usec */ - udelay(150); - - /* full reset */ - ret = mt312_reset(state, 1); - if (ret < 0) - return ret; - -/* Per datasheet, write correct values. 09/28/03 ACCJr. - * If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */ - { - u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02, - 0x01, 0x00, 0x00, 0x00 }; - - ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def)); - if (ret < 0) - return ret; - } - - switch (state->id) { - case ID_ZL10313: - /* enable ADC */ - ret = mt312_writereg(state, GPP_CTRL, 0x80); - if (ret < 0) - return ret; - - /* configure ZL10313 for optimal ADC performance */ - buf[0] = 0x80; - buf[1] = 0xB0; - ret = mt312_write(state, HW_CTRL, buf, 2); - if (ret < 0) - return ret; - - /* enable MPEG output and ADCs */ - ret = mt312_writereg(state, HW_CTRL, 0x00); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, MPEG_CTRL, 0x00); - if (ret < 0) - return ret; - - break; - } - - /* SYS_CLK */ - buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000); - - /* DISEQC_RATIO */ - buf[1] = mt312_div(state->xtal, 22000 * 4); - - ret = mt312_write(state, SYS_CLK, buf, sizeof(buf)); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, SNR_THS_HIGH, 0x32); - if (ret < 0) - return ret; - - /* different MOCLK polarity */ - switch (state->id) { - case ID_ZL10313: - buf[0] = 0x33; - break; - default: - buf[0] = 0x53; - break; - } - - ret = mt312_writereg(state, OP_CTRL, buf[0]); - if (ret < 0) - return ret; - - /* TS_SW_LIM */ - buf[0] = 0x8c; - buf[1] = 0x98; - - ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf)); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, CS_SW_LIM, 0x69); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_send_master_cmd(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *c) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 diseqc_mode; - - if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg))) - return -EINVAL; - - ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); - if (ret < 0) - return ret; - - ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3) - | 0x04); - if (ret < 0) - return ret; - - /* is there a better way to wait for message to be transmitted */ - msleep(100); - - /* set DISEQC_MODE[2:0] to zero if a return message is expected */ - if (c->msg[0] & 0x02) { - ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40)); - if (ret < 0) - return ret; - } - - return 0; -} - -static int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c) -{ - struct mt312_state *state = fe->demodulator_priv; - const u8 mini_tab[2] = { 0x02, 0x03 }; - - int ret; - u8 diseqc_mode; - - if (c > SEC_MINI_B) - return -EINVAL; - - ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | mini_tab[c]); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t) -{ - struct mt312_state *state = fe->demodulator_priv; - const u8 tone_tab[2] = { 0x01, 0x00 }; - - int ret; - u8 diseqc_mode; - - if (t > SEC_TONE_OFF) - return -EINVAL; - - ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); - if (ret < 0) - return ret; - - ret = mt312_writereg(state, DISEQC_MODE, - (diseqc_mode & 0x40) | tone_tab[t]); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v) -{ - struct mt312_state *state = fe->demodulator_priv; - const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; - u8 val; - - if (v > SEC_VOLTAGE_OFF) - return -EINVAL; - - val = volt_tab[v]; - if (state->config->voltage_inverted) - val ^= 0x40; - - return mt312_writereg(state, DISEQC_MODE, val); -} - -static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 status[3]; - - *s = 0; - - ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status)); - if (ret < 0) - return ret; - - dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x," - " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]); - - if (status[0] & 0xc0) - *s |= FE_HAS_SIGNAL; /* signal noise ratio */ - if (status[0] & 0x04) - *s |= FE_HAS_CARRIER; /* qpsk carrier lock */ - if (status[2] & 0x02) - *s |= FE_HAS_VITERBI; /* viterbi lock */ - if (status[2] & 0x04) - *s |= FE_HAS_SYNC; /* byte align lock */ - if (status[0] & 0x01) - *s |= FE_HAS_LOCK; /* qpsk lock */ - - return 0; -} - -static int mt312_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[3]; - - ret = mt312_read(state, RS_BERCNT_H, buf, 3); - if (ret < 0) - return ret; - - *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64; - - return 0; -} - -static int mt312_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[3]; - u16 agc; - s16 err_db; - - ret = mt312_read(state, AGC_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - agc = (buf[0] << 6) | (buf[1] >> 2); - err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6; - - *signal_strength = agc; - - dprintk("agc=%08x err_db=%hd\n", agc, err_db); - - return 0; -} - -static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[2]; - - ret = mt312_read(state, M_SNR_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1); - - return 0; -} - -static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[2]; - - ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - *ubc = (buf[0] << 8) | buf[1]; - - return 0; -} - -static int mt312_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 buf[5], config_val; - u16 sr; - - const u8 fec_tab[10] = - { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f }; - const u8 inv_tab[3] = { 0x00, 0x40, 0x80 }; - - dprintk("%s: Freq %d\n", __func__, p->frequency); - - if ((p->frequency < fe->ops.info.frequency_min) - || (p->frequency > fe->ops.info.frequency_max)) - return -EINVAL; - - if ((p->inversion < INVERSION_OFF) - || (p->inversion > INVERSION_ON)) - return -EINVAL; - - if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) - || (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) - return -EINVAL; - - if ((p->u.qpsk.fec_inner < FEC_NONE) - || (p->u.qpsk.fec_inner > FEC_AUTO)) - return -EINVAL; - - if ((p->u.qpsk.fec_inner == FEC_4_5) - || (p->u.qpsk.fec_inner == FEC_8_9)) - return -EINVAL; - - switch (state->id) { - case ID_VP310: - /* For now we will do this only for the VP310. - * It should be better for the mt312 as well, - * but tuning will be slower. ACCJr 09/29/03 - */ - ret = mt312_readreg(state, CONFIG, &config_val); - if (ret < 0) - return ret; - if (p->u.qpsk.symbol_rate >= 30000000) { - /* Note that 30MS/s should use 90MHz */ - if (state->freq_mult == 6) { - /* We are running 60MHz */ - state->freq_mult = 9; - ret = mt312_initfe(fe); - if (ret < 0) - return ret; - } - } else { - if (state->freq_mult == 9) { - /* We are running 90MHz */ - state->freq_mult = 6; - ret = mt312_initfe(fe); - if (ret < 0) - return ret; - } - } - break; - - case ID_MT312: - case ID_ZL10313: - break; - - default: - return -EINVAL; - } - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* sr = (u16)(sr * 256.0 / 1000000.0) */ - sr = mt312_div(p->u.qpsk.symbol_rate * 4, 15625); - - /* SYM_RATE */ - buf[0] = (sr >> 8) & 0x3f; - buf[1] = (sr >> 0) & 0xff; - - /* VIT_MODE */ - buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner]; - - /* QPSK_CTRL */ - buf[3] = 0x40; /* swap I and Q before QPSK demodulation */ - - if (p->u.qpsk.symbol_rate < 10000000) - buf[3] |= 0x04; /* use afc mode */ - - /* GO */ - buf[4] = 0x01; - - ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf)); - if (ret < 0) - return ret; - - mt312_reset(state, 0); - - return 0; -} - -static int mt312_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - - ret = mt312_get_inversion(state, &p->inversion); - if (ret < 0) - return ret; - - ret = mt312_get_symbol_rate(state, &p->u.qpsk.symbol_rate); - if (ret < 0) - return ret; - - ret = mt312_get_code_rate(state, &p->u.qpsk.fec_inner); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct mt312_state *state = fe->demodulator_priv; - - u8 val = 0x00; - int ret; - - switch (state->id) { - case ID_ZL10313: - ret = mt312_readreg(state, GPP_CTRL, &val); - if (ret < 0) - goto error; - - /* preserve this bit to not accidently shutdown ADC */ - val &= 0x80; - break; - } - - if (enable) - val |= 0x40; - else - val &= ~0x40; - - ret = mt312_writereg(state, GPP_CTRL, val); - -error: - return ret; -} - -static int mt312_sleep(struct dvb_frontend *fe) -{ - struct mt312_state *state = fe->demodulator_priv; - int ret; - u8 config; - - /* reset all registers to defaults */ - ret = mt312_reset(state, 1); - if (ret < 0) - return ret; - - if (state->id == ID_ZL10313) { - /* reset ADC */ - ret = mt312_writereg(state, GPP_CTRL, 0x00); - if (ret < 0) - return ret; - - /* full shutdown of ADCs, mpeg bus tristated */ - ret = mt312_writereg(state, HW_CTRL, 0x0d); - if (ret < 0) - return ret; - } - - ret = mt312_readreg(state, CONFIG, &config); - if (ret < 0) - return ret; - - /* enter standby */ - ret = mt312_writereg(state, CONFIG, config & 0x7f); - if (ret < 0) - return ret; - - return 0; -} - -static int mt312_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *fesettings) -{ - fesettings->min_delay_ms = 50; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void mt312_release(struct dvb_frontend *fe) -{ - struct mt312_state *state = fe->demodulator_priv; - kfree(state); -} - -#define MT312_SYS_CLK 90000000UL /* 90 MHz */ -static struct dvb_frontend_ops mt312_ops = { - - .info = { - .name = "Zarlink ???? DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */ - .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */ - .symbol_rate_max = MT312_SYS_CLK / 2, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS | - FE_CAN_RECOVER - }, - - .release = mt312_release, - - .init = mt312_initfe, - .sleep = mt312_sleep, - .i2c_gate_ctrl = mt312_i2c_gate_ctrl, - - .set_frontend = mt312_set_frontend, - .get_frontend = mt312_get_frontend, - .get_tune_settings = mt312_get_tune_settings, - - .read_status = mt312_read_status, - .read_ber = mt312_read_ber, - .read_signal_strength = mt312_read_signal_strength, - .read_snr = mt312_read_snr, - .read_ucblocks = mt312_read_ucblocks, - - .diseqc_send_master_cmd = mt312_send_master_cmd, - .diseqc_send_burst = mt312_send_burst, - .set_tone = mt312_set_tone, - .set_voltage = mt312_set_voltage, -}; - -struct dvb_frontend *mt312_attach(const struct mt312_config *config, - struct i2c_adapter *i2c) -{ - struct mt312_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (mt312_readreg(state, ID, &state->id) < 0) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &mt312_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - switch (state->id) { - case ID_VP310: - strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); - state->xtal = MT312_PLL_CLK; - state->freq_mult = 9; - break; - case ID_MT312: - strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); - state->xtal = MT312_PLL_CLK; - state->freq_mult = 6; - break; - case ID_ZL10313: - strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S"); - state->xtal = MT312_PLL_CLK_10_111; - state->freq_mult = 9; - break; - default: - printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313" - " are supported chips.\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(mt312_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); -MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h deleted file mode 100644 index 29e3bb5496b..00000000000 --- a/drivers/media/dvb/frontends/mt312.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Driver for Zarlink MT312 Satellite Channel Decoder - - Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - References: - http://products.zarlink.com/product_profiles/MT312.htm - http://products.zarlink.com/product_profiles/SL1935.htm -*/ - -#ifndef MT312_H -#define MT312_H - -#include <linux/dvb/frontend.h> - -struct mt312_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* inverted voltage setting */ - unsigned int voltage_inverted:1; -}; - -#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE)) -struct dvb_frontend *mt312_attach(const struct mt312_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *mt312_attach( - const struct mt312_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_MT312 */ - -#endif /* MT312_H */ diff --git a/drivers/media/dvb/frontends/mt312_priv.h b/drivers/media/dvb/frontends/mt312_priv.h deleted file mode 100644 index a3959f94d63..00000000000 --- a/drivers/media/dvb/frontends/mt312_priv.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - Driver for Zarlink MT312 QPSK Frontend - - Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef _DVB_FRONTENDS_MT312_PRIV -#define _DVB_FRONTENDS_MT312_PRIV - -enum mt312_reg_addr { - QPSK_INT_H = 0, - QPSK_INT_M = 1, - QPSK_INT_L = 2, - FEC_INT = 3, - QPSK_STAT_H = 4, - QPSK_STAT_L = 5, - FEC_STATUS = 6, - LNB_FREQ_H = 7, - LNB_FREQ_L = 8, - M_SNR_H = 9, - M_SNR_L = 10, - VIT_ERRCNT_H = 11, - VIT_ERRCNT_M = 12, - VIT_ERRCNT_L = 13, - RS_BERCNT_H = 14, - RS_BERCNT_M = 15, - RS_BERCNT_L = 16, - RS_UBC_H = 17, - RS_UBC_L = 18, - SIG_LEVEL = 19, - GPP_CTRL = 20, - RESET = 21, - DISEQC_MODE = 22, - SYM_RATE_H = 23, - SYM_RATE_L = 24, - VIT_MODE = 25, - QPSK_CTRL = 26, - GO = 27, - IE_QPSK_H = 28, - IE_QPSK_M = 29, - IE_QPSK_L = 30, - IE_FEC = 31, - QPSK_STAT_EN = 32, - FEC_STAT_EN = 33, - SYS_CLK = 34, - DISEQC_RATIO = 35, - DISEQC_INSTR = 36, - FR_LIM = 37, - FR_OFF = 38, - AGC_CTRL = 39, - AGC_INIT = 40, - AGC_REF = 41, - AGC_MAX = 42, - AGC_MIN = 43, - AGC_LK_TH = 44, - TS_AGC_LK_TH = 45, - AGC_PWR_SET = 46, - QPSK_MISC = 47, - SNR_THS_LOW = 48, - SNR_THS_HIGH = 49, - TS_SW_RATE = 50, - TS_SW_LIM_L = 51, - TS_SW_LIM_H = 52, - CS_SW_RATE_1 = 53, - CS_SW_RATE_2 = 54, - CS_SW_RATE_3 = 55, - CS_SW_RATE_4 = 56, - CS_SW_LIM = 57, - TS_LPK = 58, - TS_LPK_M = 59, - TS_LPK_L = 60, - CS_KPROP_H = 61, - CS_KPROP_L = 62, - CS_KINT_H = 63, - CS_KINT_L = 64, - QPSK_SCALE = 65, - TLD_OUTCLK_TH = 66, - TLD_INCLK_TH = 67, - FLD_TH = 68, - PLD_OUTLK3 = 69, - PLD_OUTLK2 = 70, - PLD_OUTLK1 = 71, - PLD_OUTLK0 = 72, - PLD_INLK3 = 73, - PLD_INLK2 = 74, - PLD_INLK1 = 75, - PLD_INLK0 = 76, - PLD_ACC_TIME = 77, - SWEEP_PAR = 78, - STARTUP_TIME = 79, - LOSSLOCK_TH = 80, - FEC_LOCK_TM = 81, - LOSSLOCK_TM = 82, - VIT_ERRPER_H = 83, - VIT_ERRPER_M = 84, - VIT_ERRPER_L = 85, - HW_CTRL = 84, /* ZL10313 only */ - MPEG_CTRL = 85, /* ZL10313 only */ - VIT_SETUP = 86, - VIT_REF0 = 87, - VIT_REF1 = 88, - VIT_REF2 = 89, - VIT_REF3 = 90, - VIT_REF4 = 91, - VIT_REF5 = 92, - VIT_REF6 = 93, - VIT_MAXERR = 94, - BA_SETUPT = 95, - OP_CTRL = 96, - FEC_SETUP = 97, - PROG_SYNC = 98, - AFC_SEAR_TH = 99, - CSACC_DIF_TH = 100, - QPSK_LK_CT = 101, - QPSK_ST_CT = 102, - MON_CTRL = 103, - QPSK_RESET = 104, - QPSK_TST_CT = 105, - QPSK_TST_ST = 106, - TEST_R = 107, - AGC_H = 108, - AGC_M = 109, - AGC_L = 110, - FREQ_ERR1_H = 111, - FREQ_ERR1_M = 112, - FREQ_ERR1_L = 113, - FREQ_ERR2_H = 114, - FREQ_ERR2_L = 115, - SYM_RAT_OP_H = 116, - SYM_RAT_OP_L = 117, - DESEQC2_INT = 118, - DISEQC2_STAT = 119, - DISEQC2_FIFO = 120, - DISEQC2_CTRL1 = 121, - DISEQC2_CTRL2 = 122, - MONITOR_H = 123, - MONITOR_L = 124, - TEST_MODE = 125, - ID = 126, - CONFIG = 127 -}; - -enum mt312_model_id { - ID_VP310 = 1, - ID_MT312 = 3, - ID_ZL10313 = 5, -}; - -#endif /* DVB_FRONTENDS_MT312_PRIV */ diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c deleted file mode 100644 index beba5aa0db5..00000000000 --- a/drivers/media/dvb/frontends/mt352.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Driver for Zarlink DVB-T MT352 demodulator - * - * Written by Holger Waechtler <holger@qanu.de> - * and Daniel Mack <daniel@qanu.de> - * - * AVerMedia AVerTV DVB-T 771 support by - * Wolfram Joost <dbox2@frokaschwei.de> - * - * Support for Samsung TDTC9251DH01C(M) tuner - * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it> - * Amauri Celani <acelani@essegi.net> - * - * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by - * Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "mt352_priv.h" -#include "mt352.h" - -struct mt352_state { - struct i2c_adapter* i2c; - struct dvb_frontend frontend; - - /* configuration settings */ - struct mt352_config config; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "mt352: " args); \ - } while (0) - -static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val) -{ - struct mt352_state* state = fe->demodulator_priv; - u8 buf[2] = { reg, val }; - struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, - .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("mt352_write() to reg %x failed (err = %d)!\n", reg, err); - return err; - } - return 0; -} - -static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) -{ - int err,i; - for (i=0; i < ilen-1; i++) - if ((err = mt352_single_write(fe,ibuf[0]+i,ibuf[i+1]))) - return err; - - return 0; -} - -static int mt352_read_register(struct mt352_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config.demod_address, - .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config.demod_address, - .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: readreg error (reg=%d, ret==%i)\n", - __func__, reg, ret); - return ret; - } - - return b1[0]; -} - -static int mt352_sleep(struct dvb_frontend* fe) -{ - static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; - - _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown)); - return 0; -} - -static void mt352_calc_nominal_rate(struct mt352_state* state, - enum fe_bandwidth bandwidth, - unsigned char *buf) -{ - u32 adc_clock = 20480; /* 20.340 MHz */ - u32 bw,value; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - bw = 6; - break; - case BANDWIDTH_7_MHZ: - bw = 7; - break; - case BANDWIDTH_8_MHZ: - default: - bw = 8; - break; - } - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - - value = 64 * bw * (1<<16) / (7 * 8); - value = value * 1000 / adc_clock; - dprintk("%s: bw %d, adc_clock %d => 0x%x\n", - __func__, bw, adc_clock, value); - buf[0] = msb(value); - buf[1] = lsb(value); -} - -static void mt352_calc_input_freq(struct mt352_state* state, - unsigned char *buf) -{ - int adc_clock = 20480; /* 20.480000 MHz */ - int if2 = 36167; /* 36.166667 MHz */ - int ife,value; - - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - if (state->config.if2) - if2 = state->config.if2; - - if (adc_clock >= if2 * 2) - ife = if2; - else { - ife = adc_clock - (if2 % adc_clock); - if (ife > adc_clock / 2) - ife = adc_clock - ife; - } - value = -16374 * ife / adc_clock; - dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __func__, if2, ife, adc_clock, value, value & 0x3fff); - buf[0] = msb(value); - buf[1] = lsb(value); -} - -static int mt352_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct mt352_state* state = fe->demodulator_priv; - unsigned char buf[13]; - static unsigned char tuner_go[] = { 0x5d, 0x01 }; - static unsigned char fsm_go[] = { 0x5e, 0x01 }; - unsigned int tps = 0; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - - switch (op->code_rate_HP) { - case FEC_2_3: - tps |= (1 << 7); - break; - case FEC_3_4: - tps |= (2 << 7); - break; - case FEC_5_6: - tps |= (3 << 7); - break; - case FEC_7_8: - tps |= (4 << 7); - break; - case FEC_1_2: - case FEC_AUTO: - break; - default: - return -EINVAL; - } - - switch (op->code_rate_LP) { - case FEC_2_3: - tps |= (1 << 4); - break; - case FEC_3_4: - tps |= (2 << 4); - break; - case FEC_5_6: - tps |= (3 << 4); - break; - case FEC_7_8: - tps |= (4 << 4); - break; - case FEC_1_2: - case FEC_AUTO: - break; - case FEC_NONE: - if (op->hierarchy_information == HIERARCHY_AUTO || - op->hierarchy_information == HIERARCHY_NONE) - break; - default: - return -EINVAL; - } - - switch (op->constellation) { - case QPSK: - break; - case QAM_AUTO: - case QAM_16: - tps |= (1 << 13); - break; - case QAM_64: - tps |= (2 << 13); - break; - default: - return -EINVAL; - } - - switch (op->transmission_mode) { - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - break; - case TRANSMISSION_MODE_8K: - tps |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - break; - case GUARD_INTERVAL_1_16: - tps |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - tps |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - tps |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (op->hierarchy_information) { - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - tps |= (1 << 10); - break; - case HIERARCHY_2: - tps |= (2 << 10); - break; - case HIERARCHY_4: - tps |= (3 << 10); - break; - default: - return -EINVAL; - } - - - buf[0] = TPS_GIVEN_1; /* TPS_GIVEN_1 and following registers */ - - buf[1] = msb(tps); /* TPS_GIVEN_(1|0) */ - buf[2] = lsb(tps); - - buf[3] = 0x50; // old -// buf[3] = 0xf4; // pinnacle - - mt352_calc_nominal_rate(state, op->bandwidth, buf+4); - mt352_calc_input_freq(state, buf+6); - - if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - _mt352_write(fe, buf, 8); - _mt352_write(fe, fsm_go, 2); - } else { - if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); - buf[8] <<= 1; - _mt352_write(fe, buf, sizeof(buf)); - _mt352_write(fe, tuner_go, 2); - } - } - - return 0; -} - -static int mt352_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct mt352_state* state = fe->demodulator_priv; - u16 tps; - u16 div; - u8 trl; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - static const u8 tps_fec_to_api[8] = - { - FEC_1_2, - FEC_2_3, - FEC_3_4, - FEC_5_6, - FEC_7_8, - FEC_AUTO, - FEC_AUTO, - FEC_AUTO - }; - - if ( (mt352_read_register(state,0x00) & 0xC0) != 0xC0 ) - return -EINVAL; - - /* Use TPS_RECEIVED-registers, not the TPS_CURRENT-registers because - * the mt352 sometimes works with the wrong parameters - */ - tps = (mt352_read_register(state, TPS_RECEIVED_1) << 8) | mt352_read_register(state, TPS_RECEIVED_0); - div = (mt352_read_register(state, CHAN_START_1) << 8) | mt352_read_register(state, CHAN_START_0); - trl = mt352_read_register(state, TRL_NOMINAL_RATE_1); - - op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; - op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; - - switch ( (tps >> 13) & 3) - { - case 0: - op->constellation = QPSK; - break; - case 1: - op->constellation = QAM_16; - break; - case 2: - op->constellation = QAM_64; - break; - default: - op->constellation = QAM_AUTO; - break; - } - - op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : TRANSMISSION_MODE_2K; - - switch ( (tps >> 2) & 3) - { - case 0: - op->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - op->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - op->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - op->guard_interval = GUARD_INTERVAL_1_4; - break; - default: - op->guard_interval = GUARD_INTERVAL_AUTO; - break; - } - - switch ( (tps >> 10) & 7) - { - case 0: - op->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - op->hierarchy_information = HIERARCHY_1; - break; - case 2: - op->hierarchy_information = HIERARCHY_2; - break; - case 3: - op->hierarchy_information = HIERARCHY_4; - break; - default: - op->hierarchy_information = HIERARCHY_AUTO; - break; - } - - param->frequency = ( 500 * (div - IF_FREQUENCYx6) ) / 3 * 1000; - - if (trl == 0x72) - op->bandwidth = BANDWIDTH_8_MHZ; - else if (trl == 0x64) - op->bandwidth = BANDWIDTH_7_MHZ; - else - op->bandwidth = BANDWIDTH_6_MHZ; - - - if (mt352_read_register(state, STATUS_2) & 0x02) - param->inversion = INVERSION_OFF; - else - param->inversion = INVERSION_ON; - - return 0; -} - -static int mt352_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct mt352_state* state = fe->demodulator_priv; - int s0, s1, s3; - - /* FIXME: - * - * The MT352 design manual from Zarlink states (page 46-47): - * - * Notes about the TUNER_GO register: - * - * If the Read_Tuner_Byte (bit-1) is activated, then the tuner status - * byte is copied from the tuner to the STATUS_3 register and - * completion of the read operation is indicated by bit-5 of the - * INTERRUPT_3 register. - */ - - if ((s0 = mt352_read_register(state, STATUS_0)) < 0) - return -EREMOTEIO; - if ((s1 = mt352_read_register(state, STATUS_1)) < 0) - return -EREMOTEIO; - if ((s3 = mt352_read_register(state, STATUS_3)) < 0) - return -EREMOTEIO; - - *status = 0; - if (s0 & (1 << 4)) - *status |= FE_HAS_CARRIER; - if (s0 & (1 << 1)) - *status |= FE_HAS_VITERBI; - if (s0 & (1 << 5)) - *status |= FE_HAS_LOCK; - if (s1 & (1 << 1)) - *status |= FE_HAS_SYNC; - if (s3 & (1 << 6)) - *status |= FE_HAS_SIGNAL; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int mt352_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct mt352_state* state = fe->demodulator_priv; - - *ber = (mt352_read_register (state, RS_ERR_CNT_2) << 16) | - (mt352_read_register (state, RS_ERR_CNT_1) << 8) | - (mt352_read_register (state, RS_ERR_CNT_0)); - - return 0; -} - -static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct mt352_state* state = fe->demodulator_priv; - - /* align the 12 bit AGC gain with the most significant bits */ - u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) | - (mt352_read_register(state, AGC_GAIN_0) << 4); - - /* inverse of gain is signal strength */ - *strength = ~signal; - return 0; -} - -static int mt352_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct mt352_state* state = fe->demodulator_priv; - - u8 _snr = mt352_read_register (state, SNR); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int mt352_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct mt352_state* state = fe->demodulator_priv; - - *ucblocks = (mt352_read_register (state, RS_UBC_1) << 8) | - (mt352_read_register (state, RS_UBC_0)); - - return 0; -} - -static int mt352_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 800; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int mt352_init(struct dvb_frontend* fe) -{ - struct mt352_state* state = fe->demodulator_priv; - - static u8 mt352_reset_attach [] = { RESET, 0xC0 }; - - dprintk("%s: hello\n",__func__); - - if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 || - (mt352_read_register(state, CONFIG) & 0x20) == 0) { - - /* Do a "hard" reset */ - _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach)); - return state->config.demod_init(fe); - } - - return 0; -} - -static void mt352_release(struct dvb_frontend* fe) -{ - struct mt352_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops mt352_ops; - -struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c) -{ - struct mt352_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config,config,sizeof(struct mt352_config)); - - /* check if the demod is there */ - if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops mt352_ops = { - - .info = { - .name = "Zarlink MT352 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = mt352_release, - - .init = mt352_init, - .sleep = mt352_sleep, - .write = _mt352_write, - - .set_frontend = mt352_set_parameters, - .get_frontend = mt352_get_parameters, - .get_tune_settings = mt352_get_tune_settings, - - .read_status = mt352_read_status, - .read_ber = mt352_read_ber, - .read_signal_strength = mt352_read_signal_strength, - .read_snr = mt352_read_snr, - .read_ucblocks = mt352_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Zarlink MT352 DVB-T Demodulator driver"); -MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(mt352_attach); diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h deleted file mode 100644 index 595092f9f0c..00000000000 --- a/drivers/media/dvb/frontends/mt352.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Driver for Zarlink DVB-T MT352 demodulator - * - * Written by Holger Waechtler <holger@qanu.de> - * and Daniel Mack <daniel@qanu.de> - * - * AVerMedia AVerTV DVB-T 771 support by - * Wolfram Joost <dbox2@frokaschwei.de> - * - * Support for Samsung TDTC9251DH01C(M) tuner - * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it> - * Amauri Celani <acelani@essegi.net> - * - * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by - * Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef MT352_H -#define MT352_H - -#include <linux/dvb/frontend.h> - -struct mt352_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* frequencies in kHz */ - int adc_clock; // default: 20480 - int if2; // default: 36166 - - /* set if no pll is connected to the secondary i2c bus */ - int no_tuner; - - /* Initialise the demodulator and PLL. Cannot be NULL */ - int (*demod_init)(struct dvb_frontend* fe); -}; - -#if defined(CONFIG_DVB_MT352) || (defined(CONFIG_DVB_MT352_MODULE) && defined(MODULE)) -extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_MT352 - -static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) { - int r = 0; - if (fe->ops.write) - r = fe->ops.write(fe, buf, len); - return r; -} - -#endif // MT352_H diff --git a/drivers/media/dvb/frontends/mt352_priv.h b/drivers/media/dvb/frontends/mt352_priv.h deleted file mode 100644 index 44ad0d4c8f1..00000000000 --- a/drivers/media/dvb/frontends/mt352_priv.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Driver for Zarlink DVB-T MT352 demodulator - * - * Written by Holger Waechtler <holger@qanu.de> - * and Daniel Mack <daniel@qanu.de> - * - * AVerMedia AVerTV DVB-T 771 support by - * Wolfram Joost <dbox2@frokaschwei.de> - * - * Support for Samsung TDTC9251DH01C(M) tuner - * Copyright (C) 2004 Antonio Mancuso <antonio.mancuso@digitaltelevision.it> - * Amauri Celani <acelani@essegi.net> - * - * DVICO FusionHDTV DVB-T1 and DVICO FusionHDTV DVB-T Lite support by - * Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef _MT352_PRIV_ -#define _MT352_PRIV_ - -#define ID_MT352 0x13 - -#define msb(x) (((x) >> 8) & 0xff) -#define lsb(x) ((x) & 0xff) - -enum mt352_reg_addr { - STATUS_0 = 0x00, - STATUS_1 = 0x01, - STATUS_2 = 0x02, - STATUS_3 = 0x03, - STATUS_4 = 0x04, - INTERRUPT_0 = 0x05, - INTERRUPT_1 = 0x06, - INTERRUPT_2 = 0x07, - INTERRUPT_3 = 0x08, - SNR = 0x09, - VIT_ERR_CNT_2 = 0x0A, - VIT_ERR_CNT_1 = 0x0B, - VIT_ERR_CNT_0 = 0x0C, - RS_ERR_CNT_2 = 0x0D, - RS_ERR_CNT_1 = 0x0E, - RS_ERR_CNT_0 = 0x0F, - RS_UBC_1 = 0x10, - RS_UBC_0 = 0x11, - AGC_GAIN_3 = 0x12, - AGC_GAIN_2 = 0x13, - AGC_GAIN_1 = 0x14, - AGC_GAIN_0 = 0x15, - FREQ_OFFSET_2 = 0x17, - FREQ_OFFSET_1 = 0x18, - FREQ_OFFSET_0 = 0x19, - TIMING_OFFSET_1 = 0x1A, - TIMING_OFFSET_0 = 0x1B, - CHAN_FREQ_1 = 0x1C, - CHAN_FREQ_0 = 0x1D, - TPS_RECEIVED_1 = 0x1E, - TPS_RECEIVED_0 = 0x1F, - TPS_CURRENT_1 = 0x20, - TPS_CURRENT_0 = 0x21, - TPS_CELL_ID_1 = 0x22, - TPS_CELL_ID_0 = 0x23, - TPS_MISC_DATA_2 = 0x24, - TPS_MISC_DATA_1 = 0x25, - TPS_MISC_DATA_0 = 0x26, - RESET = 0x50, - TPS_GIVEN_1 = 0x51, - TPS_GIVEN_0 = 0x52, - ACQ_CTL = 0x53, - TRL_NOMINAL_RATE_1 = 0x54, - TRL_NOMINAL_RATE_0 = 0x55, - INPUT_FREQ_1 = 0x56, - INPUT_FREQ_0 = 0x57, - TUNER_ADDR = 0x58, - CHAN_START_1 = 0x59, - CHAN_START_0 = 0x5A, - CONT_1 = 0x5B, - CONT_0 = 0x5C, - TUNER_GO = 0x5D, - STATUS_EN_0 = 0x5F, - STATUS_EN_1 = 0x60, - INTERRUPT_EN_0 = 0x61, - INTERRUPT_EN_1 = 0x62, - INTERRUPT_EN_2 = 0x63, - INTERRUPT_EN_3 = 0x64, - AGC_TARGET = 0x67, - AGC_CTL = 0x68, - CAPT_RANGE = 0x75, - SNR_SELECT_1 = 0x79, - SNR_SELECT_0 = 0x7A, - RS_ERR_PER_1 = 0x7C, - RS_ERR_PER_0 = 0x7D, - CHIP_ID = 0x7F, - CHAN_STOP_1 = 0x80, - CHAN_STOP_0 = 0x81, - CHAN_STEP_1 = 0x82, - CHAN_STEP_0 = 0x83, - FEC_LOCK_TIME = 0x85, - OFDM_LOCK_TIME = 0x86, - ACQ_DELAY = 0x87, - SCAN_CTL = 0x88, - CLOCK_CTL = 0x89, - CONFIG = 0x8A, - MCLK_RATIO = 0x8B, - GPP_CTL = 0x8C, - ADC_CTL_1 = 0x8E, - ADC_CTL_0 = 0x8F -}; - -/* here we assume 1/6MHz == 166.66kHz stepsize */ -#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ - -#endif /* _MT352_PRIV_ */ diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c deleted file mode 100644 index a8429ebfa8a..00000000000 --- a/drivers/media/dvb/frontends/nxt200x.c +++ /dev/null @@ -1,1239 +0,0 @@ -/* - * Support for NXT2002 and NXT2004 - VSB/QAM - * - * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> - * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net> - * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> - * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ - -/* - * NOTES ABOUT THIS DRIVER - * - * This Linux driver supports: - * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002) - * AverTVHD MCE A180 (NXT2004) - * ATI HDTV Wonder (NXT2004) - * - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or - * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to - * download/extract the appropriate firmware, and then copy it to - * /usr/lib/hotplug/firmware/ or /lib/firmware/ - * (depending on configuration of firmware hotplug). - */ -#define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" -#define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw" -#define CRC_CCIT_MASK 0x1021 - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/string.h> - -#include "dvb_frontend.h" -#include "nxt200x.h" - -struct nxt200x_state { - - struct i2c_adapter* i2c; - const struct nxt200x_config* config; - struct dvb_frontend frontend; - - /* demodulator private data */ - nxt_chip_type demod_chip; - u8 initialised:1; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "nxt200x: " args); \ - } while (0) - -static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len) -{ - int err; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len }; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", - __func__, addr, err); - return -EREMOTEIO; - } - return 0; -} - -static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len) -{ - int err; - struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", - __func__, addr, err); - return -EREMOTEIO; - } - return 0; -} - -static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, - const u8 *buf, u8 len) -{ - u8 buf2 [len+1]; - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 }; - - buf2[0] = reg; - memcpy(&buf2[1], buf, len); - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n", - __func__, state->config->demod_address, err); - return -EREMOTEIO; - } - return 0; -} - -static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len) -{ - u8 reg2 [] = { reg }; - - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; - - int err; - - if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { - printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n", - __func__, state->config->demod_address, err); - return -EREMOTEIO; - } - return 0; -} - -static u16 nxt200x_crc(u16 crc, u8 c) -{ - u8 i; - u16 input = (u16) c & 0xFF; - - input<<=8; - for(i=0; i<8; i++) { - if((crc^input) & 0x8000) - crc=(crc<<1)^CRC_CCIT_MASK; - else - crc<<=1; - input<<=1; - } - return crc; -} - -static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) -{ - u8 attr, len2, buf; - dprintk("%s\n", __func__); - - /* set mutli register register */ - nxt200x_writebytes(state, 0x35, ®, 1); - - /* send the actual data */ - nxt200x_writebytes(state, 0x36, data, len); - - switch (state->demod_chip) { - case NXT2002: - len2 = len; - buf = 0x02; - break; - case NXT2004: - /* probably not right, but gives correct values */ - attr = 0x02; - if (reg & 0x80) { - attr = attr << 1; - if (reg & 0x04) - attr = attr >> 1; - } - /* set write bit */ - len2 = ((attr << 4) | 0x10) | len; - buf = 0x80; - break; - default: - return -EINVAL; - break; - } - - /* set multi register length */ - nxt200x_writebytes(state, 0x34, &len2, 1); - - /* toggle the multireg write bit */ - nxt200x_writebytes(state, 0x21, &buf, 1); - - nxt200x_readbytes(state, 0x21, &buf, 1); - - switch (state->demod_chip) { - case NXT2002: - if ((buf & 0x02) == 0) - return 0; - break; - case NXT2004: - if (buf == 0) - return 0; - break; - default: - return -EINVAL; - break; - } - - printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg); - - return 0; -} - -static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len) -{ - int i; - u8 buf, len2, attr; - dprintk("%s\n", __func__); - - /* set mutli register register */ - nxt200x_writebytes(state, 0x35, ®, 1); - - switch (state->demod_chip) { - case NXT2002: - /* set multi register length */ - len2 = len & 0x80; - nxt200x_writebytes(state, 0x34, &len2, 1); - - /* read the actual data */ - nxt200x_readbytes(state, reg, data, len); - return 0; - break; - case NXT2004: - /* probably not right, but gives correct values */ - attr = 0x02; - if (reg & 0x80) { - attr = attr << 1; - if (reg & 0x04) - attr = attr >> 1; - } - - /* set multi register length */ - len2 = (attr << 4) | len; - nxt200x_writebytes(state, 0x34, &len2, 1); - - /* toggle the multireg bit*/ - buf = 0x80; - nxt200x_writebytes(state, 0x21, &buf, 1); - - /* read the actual data */ - for(i = 0; i < len; i++) { - nxt200x_readbytes(state, 0x36 + i, &data[i], 1); - } - return 0; - break; - default: - return -EINVAL; - break; - } -} - -static void nxt200x_microcontroller_stop (struct nxt200x_state* state) -{ - u8 buf, stopval, counter = 0; - dprintk("%s\n", __func__); - - /* set correct stop value */ - switch (state->demod_chip) { - case NXT2002: - stopval = 0x40; - break; - case NXT2004: - stopval = 0x10; - break; - default: - stopval = 0; - break; - } - - buf = 0x80; - nxt200x_writebytes(state, 0x22, &buf, 1); - - while (counter < 20) { - nxt200x_readbytes(state, 0x31, &buf, 1); - if (buf & stopval) - return; - msleep(10); - counter++; - } - - printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n"); - return; -} - -static void nxt200x_microcontroller_start (struct nxt200x_state* state) -{ - u8 buf; - dprintk("%s\n", __func__); - - buf = 0x00; - nxt200x_writebytes(state, 0x22, &buf, 1); -} - -static void nxt2004_microcontroller_init (struct nxt200x_state* state) -{ - u8 buf[9]; - u8 counter = 0; - dprintk("%s\n", __func__); - - buf[0] = 0x00; - nxt200x_writebytes(state, 0x2b, buf, 1); - buf[0] = 0x70; - nxt200x_writebytes(state, 0x34, buf, 1); - buf[0] = 0x04; - nxt200x_writebytes(state, 0x35, buf, 1); - buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89; - buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0; - nxt200x_writebytes(state, 0x36, buf, 9); - buf[0] = 0x80; - nxt200x_writebytes(state, 0x21, buf, 1); - - while (counter < 20) { - nxt200x_readbytes(state, 0x21, buf, 1); - if (buf[0] == 0) - return; - msleep(10); - counter++; - } - - printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n"); - - return; -} - -static int nxt200x_writetuner (struct nxt200x_state* state, u8* data) -{ - u8 buf, count = 0; - - dprintk("%s\n", __func__); - - dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]); - - /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip. - * direct write is required for Philips TUV1236D and ALPS TDHU2 */ - switch (state->demod_chip) { - case NXT2004: - if (i2c_writebytes(state, data[0], data+1, 4)) - printk(KERN_WARNING "nxt200x: error writing to tuner\n"); - /* wait until we have a lock */ - while (count < 20) { - i2c_readbytes(state, data[0], &buf, 1); - if (buf & 0x40) - return 0; - msleep(100); - count++; - } - printk("nxt2004: timeout waiting for tuner lock\n"); - break; - case NXT2002: - /* set the i2c transfer speed to the tuner */ - buf = 0x03; - nxt200x_writebytes(state, 0x20, &buf, 1); - - /* setup to transfer 4 bytes via i2c */ - buf = 0x04; - nxt200x_writebytes(state, 0x34, &buf, 1); - - /* write actual tuner bytes */ - nxt200x_writebytes(state, 0x36, data+1, 4); - - /* set tuner i2c address */ - buf = data[0] << 1; - nxt200x_writebytes(state, 0x35, &buf, 1); - - /* write UC Opmode to begin transfer */ - buf = 0x80; - nxt200x_writebytes(state, 0x21, &buf, 1); - - while (count < 20) { - nxt200x_readbytes(state, 0x21, &buf, 1); - if ((buf & 0x80)== 0x00) - return 0; - msleep(100); - count++; - } - printk("nxt2002: timeout error writing tuner\n"); - break; - default: - return -EINVAL; - break; - } - return 0; -} - -static void nxt200x_agc_reset(struct nxt200x_state* state) -{ - u8 buf; - dprintk("%s\n", __func__); - - switch (state->demod_chip) { - case NXT2002: - buf = 0x08; - nxt200x_writebytes(state, 0x08, &buf, 1); - buf = 0x00; - nxt200x_writebytes(state, 0x08, &buf, 1); - break; - case NXT2004: - nxt200x_readreg_multibyte(state, 0x08, &buf, 1); - buf = 0x08; - nxt200x_writereg_multibyte(state, 0x08, &buf, 1); - buf = 0x00; - nxt200x_writereg_multibyte(state, 0x08, &buf, 1); - break; - default: - break; - } - return; -} - -static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - - struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[3], written = 0, chunkpos = 0; - u16 rambase, position, crc = 0; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes\n", fw->size); - - /* Get the RAM base for this nxt2002 */ - nxt200x_readbytes(state, 0x10, buf, 1); - - if (buf[0] & 0x10) - rambase = 0x1000; - else - rambase = 0x0000; - - dprintk("rambase on this nxt2002 is %04X\n", rambase); - - /* Hold the micro in reset while loading firmware */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf, 1); - - for (position = 0; position < fw->size; position++) { - if (written == 0) { - crc = 0; - chunkpos = 0x28; - buf[0] = ((rambase + position) >> 8); - buf[1] = (rambase + position) & 0xFF; - buf[2] = 0x81; - /* write starting address */ - nxt200x_writebytes(state, 0x29, buf, 3); - } - written++; - chunkpos++; - - if ((written % 4) == 0) - nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4); - - crc = nxt200x_crc(crc, fw->data[position]); - - if ((written == 255) || (position+1 == fw->size)) { - /* write remaining bytes of firmware */ - nxt200x_writebytes(state, chunkpos+4-(written %4), - &fw->data[position-(written %4) + 1], - written %4); - buf[0] = crc << 8; - buf[1] = crc & 0xFF; - - /* write crc */ - nxt200x_writebytes(state, 0x2C, buf, 2); - - /* do a read to stop things */ - nxt200x_readbytes(state, 0x2A, buf, 1); - - /* set transfer mode to complete */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf, 1); - - written = 0; - } - } - - return 0; -}; - -static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - - struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[3]; - u16 rambase, position, crc=0; - - dprintk("%s\n", __func__); - dprintk("Firmware is %zu bytes\n", fw->size); - - /* set rambase */ - rambase = 0x1000; - - /* hold the micro in reset while loading firmware */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf,1); - - /* calculate firmware CRC */ - for (position = 0; position < fw->size; position++) { - crc = nxt200x_crc(crc, fw->data[position]); - } - - buf[0] = rambase >> 8; - buf[1] = rambase & 0xFF; - buf[2] = 0x81; - /* write starting address */ - nxt200x_writebytes(state,0x29,buf,3); - - for (position = 0; position < fw->size;) { - nxt200x_writebytes(state, 0x2C, &fw->data[position], - fw->size-position > 255 ? 255 : fw->size-position); - position += (fw->size-position > 255 ? 255 : fw->size-position); - } - buf[0] = crc >> 8; - buf[1] = crc & 0xFF; - - dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]); - - /* write crc */ - nxt200x_writebytes(state, 0x2C, buf,2); - - /* do a read to stop things */ - nxt200x_readbytes(state, 0x2C, buf, 1); - - /* set transfer mode to complete */ - buf[0] = 0x80; - nxt200x_writebytes(state, 0x2B, buf,1); - - return 0; -}; - -static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 buf[5]; - - /* stop the micro first */ - nxt200x_microcontroller_stop(state); - - if (state->demod_chip == NXT2004) { - /* make sure demod is set to digital */ - buf[0] = 0x04; - nxt200x_writebytes(state, 0x14, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x17, buf, 1); - } - - /* set additional params */ - switch (p->u.vsb.modulation) { - case QAM_64: - case QAM_256: - /* Set punctured clock for QAM */ - /* This is just a guess since I am unable to test it */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 1); - break; - case VSB_8: - /* Set non-punctured clock for VSB */ - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - break; - default: - return -EINVAL; - break; - } - - if (fe->ops.tuner_ops.calc_regs) { - /* get tuning information */ - fe->ops.tuner_ops.calc_regs(fe, p, buf, 5); - - /* write frequency information */ - nxt200x_writetuner(state, buf); - } - - /* reset the agc now that tuning has been completed */ - nxt200x_agc_reset(state); - - /* set target power level */ - switch (p->u.vsb.modulation) { - case QAM_64: - case QAM_256: - buf[0] = 0x74; - break; - case VSB_8: - buf[0] = 0x70; - break; - default: - return -EINVAL; - break; - } - nxt200x_writebytes(state, 0x42, buf, 1); - - /* configure sdm */ - switch (state->demod_chip) { - case NXT2002: - buf[0] = 0x87; - break; - case NXT2004: - buf[0] = 0x07; - break; - default: - return -EINVAL; - break; - } - nxt200x_writebytes(state, 0x57, buf, 1); - - /* write sdm1 input */ - buf[0] = 0x10; - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x58, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x58, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write sdmx input */ - switch (p->u.vsb.modulation) { - case QAM_64: - buf[0] = 0x68; - break; - case QAM_256: - buf[0] = 0x64; - break; - case VSB_8: - buf[0] = 0x60; - break; - default: - return -EINVAL; - break; - } - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x5C, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x5C, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write adc power lpf fc */ - buf[0] = 0x05; - nxt200x_writebytes(state, 0x43, buf, 1); - - if (state->demod_chip == NXT2004) { - /* write ??? */ - buf[0] = 0x00; - buf[1] = 0x00; - nxt200x_writebytes(state, 0x46, buf, 2); - } - - /* write accumulator2 input */ - buf[0] = 0x80; - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x4B, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x4B, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write kg1 */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0x4D, buf, 1); - - /* write sdm12 lpf fc */ - buf[0] = 0x44; - nxt200x_writebytes(state, 0x55, buf, 1); - - /* write agc control reg */ - buf[0] = 0x04; - nxt200x_writebytes(state, 0x41, buf, 1); - - if (state->demod_chip == NXT2004) { - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x24; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* soft reset? */ - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x10; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x04; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x81, buf, 1); - buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00; - nxt200x_writereg_multibyte(state, 0x82, buf, 3); - nxt200x_readreg_multibyte(state, 0x88, buf, 1); - buf[0] = 0x11; - nxt200x_writereg_multibyte(state, 0x88, buf, 1); - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x44; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - } - - /* write agc ucgp0 */ - switch (p->u.vsb.modulation) { - case QAM_64: - buf[0] = 0x02; - break; - case QAM_256: - buf[0] = 0x03; - break; - case VSB_8: - buf[0] = 0x00; - break; - default: - return -EINVAL; - break; - } - nxt200x_writebytes(state, 0x30, buf, 1); - - /* write agc control reg */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0x41, buf, 1); - - /* write accumulator2 input */ - buf[0] = 0x80; - buf[1] = 0x00; - switch (state->demod_chip) { - case NXT2002: - nxt200x_writereg_multibyte(state, 0x49, buf, 2); - nxt200x_writereg_multibyte(state, 0x4B, buf, 2); - break; - case NXT2004: - nxt200x_writebytes(state, 0x49, buf, 2); - nxt200x_writebytes(state, 0x4B, buf, 2); - break; - default: - return -EINVAL; - break; - } - - /* write agc control reg */ - buf[0] = 0x04; - nxt200x_writebytes(state, 0x41, buf, 1); - - nxt200x_microcontroller_start(state); - - if (state->demod_chip == NXT2004) { - nxt2004_microcontroller_init(state); - - /* ???? */ - buf[0] = 0xF0; - buf[1] = 0x00; - nxt200x_writebytes(state, 0x5C, buf, 2); - } - - /* adjacent channel detection should be done here, but I don't - have any stations with this need so I cannot test it */ - - return 0; -} - -static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 lock; - nxt200x_readbytes(state, 0x31, &lock, 1); - - *status = 0; - if (lock & 0x20) { - *status |= FE_HAS_SIGNAL; - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_LOCK; - } - return 0; -} - -static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[3]; - - nxt200x_readreg_multibyte(state, 0xE6, b, 3); - - *ber = ((b[0] << 8) + b[1]) * 8; - - return 0; -} - -static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[2]; - u16 temp = 0; - - /* setup to read cluster variance */ - b[0] = 0x00; - nxt200x_writebytes(state, 0xA1, b, 1); - - /* get multreg val */ - nxt200x_readreg_multibyte(state, 0xA6, b, 2); - - temp = (b[0] << 8) | b[1]; - *strength = ((0x7FFF - temp) & 0x0FFF) * 16; - - return 0; -} - -static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr) -{ - - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[2]; - u16 temp = 0, temp2; - u32 snrdb = 0; - - /* setup to read cluster variance */ - b[0] = 0x00; - nxt200x_writebytes(state, 0xA1, b, 1); - - /* get multreg val from 0xA6 */ - nxt200x_readreg_multibyte(state, 0xA6, b, 2); - - temp = (b[0] << 8) | b[1]; - temp2 = 0x7FFF - temp; - - /* snr will be in db */ - if (temp2 > 0x7F00) - snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) ); - else if (temp2 > 0x7EC0) - snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) ); - else if (temp2 > 0x7C00) - snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) ); - else - snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) ); - - /* the value reported back from the frontend will be FFFF=32db 0000=0db */ - *snr = snrdb * (0xFFFF/32000); - - return 0; -} - -static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct nxt200x_state* state = fe->demodulator_priv; - u8 b[3]; - - nxt200x_readreg_multibyte(state, 0xE6, b, 3); - *ucblocks = b[2]; - - return 0; -} - -static int nxt200x_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int nxt2002_init(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - const struct firmware *fw; - int ret; - u8 buf[2]; - - /* request the firmware, this will block until someone uploads it */ - printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev); - printk("nxt2002: Waiting for firmware upload(2)...\n"); - if (ret) { - printk("nxt2002: No firmware uploaded (timeout or file not found?)\n"); - return ret; - } - - ret = nxt2002_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk("nxt2002: Writing firmware to device failed\n"); - return ret; - } - printk("nxt2002: Firmware upload complete\n"); - - /* Put the micro into reset */ - nxt200x_microcontroller_stop(state); - - /* ensure transfer is complete */ - buf[0]=0x00; - nxt200x_writebytes(state, 0x2B, buf, 1); - - /* Put the micro into reset for real this time */ - nxt200x_microcontroller_stop(state); - - /* soft reset everything (agc,frontend,eq,fec)*/ - buf[0] = 0x0F; - nxt200x_writebytes(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x08, buf, 1); - - /* write agc sdm configure */ - buf[0] = 0xF1; - nxt200x_writebytes(state, 0x57, buf, 1); - - /* write mod output format */ - buf[0] = 0x20; - nxt200x_writebytes(state, 0x09, buf, 1); - - /* write fec mpeg mode */ - buf[0] = 0x7E; - buf[1] = 0x00; - nxt200x_writebytes(state, 0xE9, buf, 2); - - /* write mux selection */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0xCC, buf, 1); - - return 0; -} - -static int nxt2004_init(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - const struct firmware *fw; - int ret; - u8 buf[3]; - - /* ??? */ - buf[0]=0x00; - nxt200x_writebytes(state, 0x1E, buf, 1); - - /* request the firmware, this will block until someone uploads it */ - printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE); - ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev); - printk("nxt2004: Waiting for firmware upload(2)...\n"); - if (ret) { - printk("nxt2004: No firmware uploaded (timeout or file not found?)\n"); - return ret; - } - - ret = nxt2004_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk("nxt2004: Writing firmware to device failed\n"); - return ret; - } - printk("nxt2004: Firmware upload complete\n"); - - /* ensure transfer is complete */ - buf[0] = 0x01; - nxt200x_writebytes(state, 0x19, buf, 1); - - nxt2004_microcontroller_init(state); - nxt200x_microcontroller_stop(state); - nxt200x_microcontroller_stop(state); - nxt2004_microcontroller_init(state); - nxt200x_microcontroller_stop(state); - - /* soft reset everything (agc,frontend,eq,fec)*/ - buf[0] = 0xFF; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - /* write agc sdm configure */ - buf[0] = 0xD7; - nxt200x_writebytes(state, 0x57, buf, 1); - - /* ???*/ - buf[0] = 0x07; - buf[1] = 0xfe; - nxt200x_writebytes(state, 0x35, buf, 2); - buf[0] = 0x12; - nxt200x_writebytes(state, 0x34, buf, 1); - buf[0] = 0x80; - nxt200x_writebytes(state, 0x21, buf, 1); - - /* ???*/ - buf[0] = 0x21; - nxt200x_writebytes(state, 0x0A, buf, 1); - - /* ???*/ - buf[0] = 0x01; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* write fec mpeg mode */ - buf[0] = 0x7E; - buf[1] = 0x00; - nxt200x_writebytes(state, 0xE9, buf, 2); - - /* write mux selection */ - buf[0] = 0x00; - nxt200x_writebytes(state, 0xCC, buf, 1); - - /* ???*/ - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* soft reset? */ - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x10; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - /* ???*/ - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x01; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x70; - nxt200x_writereg_multibyte(state, 0x81, buf, 1); - buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66; - nxt200x_writereg_multibyte(state, 0x82, buf, 3); - - nxt200x_readreg_multibyte(state, 0x88, buf, 1); - buf[0] = 0x11; - nxt200x_writereg_multibyte(state, 0x88, buf, 1); - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x40; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - nxt200x_readbytes(state, 0x10, buf, 1); - buf[0] = 0x10; - nxt200x_writebytes(state, 0x10, buf, 1); - nxt200x_readbytes(state, 0x0A, buf, 1); - buf[0] = 0x21; - nxt200x_writebytes(state, 0x0A, buf, 1); - - nxt2004_microcontroller_init(state); - - buf[0] = 0x21; - nxt200x_writebytes(state, 0x0A, buf, 1); - buf[0] = 0x7E; - nxt200x_writebytes(state, 0xE9, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0xEA, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* soft reset? */ - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x10; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - nxt200x_readreg_multibyte(state, 0x08, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x08, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x04; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x00; - nxt200x_writereg_multibyte(state, 0x81, buf, 1); - buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00; - nxt200x_writereg_multibyte(state, 0x82, buf, 3); - - nxt200x_readreg_multibyte(state, 0x88, buf, 1); - buf[0] = 0x11; - nxt200x_writereg_multibyte(state, 0x88, buf, 1); - - nxt200x_readreg_multibyte(state, 0x80, buf, 1); - buf[0] = 0x44; - nxt200x_writereg_multibyte(state, 0x80, buf, 1); - - /* initialize tuner */ - nxt200x_readbytes(state, 0x10, buf, 1); - buf[0] = 0x12; - nxt200x_writebytes(state, 0x10, buf, 1); - buf[0] = 0x04; - nxt200x_writebytes(state, 0x13, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x16, buf, 1); - buf[0] = 0x04; - nxt200x_writebytes(state, 0x14, buf, 1); - buf[0] = 0x00; - nxt200x_writebytes(state, 0x14, buf, 1); - nxt200x_writebytes(state, 0x17, buf, 1); - nxt200x_writebytes(state, 0x14, buf, 1); - nxt200x_writebytes(state, 0x17, buf, 1); - - return 0; -} - -static int nxt200x_init(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - int ret = 0; - - if (!state->initialised) { - switch (state->demod_chip) { - case NXT2002: - ret = nxt2002_init(fe); - break; - case NXT2004: - ret = nxt2004_init(fe); - break; - default: - return -EINVAL; - break; - } - state->initialised = 1; - } - return ret; -} - -static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 500; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void nxt200x_release(struct dvb_frontend* fe) -{ - struct nxt200x_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops nxt200x_ops; - -struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c) -{ - struct nxt200x_state* state = NULL; - u8 buf [] = {0,0,0,0,0}; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - - /* read card id */ - nxt200x_readbytes(state, 0x00, buf, 5); - dprintk("NXT info: %02X %02X %02X %02X %02X\n", - buf[0], buf[1], buf[2], buf[3], buf[4]); - - /* set demod chip */ - switch (buf[0]) { - case 0x04: - state->demod_chip = NXT2002; - printk("nxt200x: NXT2002 Detected\n"); - break; - case 0x05: - state->demod_chip = NXT2004; - printk("nxt200x: NXT2004 Detected\n"); - break; - default: - goto error; - } - - /* make sure demod chip is supported */ - switch (state->demod_chip) { - case NXT2002: - if (buf[0] != 0x04) goto error; /* device id */ - if (buf[1] != 0x02) goto error; /* fab id */ - if (buf[2] != 0x11) goto error; /* month */ - if (buf[3] != 0x20) goto error; /* year msb */ - if (buf[4] != 0x00) goto error; /* year lsb */ - break; - case NXT2004: - if (buf[0] != 0x05) goto error; /* device id */ - break; - default: - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n", - buf[0], buf[1], buf[2], buf[3], buf[4]); - return NULL; -} - -static struct dvb_frontend_ops nxt200x_ops = { - - .info = { - .name = "Nextwave NXT200X VSB/QAM frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 860000000, - .frequency_stepsize = 166666, /* stepsize is just a guess */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256 - }, - - .release = nxt200x_release, - - .init = nxt200x_init, - .sleep = nxt200x_sleep, - - .set_frontend = nxt200x_setup_frontend_parameters, - .get_tune_settings = nxt200x_get_tune_settings, - - .read_status = nxt200x_read_status, - .read_ber = nxt200x_read_ber, - .read_signal_strength = nxt200x_read_signal_strength, - .read_snr = nxt200x_read_snr, - .read_ucblocks = nxt200x_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); -MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(nxt200x_attach); - diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h deleted file mode 100644 index f3c84583770..00000000000 --- a/drivers/media/dvb/frontends/nxt200x.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Support for NXT2002 and NXT2004 - VSB/QAM - * - * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com) - * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> - * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ - -#ifndef NXT200X_H -#define NXT200X_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -typedef enum nxt_chip_t { - NXTUNDEFINED, - NXT2002, - NXT2004 -}nxt_chip_type; - -struct nxt200x_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_NXT200X) || (defined(CONFIG_DVB_NXT200X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_NXT200X - -#endif /* NXT200X_H */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c deleted file mode 100644 index 0eef22dbf8a..00000000000 --- a/drivers/media/dvb/frontends/nxt6000.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - NxtWave Communications - NXT6000 demodulator driver - - Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org> - Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "nxt6000_priv.h" -#include "nxt6000.h" - - - -struct nxt6000_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct nxt6000_config* config; - struct dvb_frontend frontend; -}; - -static int debug; -#define dprintk if (debug) printk - -static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 }; - int ret; - - 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; -} - -static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msgs[] = { - {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; - - ret = i2c_transfer(state->i2c, msgs, 2); - - if (ret != 2) - dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret); - - return b1[0]; -} - -static void nxt6000_reset(struct nxt6000_state* state) -{ - u8 val; - - val = nxt6000_readreg(state, OFDM_COR_CTL); - - nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT); - nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT); -} - -static int nxt6000_set_bandwidth(struct nxt6000_state* state, fe_bandwidth_t bandwidth) -{ - u16 nominal_rate; - int result; - - switch (bandwidth) { - - case BANDWIDTH_6_MHZ: - nominal_rate = 0x55B7; - break; - - case BANDWIDTH_7_MHZ: - nominal_rate = 0x6400; - break; - - case BANDWIDTH_8_MHZ: - nominal_rate = 0x7249; - break; - - default: - return -EINVAL; - } - - if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0) - return result; - - return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF); -} - -static int nxt6000_set_guard_interval(struct nxt6000_state* state, fe_guard_interval_t guard_interval) -{ - switch (guard_interval) { - - case GUARD_INTERVAL_1_32: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - case GUARD_INTERVAL_1_16: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - case GUARD_INTERVAL_AUTO: - case GUARD_INTERVAL_1_8: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - case GUARD_INTERVAL_1_4: - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03)); - - default: - return -EINVAL; - } -} - -static int nxt6000_set_inversion(struct nxt6000_state* state, fe_spectral_inversion_t inversion) -{ - switch (inversion) { - - case INVERSION_OFF: - return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00); - - case INVERSION_ON: - return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV); - - default: - return -EINVAL; - - } -} - -static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmit_mode_t transmission_mode) -{ - int result; - - switch (transmission_mode) { - - case TRANSMISSION_MODE_2K: - if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0) - return result; - - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04)); - - case TRANSMISSION_MODE_8K: - case TRANSMISSION_MODE_AUTO: - if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0) - return result; - - return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04)); - - default: - return -EINVAL; - - } -} - -static void nxt6000_setup(struct dvb_frontend* fe) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM); - nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01); - nxt6000_writereg(state, VIT_BERTIME_2, 0x00); // BER Timer = 0x000200 * 256 = 131072 bits - nxt6000_writereg(state, VIT_BERTIME_1, 0x02); // - nxt6000_writereg(state, VIT_BERTIME_0, 0x00); // - nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts - nxt6000_writereg(state, VIT_COR_CTL, 0x82); // Enable BER measurement - nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 ); - nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F)); - nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02); - nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW); - nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06); - nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31); - nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04); - nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */ - nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2); - nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256); - nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49); - nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72); - nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5); - nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2); - nxt6000_writereg(state, DIAG_CONFIG, TB_SET); - - if (state->config->clock_inversion) - nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION); - else - nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0); - - nxt6000_writereg(state, TS_FORMAT, 0); -} - -static void nxt6000_dump_status(struct nxt6000_state *state) -{ - u8 val; - -/* - printk("RS_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, RS_COR_STAT)); - printk("VIT_SYNC_STATUS: 0x%02X\n", nxt6000_readreg(fe, VIT_SYNC_STATUS)); - printk("OFDM_COR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_COR_STAT)); - printk("OFDM_SYR_STAT: 0x%02X\n", nxt6000_readreg(fe, OFDM_SYR_STAT)); - printk("OFDM_TPS_RCVD_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_1)); - printk("OFDM_TPS_RCVD_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_2)); - printk("OFDM_TPS_RCVD_3: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_3)); - printk("OFDM_TPS_RCVD_4: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RCVD_4)); - printk("OFDM_TPS_RESERVED_1: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_1)); - printk("OFDM_TPS_RESERVED_2: 0x%02X\n", nxt6000_readreg(fe, OFDM_TPS_RESERVED_2)); -*/ - printk("NXT6000 status:"); - - val = nxt6000_readreg(state, RS_COR_STAT); - - printk(" DATA DESCR LOCK: %d,", val & 0x01); - printk(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01); - - val = nxt6000_readreg(state, VIT_SYNC_STATUS); - - printk(" VITERBI LOCK: %d,", (val >> 7) & 0x01); - - switch ((val >> 4) & 0x07) { - - case 0x00: - printk(" VITERBI CODERATE: 1/2,"); - break; - - case 0x01: - printk(" VITERBI CODERATE: 2/3,"); - break; - - case 0x02: - printk(" VITERBI CODERATE: 3/4,"); - break; - - case 0x03: - printk(" VITERBI CODERATE: 5/6,"); - break; - - case 0x04: - printk(" VITERBI CODERATE: 7/8,"); - break; - - default: - printk(" VITERBI CODERATE: Reserved,"); - - } - - val = nxt6000_readreg(state, OFDM_COR_STAT); - - printk(" CHCTrack: %d,", (val >> 7) & 0x01); - printk(" TPSLock: %d,", (val >> 6) & 0x01); - printk(" SYRLock: %d,", (val >> 5) & 0x01); - printk(" AGCLock: %d,", (val >> 4) & 0x01); - - switch (val & 0x0F) { - - case 0x00: - printk(" CoreState: IDLE,"); - break; - - case 0x02: - printk(" CoreState: WAIT_AGC,"); - break; - - case 0x03: - printk(" CoreState: WAIT_SYR,"); - break; - - case 0x04: - printk(" CoreState: WAIT_PPM,"); - break; - - case 0x01: - printk(" CoreState: WAIT_TRL,"); - break; - - case 0x05: - printk(" CoreState: WAIT_TPS,"); - break; - - case 0x06: - printk(" CoreState: MONITOR_TPS,"); - break; - - default: - printk(" CoreState: Reserved,"); - - } - - val = nxt6000_readreg(state, OFDM_SYR_STAT); - - printk(" SYRLock: %d,", (val >> 4) & 0x01); - printk(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K"); - - switch ((val >> 4) & 0x03) { - - case 0x00: - printk(" SYRGuard: 1/32,"); - break; - - case 0x01: - printk(" SYRGuard: 1/16,"); - break; - - case 0x02: - printk(" SYRGuard: 1/8,"); - break; - - case 0x03: - printk(" SYRGuard: 1/4,"); - break; - } - - val = nxt6000_readreg(state, OFDM_TPS_RCVD_3); - - switch ((val >> 4) & 0x07) { - - case 0x00: - printk(" TPSLP: 1/2,"); - break; - - case 0x01: - printk(" TPSLP: 2/3,"); - break; - - case 0x02: - printk(" TPSLP: 3/4,"); - break; - - case 0x03: - printk(" TPSLP: 5/6,"); - break; - - case 0x04: - printk(" TPSLP: 7/8,"); - break; - - default: - printk(" TPSLP: Reserved,"); - - } - - switch (val & 0x07) { - - case 0x00: - printk(" TPSHP: 1/2,"); - break; - - case 0x01: - printk(" TPSHP: 2/3,"); - break; - - case 0x02: - printk(" TPSHP: 3/4,"); - break; - - case 0x03: - printk(" TPSHP: 5/6,"); - break; - - case 0x04: - printk(" TPSHP: 7/8,"); - break; - - default: - printk(" TPSHP: Reserved,"); - - } - - val = nxt6000_readreg(state, OFDM_TPS_RCVD_4); - - printk(" TPSMode: %s,", val & 0x01 ? "8K" : "2K"); - - switch ((val >> 4) & 0x03) { - - case 0x00: - printk(" TPSGuard: 1/32,"); - break; - - case 0x01: - printk(" TPSGuard: 1/16,"); - break; - - case 0x02: - printk(" TPSGuard: 1/8,"); - break; - - case 0x03: - printk(" TPSGuard: 1/4,"); - break; - - } - - /* Strange magic required to gain access to RF_AGC_STATUS */ - nxt6000_readreg(state, RF_AGC_VAL_1); - val = nxt6000_readreg(state, RF_AGC_STATUS); - val = nxt6000_readreg(state, RF_AGC_STATUS); - - printk(" RF AGC LOCK: %d,", (val >> 4) & 0x01); - printk("\n"); -} - -static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - u8 core_status; - struct nxt6000_state* state = fe->demodulator_priv; - - *status = 0; - - core_status = nxt6000_readreg(state, OFDM_COR_STAT); - - if (core_status & AGCLOCKED) - *status |= FE_HAS_SIGNAL; - - if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK) - *status |= FE_HAS_CARRIER; - - if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC) - *status |= FE_HAS_VITERBI; - - if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS) - *status |= FE_HAS_SYNC; - - if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC))) - *status |= FE_HAS_LOCK; - - if (debug) - nxt6000_dump_status(state); - - return 0; -} - -static int nxt6000_init(struct dvb_frontend* fe) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - nxt6000_reset(state); - nxt6000_setup(fe); - - return 0; -} - -static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) -{ - struct nxt6000_state* state = fe->demodulator_priv; - int result; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - if ((result = nxt6000_set_bandwidth(state, param->u.ofdm.bandwidth)) < 0) - return result; - if ((result = nxt6000_set_guard_interval(state, param->u.ofdm.guard_interval)) < 0) - return result; - if ((result = nxt6000_set_transmission_mode(state, param->u.ofdm.transmission_mode)) < 0) - return result; - if ((result = nxt6000_set_inversion(state, param->inversion)) < 0) - return result; - - msleep(500); - return 0; -} - -static void nxt6000_release(struct dvb_frontend* fe) -{ - struct nxt6000_state* state = fe->demodulator_priv; - kfree(state); -} - -static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8; - - return 0; -} - -static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 ); - - *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) | - nxt6000_readreg( state, VIT_BER_0 ); - - nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts - - return 0; -} - -static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - *signal_strength = (short) (511 - - (nxt6000_readreg(state, AGC_GAIN_1) + - ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8))); - - return 0; -} - -static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 500; - return 0; -} - -static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct nxt6000_state* state = fe->demodulator_priv; - - if (enable) { - return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); - } else { - return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00); - } -} - -static struct dvb_frontend_ops nxt6000_ops; - -struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c) -{ - struct nxt6000_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops nxt6000_ops = { - - .info = { - .name = "NxtWave NXT6000 DVB-T", - .type = FE_OFDM, - .frequency_min = 0, - .frequency_max = 863250000, - .frequency_stepsize = 62500, - /*.frequency_tolerance = *//* FIXME: 12% of SR */ - .symbol_rate_min = 0, /* FIXME */ - .symbol_rate_max = 9360000, /* FIXME */ - .symbol_rate_tolerance = 4000, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = nxt6000_release, - - .init = nxt6000_init, - .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl, - - .get_tune_settings = nxt6000_fe_get_tune_settings, - - .set_frontend = nxt6000_set_frontend, - - .read_status = nxt6000_read_status, - .read_ber = nxt6000_read_ber, - .read_signal_strength = nxt6000_read_signal_strength, - .read_snr = nxt6000_read_snr, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver"); -MODULE_AUTHOR("Florian Schirmer"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(nxt6000_attach); diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h deleted file mode 100644 index 878eb38a075..00000000000 --- a/drivers/media/dvb/frontends/nxt6000.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - NxtWave Communications - NXT6000 demodulator driver - - Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org> - Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef NXT6000_H -#define NXT6000_H - -#include <linux/dvb/frontend.h> - -struct nxt6000_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* should clock inversion be used? */ - u8 clock_inversion:1; -}; - -#if defined(CONFIG_DVB_NXT6000) || (defined(CONFIG_DVB_NXT6000_MODULE) && defined(MODULE)) -extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_NXT6000 - -#endif // NXT6000_H diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h deleted file mode 100644 index 0422e580038..00000000000 --- a/drivers/media/dvb/frontends/nxt6000_priv.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Public Include File for DRV6000 users - * (ie. NxtWave Communications - NXT6000 demodulator driver) - * - * Copyright (C) 2001 NxtWave Communications, Inc. - * - */ - -/* Nxt6000 Register Addresses and Bit Masks */ - -/* Maximum Register Number */ -#define MAXNXT6000REG (0x9A) - -/* 0x1B A_VIT_BER_0 aka 0x3A */ -#define A_VIT_BER_0 (0x1B) - -/* 0x1D A_VIT_BER_TIMER_0 aka 0x38 */ -#define A_VIT_BER_TIMER_0 (0x1D) - -/* 0x21 RS_COR_STAT */ -#define RS_COR_STAT (0x21) -#define RSCORESTATUS (0x03) - -/* 0x22 RS_COR_INTEN */ -#define RS_COR_INTEN (0x22) - -/* 0x23 RS_COR_INSTAT */ -#define RS_COR_INSTAT (0x23) -#define INSTAT_ERROR (0x04) -#define LOCK_LOSS_BITS (0x03) - -/* 0x24 RS_COR_SYNC_PARAM */ -#define RS_COR_SYNC_PARAM (0x24) -#define SYNC_PARAM (0x03) - -/* 0x25 BER_CTRL */ -#define BER_CTRL (0x25) -#define BER_ENABLE (0x02) -#define BER_RESET (0x01) - -/* 0x26 BER_PAY */ -#define BER_PAY (0x26) - -/* 0x27 BER_PKT_L */ -#define BER_PKT_L (0x27) -#define BER_PKTOVERFLOW (0x80) - -/* 0x30 VIT_COR_CTL */ -#define VIT_COR_CTL (0x30) -#define BER_CONTROL (0x02) -#define VIT_COR_MASK (0x82) -#define VIT_COR_RESYNC (0x80) - - -/* 0x32 VIT_SYNC_STATUS */ -#define VIT_SYNC_STATUS (0x32) -#define VITINSYNC (0x80) - -/* 0x33 VIT_COR_INTEN */ -#define VIT_COR_INTEN (0x33) -#define GLOBAL_ENABLE (0x80) - -/* 0x34 VIT_COR_INTSTAT */ -#define VIT_COR_INTSTAT (0x34) -#define BER_DONE (0x08) -#define BER_OVERFLOW (0x10) - -/* 0x38 VIT_BERTIME_2 */ -#define VIT_BERTIME_2 (0x38) - -/* 0x39 VIT_BERTIME_1 */ -#define VIT_BERTIME_1 (0x39) - -/* 0x3A VIT_BERTIME_0 */ -#define VIT_BERTIME_0 (0x3a) - - /* 0x38 OFDM_BERTimer *//* Use the alias registers */ -#define A_VIT_BER_TIMER_0 (0x1D) - - /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */ -#define A_VIT_BER_0 (0x1B) - -/* 0x3B VIT_BER_1 */ -#define VIT_BER_1 (0x3b) - -/* 0x3C VIT_BER_0 */ -#define VIT_BER_0 (0x3c) - -/* 0x40 OFDM_COR_CTL */ -#define OFDM_COR_CTL (0x40) -#define COREACT (0x20) -#define HOLDSM (0x10) -#define WAIT_AGC (0x02) -#define WAIT_SYR (0x03) - -/* 0x41 OFDM_COR_STAT */ -#define OFDM_COR_STAT (0x41) -#define COR_STATUS (0x0F) -#define MONITOR_TPS (0x06) -#define TPSLOCKED (0x40) -#define AGCLOCKED (0x10) - -/* 0x42 OFDM_COR_INTEN */ -#define OFDM_COR_INTEN (0x42) -#define TPSRCVBAD (0x04) -#define TPSRCVCHANGED (0x02) -#define TPSRCVUPDATE (0x01) - -/* 0x43 OFDM_COR_INSTAT */ -#define OFDM_COR_INSTAT (0x43) - -/* 0x44 OFDM_COR_MODEGUARD */ -#define OFDM_COR_MODEGUARD (0x44) -#define FORCEMODE (0x08) -#define FORCEMODE8K (0x04) - -/* 0x45 OFDM_AGC_CTL */ -#define OFDM_AGC_CTL (0x45) -#define INITIAL_AGC_BW (0x08) -#define AGCNEG (0x02) -#define AGCLAST (0x10) - -/* 0x48 OFDM_AGC_TARGET */ -#define OFDM_AGC_TARGET (0x48) -#define OFDM_AGC_TARGET_DEFAULT (0x28) -#define OFDM_AGC_TARGET_IMPULSE (0x38) - -/* 0x49 OFDM_AGC_GAIN_1 */ -#define OFDM_AGC_GAIN_1 (0x49) - -/* 0x4B OFDM_ITB_CTL */ -#define OFDM_ITB_CTL (0x4B) -#define ITBINV (0x01) - -/* 0x49 AGC_GAIN_1 */ -#define AGC_GAIN_1 (0x49) - -/* 0x4A AGC_GAIN_2 */ -#define AGC_GAIN_2 (0x4A) - -/* 0x4C OFDM_ITB_FREQ_1 */ -#define OFDM_ITB_FREQ_1 (0x4C) - -/* 0x4D OFDM_ITB_FREQ_2 */ -#define OFDM_ITB_FREQ_2 (0x4D) - -/* 0x4E OFDM_CAS_CTL */ -#define OFDM_CAS_CTL (0x4E) -#define ACSDIS (0x40) -#define CCSEN (0x80) - -/* 0x4F CAS_FREQ */ -#define CAS_FREQ (0x4F) - -/* 0x51 OFDM_SYR_CTL */ -#define OFDM_SYR_CTL (0x51) -#define SIXTH_ENABLE (0x80) -#define SYR_TRACKING_DISABLE (0x01) - -/* 0x52 OFDM_SYR_STAT */ -#define OFDM_SYR_STAT (0x52) -#define GI14_2K_SYR_LOCK (0x13) -#define GI14_8K_SYR_LOCK (0x17) -#define GI14_SYR_LOCK (0x10) - -/* 0x55 OFDM_SYR_OFFSET_1 */ -#define OFDM_SYR_OFFSET_1 (0x55) - -/* 0x56 OFDM_SYR_OFFSET_2 */ -#define OFDM_SYR_OFFSET_2 (0x56) - -/* 0x58 OFDM_SCR_CTL */ -#define OFDM_SCR_CTL (0x58) -#define SYR_ADJ_DECAY_MASK (0x70) -#define SYR_ADJ_DECAY (0x30) - -/* 0x59 OFDM_PPM_CTL_1 */ -#define OFDM_PPM_CTL_1 (0x59) -#define PPMMAX_MASK (0x30) -#define PPM256 (0x30) - -/* 0x5B OFDM_TRL_NOMINALRATE_1 */ -#define OFDM_TRL_NOMINALRATE_1 (0x5B) - -/* 0x5C OFDM_TRL_NOMINALRATE_2 */ -#define OFDM_TRL_NOMINALRATE_2 (0x5C) - -/* 0x5D OFDM_TRL_TIME_1 */ -#define OFDM_TRL_TIME_1 (0x5D) - -/* 0x60 OFDM_CRL_FREQ_1 */ -#define OFDM_CRL_FREQ_1 (0x60) - -/* 0x63 OFDM_CHC_CTL_1 */ -#define OFDM_CHC_CTL_1 (0x63) -#define MANMEAN1 (0xF0); -#define CHCFIR (0x01) - -/* 0x64 OFDM_CHC_SNR */ -#define OFDM_CHC_SNR (0x64) - -/* 0x65 OFDM_BDI_CTL */ -#define OFDM_BDI_CTL (0x65) -#define LP_SELECT (0x02) - -/* 0x67 OFDM_TPS_RCVD_1 */ -#define OFDM_TPS_RCVD_1 (0x67) -#define TPSFRAME (0x03) - -/* 0x68 OFDM_TPS_RCVD_2 */ -#define OFDM_TPS_RCVD_2 (0x68) - -/* 0x69 OFDM_TPS_RCVD_3 */ -#define OFDM_TPS_RCVD_3 (0x69) - -/* 0x6A OFDM_TPS_RCVD_4 */ -#define OFDM_TPS_RCVD_4 (0x6A) - -/* 0x6B OFDM_TPS_RESERVED_1 */ -#define OFDM_TPS_RESERVED_1 (0x6B) - -/* 0x6C OFDM_TPS_RESERVED_2 */ -#define OFDM_TPS_RESERVED_2 (0x6C) - -/* 0x73 OFDM_MSC_REV */ -#define OFDM_MSC_REV (0x73) - -/* 0x76 OFDM_SNR_CARRIER_2 */ -#define OFDM_SNR_CARRIER_2 (0x76) -#define MEAN_MASK (0x80) -#define MEANBIT (0x80) - -/* 0x80 ANALOG_CONTROL_0 */ -#define ANALOG_CONTROL_0 (0x80) -#define POWER_DOWN_ADC (0x40) - -/* 0x81 ENABLE_TUNER_IIC */ -#define ENABLE_TUNER_IIC (0x81) -#define ENABLE_TUNER_BIT (0x01) - -/* 0x82 EN_DMD_RACQ */ -#define EN_DMD_RACQ (0x82) -#define EN_DMD_RACQ_REG_VAL (0x81) -#define EN_DMD_RACQ_REG_VAL_14 (0x01) - -/* 0x84 SNR_COMMAND */ -#define SNR_COMMAND (0x84) -#define SNRStat (0x80) - -/* 0x85 SNRCARRIERNUMBER_LSB */ -#define SNRCARRIERNUMBER_LSB (0x85) - -/* 0x87 SNRMINTHRESHOLD_LSB */ -#define SNRMINTHRESHOLD_LSB (0x87) - -/* 0x89 SNR_PER_CARRIER_LSB */ -#define SNR_PER_CARRIER_LSB (0x89) - -/* 0x8B SNRBELOWTHRESHOLD_LSB */ -#define SNRBELOWTHRESHOLD_LSB (0x8B) - -/* 0x91 RF_AGC_VAL_1 */ -#define RF_AGC_VAL_1 (0x91) - -/* 0x92 RF_AGC_STATUS */ -#define RF_AGC_STATUS (0x92) - -/* 0x98 DIAG_CONFIG */ -#define DIAG_CONFIG (0x98) -#define DIAG_MASK (0x70) -#define TB_SET (0x10) -#define TRAN_SELECT (0x07) -#define SERIAL_SELECT (0x01) - -/* 0x99 SUB_DIAG_MODE_SEL */ -#define SUB_DIAG_MODE_SEL (0x99) -#define CLKINVERSION (0x01) - -/* 0x9A TS_FORMAT */ -#define TS_FORMAT (0x9A) -#define ERROR_SENSE (0x08) -#define VALID_SENSE (0x04) -#define SYNC_SENSE (0x02) -#define GATED_CLOCK (0x01) - -#define NXT6000ASICDEVICE (0x0b) diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c deleted file mode 100644 index 5ed32544de3..00000000000 --- a/drivers/media/dvb/frontends/or51132.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM - * - * - * Copyright (C) 2007 Trent Piepho <xyzzy@speakeasy.org> - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * Based on code from Jack Kelliher (kelliher@xmission.com) - * Copyright (C) 2002 & pcHDTV, inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ - -/* - * This driver needs two external firmware files. Please copy - * "dvb-fe-or51132-vsb.fw" and "dvb-fe-or51132-qam.fw" to - * /usr/lib/hotplug/firmware/ or /lib/firmware/ - * (depending on configuration of firmware hotplug). - */ -#define OR51132_VSB_FIRMWARE "dvb-fe-or51132-vsb.fw" -#define OR51132_QAM_FIRMWARE "dvb-fe-or51132-qam.fw" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.h> - -#include "dvb_math.h" -#include "dvb_frontend.h" -#include "or51132.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "or51132: " args); \ - } while (0) - - -struct or51132_state -{ - struct i2c_adapter* i2c; - - /* Configuration settings */ - const struct or51132_config* config; - - struct dvb_frontend frontend; - - /* Demodulator private data */ - fe_modulation_t current_modulation; - u32 snr; /* Result of last SNR calculation */ - - /* Tuner private data */ - u32 current_frequency; -}; - - -/* Write buffer to demod */ -static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len) -{ - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = (u8*)buf, .len = len }; - - /* msleep(20); */ /* doesn't appear to be necessary */ - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51132: I2C write (addr 0x%02x len %d) error: %d\n", - msg.addr, msg.len, err); - return -EREMOTEIO; - } - return 0; -} - -/* Write constant bytes, e.g. or51132_writebytes(state, 0x04, 0x42, 0x00); - Less code and more efficient that loading a buffer on the stack with - the bytes to send and then calling or51132_writebuf() on that. */ -#define or51132_writebytes(state, data...) \ - ({ static const u8 _data[] = {data}; \ - or51132_writebuf(state, _data, sizeof(_data)); }) - -/* Read data from demod into buffer. Returns 0 on success. */ -static int or51132_readbuf(struct or51132_state *state, u8 *buf, int len) -{ - int err; - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = I2C_M_RD, .buf = buf, .len = len }; - - /* msleep(20); */ /* doesn't appear to be necessary */ - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51132: I2C read (addr 0x%02x len %d) error: %d\n", - msg.addr, msg.len, err); - return -EREMOTEIO; - } - return 0; -} - -/* Reads a 16-bit demod register. Returns <0 on error. */ -static int or51132_readreg(struct or51132_state *state, u8 reg) -{ - u8 buf[2] = { 0x04, reg }; - struct i2c_msg msg[2] = { - {.addr = state->config->demod_address, .flags = 0, - .buf = buf, .len = 2 }, - {.addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = buf, .len = 2 }}; - int err; - - if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) { - printk(KERN_WARNING "or51132: I2C error reading register %d: %d\n", - reg, err); - return -EREMOTEIO; - } - return buf[0] | (buf[1] << 8); -} - -static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) -{ - struct or51132_state* state = fe->demodulator_priv; - static const u8 run_buf[] = {0x7F,0x01}; - u8 rec_buf[8]; - u32 firmwareAsize, firmwareBsize; - int i,ret; - - dprintk("Firmware is %Zd bytes\n",fw->size); - - /* Get size of firmware A and B */ - firmwareAsize = le32_to_cpu(*((__le32*)fw->data)); - dprintk("FirmwareA is %i bytes\n",firmwareAsize); - firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4))); - dprintk("FirmwareB is %i bytes\n",firmwareBsize); - - /* Upload firmware */ - if ((ret = or51132_writebuf(state, &fw->data[8], firmwareAsize))) { - printk(KERN_WARNING "or51132: load_firmware error 1\n"); - return ret; - } - if ((ret = or51132_writebuf(state, &fw->data[8+firmwareAsize], - firmwareBsize))) { - printk(KERN_WARNING "or51132: load_firmware error 2\n"); - return ret; - } - - if ((ret = or51132_writebuf(state, run_buf, 2))) { - printk(KERN_WARNING "or51132: load_firmware error 3\n"); - return ret; - } - if ((ret = or51132_writebuf(state, run_buf, 2))) { - printk(KERN_WARNING "or51132: load_firmware error 4\n"); - return ret; - } - - /* 50ms for operation to begin */ - msleep(50); - - /* Read back ucode version to besure we loaded correctly and are really up and running */ - /* Get uCode version */ - if ((ret = or51132_writebytes(state, 0x10, 0x10, 0x00))) { - printk(KERN_WARNING "or51132: load_firmware error a\n"); - return ret; - } - if ((ret = or51132_writebytes(state, 0x04, 0x17))) { - printk(KERN_WARNING "or51132: load_firmware error b\n"); - return ret; - } - if ((ret = or51132_writebytes(state, 0x00, 0x00))) { - printk(KERN_WARNING "or51132: load_firmware error c\n"); - return ret; - } - for (i=0;i<4;i++) { - /* Once upon a time, this command might have had something - to do with getting the firmware version, but it's - not used anymore: - {0x04,0x00,0x30,0x00,i+1} */ - /* Read 8 bytes, two bytes at a time */ - if ((ret = or51132_readbuf(state, &rec_buf[i*2], 2))) { - printk(KERN_WARNING - "or51132: load_firmware error d - %d\n",i); - return ret; - } - } - - printk(KERN_WARNING - "or51132: Version: %02X%02X%02X%02X-%02X%02X%02X%02X (%02X%01X-%01X-%02X%01X-%01X)\n", - rec_buf[1],rec_buf[0],rec_buf[3],rec_buf[2], - rec_buf[5],rec_buf[4],rec_buf[7],rec_buf[6], - rec_buf[3],rec_buf[2]>>4,rec_buf[2]&0x0f, - rec_buf[5],rec_buf[4]>>4,rec_buf[4]&0x0f); - - if ((ret = or51132_writebytes(state, 0x10, 0x00, 0x00))) { - printk(KERN_WARNING "or51132: load_firmware error e\n"); - return ret; - } - return 0; -}; - -static int or51132_init(struct dvb_frontend* fe) -{ - return 0; -} - -static int or51132_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = 0; - return 0; -} - -static int or51132_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = 0; - return 0; -} - -static int or51132_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int or51132_setmode(struct dvb_frontend* fe) -{ - struct or51132_state* state = fe->demodulator_priv; - u8 cmd_buf1[3] = {0x04, 0x01, 0x5f}; - u8 cmd_buf2[3] = {0x1c, 0x00, 0 }; - - dprintk("setmode %d\n",(int)state->current_modulation); - - switch (state->current_modulation) { - case VSB_8: - /* Auto CH, Auto NTSC rej, MPEGser, MPEG2tr, phase noise-high */ - cmd_buf1[2] = 0x50; - /* REC MODE inv IF spectrum, Normal */ - cmd_buf2[1] = 0x03; - /* Channel MODE ATSC/VSB8 */ - cmd_buf2[2] = 0x06; - break; - /* All QAM modes are: - Auto-deinterleave; MPEGser, MPEG2tr, phase noise-high - REC MODE Normal Carrier Lock */ - case QAM_AUTO: - /* Channel MODE Auto QAM64/256 */ - cmd_buf2[2] = 0x4f; - break; - case QAM_256: - /* Channel MODE QAM256 */ - cmd_buf2[2] = 0x45; - break; - case QAM_64: - /* Channel MODE QAM64 */ - cmd_buf2[2] = 0x43; - break; - default: - printk(KERN_WARNING - "or51132: setmode: Modulation set to unsupported value (%d)\n", - state->current_modulation); - return -EINVAL; - } - - /* Set Receiver 1 register */ - if (or51132_writebuf(state, cmd_buf1, 3)) { - printk(KERN_WARNING "or51132: set_mode error 1\n"); - return -EREMOTEIO; - } - dprintk("set #1 to %02x\n", cmd_buf1[2]); - - /* Set operation mode in Receiver 6 register */ - if (or51132_writebuf(state, cmd_buf2, 3)) { - printk(KERN_WARNING "or51132: set_mode error 2\n"); - return -EREMOTEIO; - } - dprintk("set #6 to 0x%02x%02x\n", cmd_buf2[1], cmd_buf2[2]); - - return 0; -} - -/* Some modulations use the same firmware. This classifies modulations - by the firmware they use. */ -#define MOD_FWCLASS_UNKNOWN 0 -#define MOD_FWCLASS_VSB 1 -#define MOD_FWCLASS_QAM 2 -static int modulation_fw_class(fe_modulation_t modulation) -{ - switch(modulation) { - case VSB_8: - return MOD_FWCLASS_VSB; - case QAM_AUTO: - case QAM_64: - case QAM_256: - return MOD_FWCLASS_QAM; - default: - return MOD_FWCLASS_UNKNOWN; - } -} - -static int or51132_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - int ret; - struct or51132_state* state = fe->demodulator_priv; - const struct firmware *fw; - const char *fwname; - int clock_mode; - - /* Upload new firmware only if we need a different one */ - if (modulation_fw_class(state->current_modulation) != - modulation_fw_class(param->u.vsb.modulation)) { - switch(modulation_fw_class(param->u.vsb.modulation)) { - case MOD_FWCLASS_VSB: - dprintk("set_parameters VSB MODE\n"); - fwname = OR51132_VSB_FIRMWARE; - - /* Set non-punctured clock for VSB */ - clock_mode = 0; - break; - case MOD_FWCLASS_QAM: - dprintk("set_parameters QAM MODE\n"); - fwname = OR51132_QAM_FIRMWARE; - - /* Set punctured clock for QAM */ - clock_mode = 1; - break; - default: - printk("or51132: Modulation type(%d) UNSUPPORTED\n", - param->u.vsb.modulation); - return -1; - } - printk("or51132: Waiting for firmware upload(%s)...\n", - fwname); - ret = request_firmware(&fw, fwname, &state->i2c->dev); - if (ret) { - printk(KERN_WARNING "or51132: No firmware up" - "loaded(timeout or file not found?)\n"); - return ret; - } - ret = or51132_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk(KERN_WARNING "or51132: Writing firmware to " - "device failed!\n"); - return ret; - } - printk("or51132: Firmware upload complete.\n"); - state->config->set_ts_params(fe, clock_mode); - } - /* Change only if we are actually changing the modulation */ - if (state->current_modulation != param->u.vsb.modulation) { - state->current_modulation = param->u.vsb.modulation; - or51132_setmode(fe); - } - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Set to current mode */ - or51132_setmode(fe); - - /* Update current frequency */ - state->current_frequency = param->frequency; - return 0; -} - -static int or51132_get_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct or51132_state* state = fe->demodulator_priv; - int status; - int retry = 1; - -start: - /* Receiver Status */ - if ((status = or51132_readreg(state, 0x00)) < 0) { - printk(KERN_WARNING "or51132: get_parameters: error reading receiver status\n"); - return -EREMOTEIO; - } - switch(status&0xff) { - case 0x06: param->u.vsb.modulation = VSB_8; break; - case 0x43: param->u.vsb.modulation = QAM_64; break; - case 0x45: param->u.vsb.modulation = QAM_256; break; - default: - if (retry--) goto start; - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", - status&0xff); - return -EREMOTEIO; - } - - /* FIXME: Read frequency from frontend, take AFC into account */ - param->frequency = state->current_frequency; - - /* FIXME: How to read inversion setting? Receiver 6 register? */ - param->inversion = INVERSION_AUTO; - - return 0; -} - -static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct or51132_state* state = fe->demodulator_priv; - int reg; - - /* Receiver Status */ - if ((reg = or51132_readreg(state, 0x00)) < 0) { - printk(KERN_WARNING "or51132: read_status: error reading receiver status: %d\n", reg); - *status = 0; - return -EREMOTEIO; - } - dprintk("%s: read_status %04x\n", __func__, reg); - - if (reg & 0x0100) /* Receiver Lock */ - *status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI| - FE_HAS_SYNC|FE_HAS_LOCK; - else - *status = 0; - return 0; -} - -/* Calculate SNR estimation (scaled by 2^24) - - 8-VSB SNR and QAM equations from Oren datasheets - - For 8-VSB: - SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - K - - Where K = 0 if NTSC rejection filter is OFF; and - K = 3 if NTSC rejection filter is ON - - For QAM64: - SNR[dB] = 10 * log10(897152044.8282 / MSE^2 ) - - For QAM256: - SNR[dB] = 10 * log10(907832426.314266 / MSE^2 ) - - We re-write the snr equation as: - SNR * 2^24 = 10*(c - 2*intlog10(MSE)) - Where for QAM256, c = log10(907832426.314266) * 2^24 - and for 8-VSB and QAM64, c = log10(897152044.8282) * 2^24 */ - -static u32 calculate_snr(u32 mse, u32 c) -{ - if (mse == 0) /* No signal */ - return 0; - - mse = 2*intlog10(mse); - if (mse > c) { - /* Negative SNR, which is possible, but realisticly the - demod will lose lock before the signal gets this bad. The - API only allows for unsigned values, so just return 0 */ - return 0; - } - return 10*(c - mse); -} - -static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct or51132_state* state = fe->demodulator_priv; - int noise, reg; - u32 c, usK = 0; - int retry = 1; - -start: - /* SNR after Equalizer */ - noise = or51132_readreg(state, 0x02); - if (noise < 0) { - printk(KERN_WARNING "or51132: read_snr: error reading equalizer\n"); - return -EREMOTEIO; - } - dprintk("read_snr noise (%d)\n", noise); - - /* Read status, contains modulation type for QAM_AUTO and - NTSC filter for VSB */ - reg = or51132_readreg(state, 0x00); - if (reg < 0) { - printk(KERN_WARNING "or51132: read_snr: error reading receiver status\n"); - return -EREMOTEIO; - } - - switch (reg&0xff) { - case 0x06: - if (reg & 0x1000) usK = 3 << 24; - /* Fall through to QAM64 case */ - case 0x43: - c = 150204167; - break; - case 0x45: - c = 150290396; - break; - default: - printk(KERN_WARNING "or51132: unknown status 0x%02x\n", reg&0xff); - if (retry--) goto start; - return -EREMOTEIO; - } - dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__, - reg&0xff, reg&0x1000?"n":"ff"); - - /* Calculate SNR using noise, c, and NTSC rejection correction */ - state->snr = calculate_snr(noise, c) - usK; - *snr = (state->snr) >> 16; - - dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise, - state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* Calculate Strength from SNR up to 35dB */ - /* Even though the SNR can go higher than 35dB, there is some comfort */ - /* factor in having a range of strong signals that can show at 100% */ - struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; - u16 snr; - int ret; - - ret = fe->ops.read_snr(fe, &snr); - if (ret != 0) - return ret; - /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ - /* scale the range 0 - 35*2^24 into 0 - 65535 */ - if (state->snr >= 8960 * 0x10000) - *strength = 0xffff; - else - *strength = state->snr / 8960; - - return 0; -} - -static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 500; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static void or51132_release(struct dvb_frontend* fe) -{ - struct or51132_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops or51132_ops; - -struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c) -{ - struct or51132_state* state = NULL; - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - state->current_frequency = -1; - state->current_modulation = -1; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &or51132_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops or51132_ops = { - - .info = { - .name = "Oren OR51132 VSB/QAM Frontend", - .type = FE_ATSC, - .frequency_min = 44000000, - .frequency_max = 958000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | - FE_CAN_8VSB - }, - - .release = or51132_release, - - .init = or51132_init, - .sleep = or51132_sleep, - - .set_frontend = or51132_set_parameters, - .get_frontend = or51132_get_parameters, - .get_tune_settings = or51132_get_tune_settings, - - .read_status = or51132_read_status, - .read_ber = or51132_read_ber, - .read_signal_strength = or51132_read_signal_strength, - .read_snr = or51132_read_snr, - .read_ucblocks = or51132_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("OR51132 ATSC [pcHDTV HD-3000] (8VSB & ITU J83 AnnexB FEC QAM64/256) Demodulator Driver"); -MODULE_AUTHOR("Kirk Lapray"); -MODULE_AUTHOR("Trent Piepho"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(or51132_attach); - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h deleted file mode 100644 index 1b8e04d973c..00000000000 --- a/drivers/media/dvb/frontends/or51132.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Support for OR51132 (pcHDTV HD-3000) - VSB/QAM - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ - -#ifndef OR51132_H -#define OR51132_H - -#include <linux/firmware.h> -#include <linux/dvb/frontend.h> - -struct or51132_config -{ - /* The demodulator's i2c address */ - u8 demod_address; - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_OR51132) || (defined(CONFIG_DVB_OR51132_MODULE) && defined(MODULE)) -extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_OR51132 - -#endif // OR51132_H - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c deleted file mode 100644 index 16cf2fdd5d7..00000000000 --- a/drivers/media/dvb/frontends/or51211.c +++ /dev/null @@ -1,582 +0,0 @@ -/* - * Support for OR51211 (pcHDTV HD-2000) - VSB - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * Based on code from Jack Kelliher (kelliher@xmission.com) - * Copyright (C) 2002 & pcHDTV, inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ - -/* - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/byteorder.h> - -#include "dvb_math.h" -#include "dvb_frontend.h" -#include "or51211.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "or51211: " args); \ - } while (0) - -static u8 run_buf[] = {0x7f,0x01}; -static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC - -struct or51211_state { - - struct i2c_adapter* i2c; - - /* Configuration settings */ - const struct or51211_config* config; - - struct dvb_frontend frontend; - struct bt878* bt; - - /* Demodulator private data */ - u8 initialized:1; - u32 snr; /* Result of last SNR claculation */ - - /* Tuner private data */ - u32 current_frequency; -}; - -static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf, - int len) -{ - int err; - struct i2c_msg msg; - msg.addr = reg; - msg.flags = 0; - msg.len = len; - msg.buf = (u8 *)buf; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51211: i2c_writebytes error " - "(addr %02x, err == %i)\n", reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len) -{ - int err; - struct i2c_msg msg; - msg.addr = reg; - msg.flags = I2C_M_RD; - msg.len = len; - msg.buf = buf; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk(KERN_WARNING "or51211: i2c_readbytes error " - "(addr %02x, err == %i)\n", reg, err); - return -EREMOTEIO; - } - - return 0; -} - -static int or51211_load_firmware (struct dvb_frontend* fe, - const struct firmware *fw) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 tudata[585]; - int i; - - dprintk("Firmware is %zd bytes\n",fw->size); - - /* Get eprom data */ - tudata[0] = 17; - if (i2c_writebytes(state,0x50,tudata,1)) { - printk(KERN_WARNING "or51211:load_firmware error eprom addr\n"); - return -1; - } - if (i2c_readbytes(state,0x50,&tudata[145],192)) { - printk(KERN_WARNING "or51211: load_firmware error eprom\n"); - return -1; - } - - /* Create firmware buffer */ - for (i = 0; i < 145; i++) - tudata[i] = fw->data[i]; - - for (i = 0; i < 248; i++) - tudata[i+337] = fw->data[145+i]; - - state->config->reset(fe); - - if (i2c_writebytes(state,state->config->demod_address,tudata,585)) { - printk(KERN_WARNING "or51211: load_firmware error 1\n"); - return -1; - } - msleep(1); - - if (i2c_writebytes(state,state->config->demod_address, - &fw->data[393],8125)) { - printk(KERN_WARNING "or51211: load_firmware error 2\n"); - return -1; - } - msleep(1); - - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: load_firmware error 3\n"); - return -1; - } - - /* Wait at least 5 msec */ - msleep(10); - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: load_firmware error 4\n"); - return -1; - } - msleep(10); - - printk("or51211: Done.\n"); - return 0; -}; - -static int or51211_setmode(struct dvb_frontend* fe, int mode) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 rec_buf[14]; - - state->config->setmode(fe, mode); - - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: setmode error 1\n"); - return -1; - } - - /* Wait at least 5 msec */ - msleep(10); - if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) { - printk(KERN_WARNING "or51211: setmode error 2\n"); - return -1; - } - - msleep(10); - - /* Set operation mode in Receiver 1 register; - * type 1: - * data 0x50h Automatic sets receiver channel conditions - * Automatic NTSC rejection filter - * Enable MPEG serial data output - * MPEG2tr - * High tuner phase noise - * normal +/-150kHz Carrier acquisition range - */ - if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) { - printk(KERN_WARNING "or51211: setmode error 3\n"); - return -1; - } - - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x03; - rec_buf[3] = 0x00; - msleep(20); - if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) { - printk(KERN_WARNING "or51211: setmode error 5\n"); - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) { - printk(KERN_WARNING "or51211: setmode error 6"); - return -1; - } - dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]); - - return 0; -} - -static int or51211_set_parameters(struct dvb_frontend* fe, - struct dvb_frontend_parameters *param) -{ - struct or51211_state* state = fe->demodulator_priv; - - /* Change only if we are actually changing the channel */ - if (state->current_frequency != param->frequency) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Set to ATSC mode */ - or51211_setmode(fe,0); - - /* Update current frequency */ - state->current_frequency = param->frequency; - } - return 0; -} - -static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct or51211_state* state = fe->demodulator_priv; - unsigned char rec_buf[2]; - unsigned char snd_buf[] = {0x04,0x00,0x03,0x00}; - *status = 0; - - /* Receiver Status */ - if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { - printk(KERN_WARNING "or51132: read_status write error\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "or51132: read_status read error\n"); - return -1; - } - dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]); - - if (rec_buf[0] & 0x01) { /* Receiver Lock */ - *status |= FE_HAS_SIGNAL; - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_LOCK; - } - return 0; -} - -/* Calculate SNR estimation (scaled by 2^24) - - 8-VSB SNR equation from Oren datasheets - - For 8-VSB: - SNR[dB] = 10 * log10(219037.9454 / MSE^2 ) - - We re-write the snr equation as: - SNR * 2^24 = 10*(c - 2*intlog10(MSE)) - Where for 8-VSB, c = log10(219037.9454) * 2^24 */ - -static u32 calculate_snr(u32 mse, u32 c) -{ - if (mse == 0) /* No signal */ - return 0; - - mse = 2*intlog10(mse); - if (mse > c) { - /* Negative SNR, which is possible, but realisticly the - demod will lose lock before the signal gets this bad. The - API only allows for unsigned values, so just return 0 */ - return 0; - } - return 10*(c - mse); -} - -static int or51211_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct or51211_state* state = fe->demodulator_priv; - u8 rec_buf[2]; - u8 snd_buf[3]; - - /* SNR after Equalizer */ - snd_buf[0] = 0x04; - snd_buf[1] = 0x00; - snd_buf[2] = 0x04; - - if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) { - printk(KERN_WARNING "%s: error writing snr reg\n", - __func__); - return -1; - } - if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) { - printk(KERN_WARNING "%s: read_status read error\n", - __func__); - return -1; - } - - state->snr = calculate_snr(rec_buf[0], 89599047); - *snr = (state->snr) >> 16; - - dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0], - state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16); - - return 0; -} - -static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - /* Calculate Strength from SNR up to 35dB */ - /* Even though the SNR can go higher than 35dB, there is some comfort */ - /* factor in having a range of strong signals that can show at 100% */ - struct or51211_state* state = (struct or51211_state*)fe->demodulator_priv; - u16 snr; - int ret; - - ret = fe->ops.read_snr(fe, &snr); - if (ret != 0) - return ret; - /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */ - /* scale the range 0 - 35*2^24 into 0 - 65535 */ - if (state->snr >= 8960 * 0x10000) - *strength = 0xffff; - else - *strength = state->snr / 8960; - - return 0; -} - -static int or51211_read_ber(struct dvb_frontend* fe, u32* ber) -{ - *ber = -ENOSYS; - return 0; -} - -static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - *ucblocks = -ENOSYS; - return 0; -} - -static int or51211_sleep(struct dvb_frontend* fe) -{ - return 0; -} - -static int or51211_init(struct dvb_frontend* fe) -{ - struct or51211_state* state = fe->demodulator_priv; - const struct or51211_config* config = state->config; - const struct firmware* fw; - unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; - unsigned char rec_buf[14]; - int ret,i; - - if (!state->initialized) { - /* Request the firmware, this will block until it uploads */ - printk(KERN_INFO "or51211: Waiting for firmware upload " - "(%s)...\n", OR51211_DEFAULT_FIRMWARE); - ret = config->request_firmware(fe, &fw, - OR51211_DEFAULT_FIRMWARE); - printk(KERN_INFO "or51211:Got Hotplug firmware\n"); - if (ret) { - printk(KERN_WARNING "or51211: No firmware uploaded " - "(timeout or file not found?)\n"); - return ret; - } - - ret = or51211_load_firmware(fe, fw); - release_firmware(fw); - if (ret) { - printk(KERN_WARNING "or51211: Writing firmware to " - "device failed!\n"); - return ret; - } - printk(KERN_INFO "or51211: Firmware upload complete.\n"); - - /* Set operation mode in Receiver 1 register; - * type 1: - * data 0x50h Automatic sets receiver channel conditions - * Automatic NTSC rejection filter - * Enable MPEG serial data output - * MPEG2tr - * High tuner phase noise - * normal +/-150kHz Carrier acquisition range - */ - if (i2c_writebytes(state,state->config->demod_address, - cmd_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error 5\n"); - return -1; - } - - /* Read back ucode version to besure we loaded correctly */ - /* and are really up and running */ - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x03; - rec_buf[3] = 0x00; - msleep(30); - if (i2c_writebytes(state,state->config->demod_address, - rec_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error A\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[10],2)) { - printk(KERN_WARNING "or51211: Load DVR Error B\n"); - return -1; - } - - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x01; - rec_buf[3] = 0x00; - msleep(20); - if (i2c_writebytes(state,state->config->demod_address, - rec_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error C\n"); - return -1; - } - msleep(3); - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[12],2)) { - printk(KERN_WARNING "or51211: Load DVR Error D\n"); - return -1; - } - - for (i = 0; i < 8; i++) - rec_buf[i]=0xed; - - for (i = 0; i < 5; i++) { - msleep(30); - get_ver_buf[4] = i+1; - if (i2c_writebytes(state,state->config->demod_address, - get_ver_buf,5)) { - printk(KERN_WARNING "or51211:Load DVR Error 6" - " - %d\n",i); - return -1; - } - msleep(3); - - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[i*2],2)) { - printk(KERN_WARNING "or51211:Load DVR Error 7" - " - %d\n",i); - return -1; - } - /* If we didn't receive the right index, try again */ - if ((int)rec_buf[i*2+1]!=i+1){ - i--; - } - } - dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n", - rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3], - rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7], - rec_buf[8], rec_buf[9]); - - printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x" - " Status %02x\n", - rec_buf[2], rec_buf[4],rec_buf[6], - rec_buf[12],rec_buf[10]); - - rec_buf[0] = 0x04; - rec_buf[1] = 0x00; - rec_buf[2] = 0x03; - rec_buf[3] = 0x00; - msleep(20); - if (i2c_writebytes(state,state->config->demod_address, - rec_buf,3)) { - printk(KERN_WARNING "or51211: Load DVR Error 8\n"); - return -1; - } - msleep(20); - if (i2c_readbytes(state,state->config->demod_address, - &rec_buf[8],2)) { - printk(KERN_WARNING "or51211: Load DVR Error 9\n"); - return -1; - } - state->initialized = 1; - } - - return 0; -} - -static int or51211_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 500; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void or51211_release(struct dvb_frontend* fe) -{ - struct or51211_state* state = fe->demodulator_priv; - state->config->sleep(fe); - kfree(state); -} - -static struct dvb_frontend_ops or51211_ops; - -struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c) -{ - struct or51211_state* state = NULL; - - /* Allocate memory for the internal state */ - state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - /* Setup the state */ - state->config = config; - state->i2c = i2c; - state->initialized = 0; - state->current_frequency = 0; - - /* Create dvb_frontend */ - memcpy(&state->frontend.ops, &or51211_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops or51211_ops = { - - .info = { - .name = "Oren OR51211 VSB Frontend", - .type = FE_ATSC, - .frequency_min = 44000000, - .frequency_max = 958000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_8VSB - }, - - .release = or51211_release, - - .init = or51211_init, - .sleep = or51211_sleep, - - .set_frontend = or51211_set_parameters, - .get_tune_settings = or51211_get_tune_settings, - - .read_status = or51211_read_status, - .read_ber = or51211_read_ber, - .read_signal_strength = or51211_read_signal_strength, - .read_snr = or51211_read_snr, - .read_ucblocks = or51211_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver"); -MODULE_AUTHOR("Kirk Lapray"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(or51211_attach); - diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h deleted file mode 100644 index 3ce0508b898..00000000000 --- a/drivers/media/dvb/frontends/or51211.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Support for OR51211 (pcHDTV HD-2000) - VSB - * - * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * -*/ - -#ifndef OR51211_H -#define OR51211_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct or51211_config -{ - /* The demodulator's i2c address */ - u8 demod_address; - - /* Request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); - void (*setmode)(struct dvb_frontend * fe, int mode); - void (*reset)(struct dvb_frontend * fe); - void (*sleep)(struct dvb_frontend * fe); -}; - -#if defined(CONFIG_DVB_OR51211) || (defined(CONFIG_DVB_OR51211_MODULE) && defined(MODULE)) -extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_OR51211 - -#endif // OR51211_H - diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c deleted file mode 100644 index cf4d8936bb8..00000000000 --- a/drivers/media/dvb/frontends/s5h1409.c +++ /dev/null @@ -1,867 +0,0 @@ -/* - Samsung S5H1409 VSB/QAM demodulator driver - - Copyright (C) 2006 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "s5h1409.h" - -struct s5h1409_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct s5h1409_config *config; - - struct dvb_frontend frontend; - - /* previous uncorrected block counter */ - fe_modulation_t current_modulation; - - u32 current_frequency; - int if_freq; - - u32 is_qam_locked; - u32 qam_state; -}; - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -#define dprintk if (debug) printk - -/* Register values to initialise the demod, this will set VSB by default */ -static struct init_tab { - u8 reg; - u16 data; -} init_tab[] = { - { 0x00, 0x0071, }, - { 0x01, 0x3213, }, - { 0x09, 0x0025, }, - { 0x1c, 0x001d, }, - { 0x1f, 0x002d, }, - { 0x20, 0x001d, }, - { 0x22, 0x0022, }, - { 0x23, 0x0020, }, - { 0x29, 0x110f, }, - { 0x2a, 0x10b4, }, - { 0x2b, 0x10ae, }, - { 0x2c, 0x0031, }, - { 0x31, 0x010d, }, - { 0x32, 0x0100, }, - { 0x44, 0x0510, }, - { 0x54, 0x0104, }, - { 0x58, 0x2222, }, - { 0x59, 0x1162, }, - { 0x5a, 0x3211, }, - { 0x5d, 0x0370, }, - { 0x5e, 0x0296, }, - { 0x61, 0x0010, }, - { 0x63, 0x4a00, }, - { 0x65, 0x0800, }, - { 0x71, 0x0003, }, - { 0x72, 0x0470, }, - { 0x81, 0x0002, }, - { 0x82, 0x0600, }, - { 0x86, 0x0002, }, - { 0x8a, 0x2c38, }, - { 0x8b, 0x2a37, }, - { 0x92, 0x302f, }, - { 0x93, 0x3332, }, - { 0x96, 0x000c, }, - { 0x99, 0x0101, }, - { 0x9c, 0x2e37, }, - { 0x9d, 0x2c37, }, - { 0x9e, 0x2c37, }, - { 0xab, 0x0100, }, - { 0xac, 0x1003, }, - { 0xad, 0x103f, }, - { 0xe2, 0x0100, }, - { 0xe3, 0x1000, }, - { 0x28, 0x1010, }, - { 0xb1, 0x000e, }, -}; - -/* VSB SNR lookup table */ -static struct vsb_snr_tab { - u16 val; - u16 data; -} vsb_snr_tab[] = { - { 924, 300, }, - { 923, 300, }, - { 918, 295, }, - { 915, 290, }, - { 911, 285, }, - { 906, 280, }, - { 901, 275, }, - { 896, 270, }, - { 891, 265, }, - { 885, 260, }, - { 879, 255, }, - { 873, 250, }, - { 864, 245, }, - { 858, 240, }, - { 850, 235, }, - { 841, 230, }, - { 832, 225, }, - { 823, 220, }, - { 812, 215, }, - { 802, 210, }, - { 788, 205, }, - { 778, 200, }, - { 767, 195, }, - { 753, 190, }, - { 740, 185, }, - { 725, 180, }, - { 707, 175, }, - { 689, 170, }, - { 671, 165, }, - { 656, 160, }, - { 637, 155, }, - { 616, 150, }, - { 542, 145, }, - { 519, 140, }, - { 507, 135, }, - { 497, 130, }, - { 492, 125, }, - { 474, 120, }, - { 300, 111, }, - { 0, 0, }, -}; - -/* QAM64 SNR lookup table */ -static struct qam64_snr_tab { - u16 val; - u16 data; -} qam64_snr_tab[] = { - { 1, 0, }, - { 12, 300, }, - { 15, 290, }, - { 18, 280, }, - { 22, 270, }, - { 23, 268, }, - { 24, 266, }, - { 25, 264, }, - { 27, 262, }, - { 28, 260, }, - { 29, 258, }, - { 30, 256, }, - { 32, 254, }, - { 33, 252, }, - { 34, 250, }, - { 35, 249, }, - { 36, 248, }, - { 37, 247, }, - { 38, 246, }, - { 39, 245, }, - { 40, 244, }, - { 41, 243, }, - { 42, 241, }, - { 43, 240, }, - { 44, 239, }, - { 45, 238, }, - { 46, 237, }, - { 47, 236, }, - { 48, 235, }, - { 49, 234, }, - { 50, 233, }, - { 51, 232, }, - { 52, 231, }, - { 53, 230, }, - { 55, 229, }, - { 56, 228, }, - { 57, 227, }, - { 58, 226, }, - { 59, 225, }, - { 60, 224, }, - { 62, 223, }, - { 63, 222, }, - { 65, 221, }, - { 66, 220, }, - { 68, 219, }, - { 69, 218, }, - { 70, 217, }, - { 72, 216, }, - { 73, 215, }, - { 75, 214, }, - { 76, 213, }, - { 78, 212, }, - { 80, 211, }, - { 81, 210, }, - { 83, 209, }, - { 84, 208, }, - { 85, 207, }, - { 87, 206, }, - { 89, 205, }, - { 91, 204, }, - { 93, 203, }, - { 95, 202, }, - { 96, 201, }, - { 104, 200, }, - { 255, 0, }, -}; - -/* QAM256 SNR lookup table */ -static struct qam256_snr_tab { - u16 val; - u16 data; -} qam256_snr_tab[] = { - { 1, 0, }, - { 12, 400, }, - { 13, 390, }, - { 15, 380, }, - { 17, 360, }, - { 19, 350, }, - { 22, 348, }, - { 23, 346, }, - { 24, 344, }, - { 25, 342, }, - { 26, 340, }, - { 27, 336, }, - { 28, 334, }, - { 29, 332, }, - { 30, 330, }, - { 31, 328, }, - { 32, 326, }, - { 33, 325, }, - { 34, 322, }, - { 35, 320, }, - { 37, 318, }, - { 39, 316, }, - { 40, 314, }, - { 41, 312, }, - { 42, 310, }, - { 43, 308, }, - { 46, 306, }, - { 47, 304, }, - { 49, 302, }, - { 51, 300, }, - { 53, 298, }, - { 54, 297, }, - { 55, 296, }, - { 56, 295, }, - { 57, 294, }, - { 59, 293, }, - { 60, 292, }, - { 61, 291, }, - { 63, 290, }, - { 64, 289, }, - { 65, 288, }, - { 66, 287, }, - { 68, 286, }, - { 69, 285, }, - { 71, 284, }, - { 72, 283, }, - { 74, 282, }, - { 75, 281, }, - { 76, 280, }, - { 77, 279, }, - { 78, 278, }, - { 81, 277, }, - { 83, 276, }, - { 84, 275, }, - { 86, 274, }, - { 87, 273, }, - { 89, 272, }, - { 90, 271, }, - { 92, 270, }, - { 93, 269, }, - { 95, 268, }, - { 96, 267, }, - { 98, 266, }, - { 100, 265, }, - { 102, 264, }, - { 104, 263, }, - { 105, 262, }, - { 106, 261, }, - { 110, 260, }, - { 255, 0, }, -}; - -/* 8 bit registers, 16 bit values */ -static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data) -{ - int ret; - u8 buf[] = { reg, data >> 8, data & 0xff }; - - struct i2c_msg msg = { .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 3 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0, 0 }; - - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, - .buf = b1, .len = 2 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk("%s: readreg error (ret == %i)\n", __func__, ret); - return (b1[0] << 8) | b1[1]; -} - -static int s5h1409_softreset(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - s5h1409_writereg(state, 0xf5, 0); - s5h1409_writereg(state, 0xf5, 1); - state->is_qam_locked = 0; - state->qam_state = 0; - return 0; -} - -#define S5H1409_VSB_IF_FREQ 5380 -#define S5H1409_QAM_IF_FREQ (state->config->qam_if) - -static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d KHz)\n", __func__, KHz); - - switch (KHz) { - case 4000: - s5h1409_writereg(state, 0x87, 0x014b); - s5h1409_writereg(state, 0x88, 0x0cb5); - s5h1409_writereg(state, 0x89, 0x03e2); - break; - case 5380: - case 44000: - default: - s5h1409_writereg(state, 0x87, 0x01be); - s5h1409_writereg(state, 0x88, 0x0436); - s5h1409_writereg(state, 0x89, 0x054d); - break; - } - state->if_freq = KHz; - - return 0; -} - -static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, inverted); - - if (inverted == 1) - return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */ - else - return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */ -} - -static int s5h1409_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(0x%08x)\n", __func__, m); - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - if (state->if_freq != S5H1409_VSB_IF_FREQ) - s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ); - s5h1409_writereg(state, 0xf4, 0); - break; - case QAM_64: - case QAM_256: - case QAM_AUTO: - dprintk("%s() QAM_AUTO (64/256)\n", __func__); - if (state->if_freq != S5H1409_QAM_IF_FREQ) - s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ); - s5h1409_writereg(state, 0xf4, 1); - s5h1409_writereg(state, 0x85, 0x110); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - s5h1409_softreset(fe); - - return 0; -} - -static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return s5h1409_writereg(state, 0xf3, 1); - else - return s5h1409_writereg(state, 0xf3, 0); -} - -static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return s5h1409_writereg(state, 0xe3, - s5h1409_readreg(state, 0xe3) | 0x1100); - else - return s5h1409_writereg(state, 0xe3, - s5h1409_readreg(state, 0xe3) & 0xfeff); -} - -static int s5h1409_sleep(struct dvb_frontend *fe, int enable) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - return s5h1409_writereg(state, 0xf2, enable); -} - -static int s5h1409_register_reset(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - return s5h1409_writereg(state, 0xfa, 0); -} - -static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg; - - if (state->is_qam_locked) - return; - - /* QAM EQ lock check */ - reg = s5h1409_readreg(state, 0xf0); - - if ((reg >> 13) & 0x1) { - - state->is_qam_locked = 1; - reg &= 0xff; - - s5h1409_writereg(state, 0x96, 0x00c); - if ((reg < 0x38) || (reg > 0x68)) { - s5h1409_writereg(state, 0x93, 0x3332); - s5h1409_writereg(state, 0x9e, 0x2c37); - } else { - s5h1409_writereg(state, 0x93, 0x3130); - s5h1409_writereg(state, 0x9e, 0x2836); - } - - } else { - s5h1409_writereg(state, 0x96, 0x0008); - s5h1409_writereg(state, 0x93, 0x3332); - s5h1409_writereg(state, 0x9e, 0x2c37); - } -} - -static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg, reg1, reg2; - - reg = s5h1409_readreg(state, 0xf1); - - /* Master lock */ - if ((reg >> 15) & 0x1) { - if (state->qam_state != 2) { - state->qam_state = 2; - reg1 = s5h1409_readreg(state, 0xb2); - reg2 = s5h1409_readreg(state, 0xad); - - s5h1409_writereg(state, 0x96, 0x20); - s5h1409_writereg(state, 0xad, - (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff))); - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) & 0xeffe); - } - } else { - if (state->qam_state != 1) { - state->qam_state = 1; - s5h1409_writereg(state, 0x96, 0x08); - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) | 0x1001); - } - } -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1409_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - s5h1409_softreset(fe); - - state->current_frequency = p->frequency; - - s5h1409_enable_modulation(fe, p->u.vsb.modulation); - - /* Allow the demod to settle */ - msleep(100); - - if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Optimize the demod for QAM */ - if (p->u.vsb.modulation != VSB_8) { - s5h1409_set_qam_amhum_mode(fe); - s5h1409_set_qam_interleave_mode(fe); - } - - return 0; -} - -static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, mode); - - val = s5h1409_readreg(state, 0xac) & 0xcfff; - switch (mode) { - case S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: - val |= 0x0000; - break; - case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: - dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); - val |= 0x1000; - break; - case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: - val |= 0x2000; - break; - case S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: - val |= 0x3000; - break; - default: - return -EINVAL; - } - - /* Configure MPEG Signal Timing charactistics */ - return s5h1409_writereg(state, 0xac, val); -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int s5h1409_init(struct dvb_frontend *fe) -{ - int i; - - struct s5h1409_state *state = fe->demodulator_priv; - dprintk("%s()\n", __func__); - - s5h1409_sleep(fe, 0); - s5h1409_register_reset(fe); - - for (i = 0; i < ARRAY_SIZE(init_tab); i++) - s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data); - - /* The datasheet says that after initialisation, VSB is default */ - state->current_modulation = VSB_8; - - if (state->config->output_mode == S5H1409_SERIAL_OUTPUT) - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) | 0x100); /* Serial */ - else - s5h1409_writereg(state, 0xab, - s5h1409_readreg(state, 0xab) & 0xfeff); /* Parallel */ - - s5h1409_set_spectralinversion(fe, state->config->inversion); - s5h1409_set_if_freq(fe, state->if_freq); - s5h1409_set_gpio(fe, state->config->gpio); - s5h1409_set_mpeg_timing(fe, state->config->mpeg_timing); - s5h1409_softreset(fe); - - /* Note: Leaving the I2C gate closed. */ - s5h1409_i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg; - u32 tuner_status = 0; - - *status = 0; - - /* Get the demodulator status */ - reg = s5h1409_readreg(state, 0xf1); - if (reg & 0x1000) - *status |= FE_HAS_VITERBI; - if (reg & 0x8000) - *status |= FE_HAS_LOCK | FE_HAS_SYNC; - - switch (state->config->status_mode) { - case S5H1409_DEMODLOCKING: - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case S5H1409_TUNERLOCKING: - /* Get the tuner status */ - if (fe->ops.tuner_ops.get_status) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.get_status(fe, &tuner_status); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (tuner_status) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - } - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { - if (v < qam256_snr_tab[i].val) { - *snr = qam256_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { - if (v < qam64_snr_tab[i].val) { - *snr = qam64_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { - if (v > vsb_snr_tab[i].val) { - *snr = vsb_snr_tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct s5h1409_state *state = fe->demodulator_priv; - u16 reg; - dprintk("%s()\n", __func__); - - switch (state->current_modulation) { - case QAM_64: - reg = s5h1409_readreg(state, 0xf0) & 0xff; - return s5h1409_qam64_lookup_snr(fe, snr, reg); - case QAM_256: - reg = s5h1409_readreg(state, 0xf0) & 0xff; - return s5h1409_qam256_lookup_snr(fe, snr, reg); - case VSB_8: - reg = s5h1409_readreg(state, 0xf1) & 0x3ff; - return s5h1409_vsb_lookup_snr(fe, snr, reg); - default: - break; - } - - return -EINVAL; -} - -static int s5h1409_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return s5h1409_read_snr(fe, signal_strength); -} - -static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - *ucblocks = s5h1409_readreg(state, 0xb5); - - return 0; -} - -static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return s5h1409_read_ucblocks(fe, ber); -} - -static int s5h1409_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1409_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int s5h1409_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void s5h1409_release(struct dvb_frontend *fe) -{ - struct s5h1409_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops s5h1409_ops; - -struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, - struct i2c_adapter *i2c) -{ - struct s5h1409_state *state = NULL; - u16 reg; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1409_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->current_modulation = 0; - state->if_freq = S5H1409_VSB_IF_FREQ; - - /* check if the demod exists */ - reg = s5h1409_readreg(state, 0x04); - if ((reg != 0x0066) && (reg != 0x007f)) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1409_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - if (s5h1409_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - s5h1409_i2c_gate_ctrl(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(s5h1409_attach); - -static struct dvb_frontend_ops s5h1409_ops = { - - .info = { - .name = "Samsung S5H1409 QAM/8VSB Frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .init = s5h1409_init, - .i2c_gate_ctrl = s5h1409_i2c_gate_ctrl, - .set_frontend = s5h1409_set_frontend, - .get_frontend = s5h1409_get_frontend, - .get_tune_settings = s5h1409_get_tune_settings, - .read_status = s5h1409_read_status, - .read_ber = s5h1409_read_ber, - .read_signal_strength = s5h1409_read_signal_strength, - .read_snr = s5h1409_read_snr, - .read_ucblocks = s5h1409_read_ucblocks, - .release = s5h1409_release, -}; - -MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h deleted file mode 100644 index 070d9743e33..00000000000 --- a/drivers/media/dvb/frontends/s5h1409.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Samsung S5H1409 VSB/QAM demodulator driver - - Copyright (C) 2006 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __S5H1409_H__ -#define __S5H1409_H__ - -#include <linux/dvb/frontend.h> - -struct s5h1409_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* serial/parallel output */ -#define S5H1409_PARALLEL_OUTPUT 0 -#define S5H1409_SERIAL_OUTPUT 1 - u8 output_mode; - - /* GPIO Setting */ -#define S5H1409_GPIO_OFF 0 -#define S5H1409_GPIO_ON 1 - u8 gpio; - - /* IF Freq for QAM in KHz, VSB is hardcoded to 5380 */ - u16 qam_if; - - /* Spectral Inversion */ -#define S5H1409_INVERSION_OFF 0 -#define S5H1409_INVERSION_ON 1 - u8 inversion; - - /* Return lock status based on tuner lock, or demod lock */ -#define S5H1409_TUNERLOCKING 0 -#define S5H1409_DEMODLOCKING 1 - u8 status_mode; - - /* MPEG signal timing */ -#define S5H1409_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 -#define S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 -#define S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 -#define S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 - u16 mpeg_timing; -}; - -#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *s5h1409_attach( - const struct s5h1409_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S5H1409 */ - -#endif /* __S5H1409_H__ */ - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c deleted file mode 100644 index 66e2dd6d6fe..00000000000 --- a/drivers/media/dvb/frontends/s5h1411.c +++ /dev/null @@ -1,923 +0,0 @@ -/* - Samsung S5H1411 VSB/QAM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "s5h1411.h" - -struct s5h1411_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct s5h1411_config *config; - - struct dvb_frontend frontend; - - fe_modulation_t current_modulation; - unsigned int first_tune:1; - - u32 current_frequency; - int if_freq; - - u8 inversion; -}; - -static int debug; - -#define dprintk(arg...) do { \ - if (debug) \ - printk(arg); \ - } while (0) - -/* Register values to initialise the demod, defaults to VSB */ -static struct init_tab { - u8 addr; - u8 reg; - u16 data; -} init_tab[] = { - { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, }, - { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, }, - { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, }, - { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, }, - { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342c, }, - { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, }, - { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, }, - { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, }, - { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, }, - { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, }, - { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, }, - { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, }, - { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, }, - { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, }, - { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, }, - { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, }, - { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, }, - { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, }, - { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, }, - { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, }, - { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, }, - { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, }, - { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, }, - { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, }, - { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, }, - { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, }, - { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, }, - { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, }, - { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, }, - { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, }, - { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, }, - { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, }, - { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, }, - { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, }, - { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, }, - { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, }, - { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, }, - { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, }, - { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, }, - { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, }, - { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, }, - { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, }, - { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, }, - { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, }, - { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, }, - { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, }, - { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, }, - { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, }, - { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, }, - { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, }, - { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, }, - { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, }, - { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, }, - { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, }, - { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, }, - { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, }, - { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, }, - { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, }, - { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, }, - { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, }, - { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, }, - { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, }, - { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, }, - { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, }, - { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, }, - { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, }, - { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, }, - { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, }, - { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, }, - { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, }, - { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, }, - { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, }, - { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, }, - { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, }, - { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, }, - { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, }, - { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, }, - { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, }, - { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, }, - { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, }, -}; - -/* VSB SNR lookup table */ -static struct vsb_snr_tab { - u16 val; - u16 data; -} vsb_snr_tab[] = { - { 0x39f, 300, }, - { 0x39b, 295, }, - { 0x397, 290, }, - { 0x394, 285, }, - { 0x38f, 280, }, - { 0x38b, 275, }, - { 0x387, 270, }, - { 0x382, 265, }, - { 0x37d, 260, }, - { 0x377, 255, }, - { 0x370, 250, }, - { 0x36a, 245, }, - { 0x364, 240, }, - { 0x35b, 235, }, - { 0x353, 230, }, - { 0x349, 225, }, - { 0x340, 320, }, - { 0x337, 215, }, - { 0x327, 210, }, - { 0x31b, 205, }, - { 0x310, 200, }, - { 0x302, 195, }, - { 0x2f3, 190, }, - { 0x2e4, 185, }, - { 0x2d7, 180, }, - { 0x2cd, 175, }, - { 0x2bb, 170, }, - { 0x2a9, 165, }, - { 0x29e, 160, }, - { 0x284, 155, }, - { 0x27a, 150, }, - { 0x260, 145, }, - { 0x23a, 140, }, - { 0x224, 135, }, - { 0x213, 130, }, - { 0x204, 125, }, - { 0x1fe, 120, }, - { 0, 0, }, -}; - -/* QAM64 SNR lookup table */ -static struct qam64_snr_tab { - u16 val; - u16 data; -} qam64_snr_tab[] = { - { 0x0001, 0, }, - { 0x0af0, 300, }, - { 0x0d80, 290, }, - { 0x10a0, 280, }, - { 0x14b5, 270, }, - { 0x1590, 268, }, - { 0x1680, 266, }, - { 0x17b0, 264, }, - { 0x18c0, 262, }, - { 0x19b0, 260, }, - { 0x1ad0, 258, }, - { 0x1d00, 256, }, - { 0x1da0, 254, }, - { 0x1ef0, 252, }, - { 0x2050, 250, }, - { 0x20f0, 249, }, - { 0x21d0, 248, }, - { 0x22b0, 247, }, - { 0x23a0, 246, }, - { 0x2470, 245, }, - { 0x24f0, 244, }, - { 0x25a0, 243, }, - { 0x26c0, 242, }, - { 0x27b0, 241, }, - { 0x28d0, 240, }, - { 0x29b0, 239, }, - { 0x2ad0, 238, }, - { 0x2ba0, 237, }, - { 0x2c80, 236, }, - { 0x2d20, 235, }, - { 0x2e00, 234, }, - { 0x2f10, 233, }, - { 0x3050, 232, }, - { 0x3190, 231, }, - { 0x3300, 230, }, - { 0x3340, 229, }, - { 0x3200, 228, }, - { 0x3550, 227, }, - { 0x3610, 226, }, - { 0x3600, 225, }, - { 0x3700, 224, }, - { 0x3800, 223, }, - { 0x3920, 222, }, - { 0x3a20, 221, }, - { 0x3b30, 220, }, - { 0x3d00, 219, }, - { 0x3e00, 218, }, - { 0x4000, 217, }, - { 0x4100, 216, }, - { 0x4300, 215, }, - { 0x4400, 214, }, - { 0x4600, 213, }, - { 0x4700, 212, }, - { 0x4800, 211, }, - { 0x4a00, 210, }, - { 0x4b00, 209, }, - { 0x4d00, 208, }, - { 0x4f00, 207, }, - { 0x5050, 206, }, - { 0x5200, 205, }, - { 0x53c0, 204, }, - { 0x5450, 203, }, - { 0x5650, 202, }, - { 0x5820, 201, }, - { 0x6000, 200, }, - { 0xffff, 0, }, -}; - -/* QAM256 SNR lookup table */ -static struct qam256_snr_tab { - u16 val; - u16 data; -} qam256_snr_tab[] = { - { 0x0001, 0, }, - { 0x0970, 400, }, - { 0x0a90, 390, }, - { 0x0b90, 380, }, - { 0x0d90, 370, }, - { 0x0ff0, 360, }, - { 0x1240, 350, }, - { 0x1345, 348, }, - { 0x13c0, 346, }, - { 0x14c0, 344, }, - { 0x1500, 342, }, - { 0x1610, 340, }, - { 0x1700, 338, }, - { 0x1800, 336, }, - { 0x18b0, 334, }, - { 0x1900, 332, }, - { 0x1ab0, 330, }, - { 0x1bc0, 328, }, - { 0x1cb0, 326, }, - { 0x1db0, 324, }, - { 0x1eb0, 322, }, - { 0x2030, 320, }, - { 0x2200, 318, }, - { 0x2280, 316, }, - { 0x2410, 314, }, - { 0x25b0, 312, }, - { 0x27a0, 310, }, - { 0x2840, 308, }, - { 0x29d0, 306, }, - { 0x2b10, 304, }, - { 0x2d30, 302, }, - { 0x2f20, 300, }, - { 0x30c0, 298, }, - { 0x3260, 297, }, - { 0x32c0, 296, }, - { 0x3300, 295, }, - { 0x33b0, 294, }, - { 0x34b0, 293, }, - { 0x35a0, 292, }, - { 0x3650, 291, }, - { 0x3800, 290, }, - { 0x3900, 289, }, - { 0x3a50, 288, }, - { 0x3b30, 287, }, - { 0x3cb0, 286, }, - { 0x3e20, 285, }, - { 0x3fa0, 284, }, - { 0x40a0, 283, }, - { 0x41c0, 282, }, - { 0x42f0, 281, }, - { 0x44a0, 280, }, - { 0x4600, 279, }, - { 0x47b0, 278, }, - { 0x4900, 277, }, - { 0x4a00, 276, }, - { 0x4ba0, 275, }, - { 0x4d00, 274, }, - { 0x4f00, 273, }, - { 0x5000, 272, }, - { 0x51f0, 272, }, - { 0x53a0, 270, }, - { 0x5520, 269, }, - { 0x5700, 268, }, - { 0x5800, 267, }, - { 0x5a00, 266, }, - { 0x5c00, 265, }, - { 0x5d00, 264, }, - { 0x5f00, 263, }, - { 0x6000, 262, }, - { 0x6200, 261, }, - { 0x6400, 260, }, - { 0xffff, 0, }, -}; - -/* 8 bit registers, 16 bit values */ -static int s5h1411_writereg(struct s5h1411_state *state, - u8 addr, u8 reg, u16 data) -{ - int ret; - u8 buf[] = { reg, data >> 8, data & 0xff }; - - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, " - "ret == %i)\n", __func__, addr, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0, 0 }; - - struct i2c_msg msg[] = { - { .addr = addr, .flags = 0, .buf = b0, .len = 1 }, - { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - return (b1[0] << 8) | b1[1]; -} - -static int s5h1411_softreset(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1); - return 0; -} - -static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(%d KHz)\n", __func__, KHz); - - switch (KHz) { - case 3250: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d5); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9); - break; - case 3500: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225); - break; - case 4000: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd); - break; - default: - dprintk("%s(%d KHz) Invalid, defaulting to 5380\n", - __func__, KHz); - /* no break, need to continue */ - case 5380: - case 44000: - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4); - break; - } - - state->if_freq = KHz; - - return 0; -} - -static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, mode); - - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff; - switch (mode) { - case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK: - val |= 0x0000; - break; - case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK: - dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode); - val |= 0x1000; - break; - case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK: - val |= 0x2000; - break; - case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK: - val |= 0x3000; - break; - default: - return -EINVAL; - } - - /* Configure MPEG Signal Timing charactistics */ - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val); -} - -static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, inversion); - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000; - - if (inversion == 1) - val |= 0x1000; /* Inverted */ - - state->inversion = inversion; - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val); -} - -static int s5h1411_set_serialmode(struct dvb_frontend *fe, int serial) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, serial); - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbd) & ~0x100; - - if (serial == 1) - val |= 0x100; - - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, val); -} - -static int s5h1411_enable_modulation(struct dvb_frontend *fe, - fe_modulation_t m) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(0x%08x)\n", __func__, m); - - if ((state->first_tune == 0) && (m == state->current_modulation)) { - dprintk("%s() Already at desired modulation. Skipping...\n", - __func__); - return 0; - } - - switch (m) { - case VSB_8: - dprintk("%s() VSB_8\n", __func__); - s5h1411_set_if_freq(fe, state->config->vsb_if); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1); - break; - case QAM_64: - case QAM_256: - case QAM_AUTO: - dprintk("%s() QAM_AUTO (64/256)\n", __func__); - s5h1411_set_if_freq(fe, state->config->qam_if); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001); - s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101); - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0); - break; - default: - dprintk("%s() Invalid modulation\n", __func__); - return -EINVAL; - } - - state->current_modulation = m; - state->first_tune = 0; - s5h1411_softreset(fe); - - return 0; -} - -static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); - else - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0); -} - -static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 val; - - dprintk("%s(%d)\n", __func__, enable); - - val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02; - - if (enable) - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, - val | 0x02); - else - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val); -} - -static int s5h1411_set_powerstate(struct dvb_frontend *fe, int enable) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(%d)\n", __func__, enable); - - if (enable) - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1); - else { - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0); - s5h1411_softreset(fe); - } - - return 0; -} - -static int s5h1411_sleep(struct dvb_frontend *fe) -{ - return s5h1411_set_powerstate(fe, 1); -} - -static int s5h1411_register_reset(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s()\n", __func__); - - return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0); -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -static int s5h1411_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - dprintk("%s(frequency=%d)\n", __func__, p->frequency); - - s5h1411_softreset(fe); - - state->current_frequency = p->frequency; - - s5h1411_enable_modulation(fe, p->u.vsb.modulation); - - if (fe->ops.tuner_ops.set_params) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.set_params(fe, p); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Issue a reset to the demod so it knows to resync against the - newly tuned frequency */ - s5h1411_softreset(fe); - - return 0; -} - -/* Reset the demod hardware and reset all of the configuration registers - to a default state. */ -static int s5h1411_init(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - int i; - - dprintk("%s()\n", __func__); - - s5h1411_set_powerstate(fe, 0); - s5h1411_register_reset(fe); - - for (i = 0; i < ARRAY_SIZE(init_tab); i++) - s5h1411_writereg(state, init_tab[i].addr, - init_tab[i].reg, - init_tab[i].data); - - /* The datasheet says that after initialisation, VSB is default */ - state->current_modulation = VSB_8; - - /* Although the datasheet says it's in VSB, empirical evidence - shows problems getting lock on the first tuning request. Make - sure we call enable_modulation the first time around */ - state->first_tune = 1; - - if (state->config->output_mode == S5H1411_SERIAL_OUTPUT) - /* Serial */ - s5h1411_set_serialmode(fe, 1); - else - /* Parallel */ - s5h1411_set_serialmode(fe, 0); - - s5h1411_set_spectralinversion(fe, state->config->inversion); - s5h1411_set_if_freq(fe, state->config->vsb_if); - s5h1411_set_gpio(fe, state->config->gpio); - s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing); - s5h1411_softreset(fe); - - /* Note: Leaving the I2C gate closed. */ - s5h1411_i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 reg; - u32 tuner_status = 0; - - *status = 0; - - /* Register F2 bit 15 = Master Lock, removed */ - - switch (state->current_modulation) { - case QAM_64: - case QAM_256: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0); - if (reg & 0x10) /* QAM FEC Lock */ - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - if (reg & 0x100) /* QAM EQ Lock */ - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - break; - case VSB_8: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2); - if (reg & 0x1000) /* FEC Lock */ - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - if (reg & 0x2000) /* EQ Lock */ - *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; - - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x53); - if (reg & 0x1) /* AFC Lock */ - *status |= FE_HAS_SIGNAL; - - break; - default: - return -EINVAL; - } - - switch (state->config->status_mode) { - case S5H1411_DEMODLOCKING: - if (*status & FE_HAS_VITERBI) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - case S5H1411_TUNERLOCKING: - /* Get the tuner status */ - if (fe->ops.tuner_ops.get_status) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.get_status(fe, &tuner_status); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - if (tuner_status) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - break; - } - - dprintk("%s() status 0x%08x\n", __func__, *status); - - return 0; -} - -static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) { - if (v < qam256_snr_tab[i].val) { - *snr = qam256_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) { - if (v < qam64_snr_tab[i].val) { - *snr = qam64_snr_tab[i].data; - ret = 0; - break; - } - } - return ret; -} - -static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v) -{ - int i, ret = -EINVAL; - dprintk("%s()\n", __func__); - - for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) { - if (v > vsb_snr_tab[i].val) { - *snr = vsb_snr_tab[i].data; - ret = 0; - break; - } - } - dprintk("%s() snr=%d\n", __func__, *snr); - return ret; -} - -static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct s5h1411_state *state = fe->demodulator_priv; - u16 reg; - dprintk("%s()\n", __func__); - - switch (state->current_modulation) { - case QAM_64: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1); - return s5h1411_qam64_lookup_snr(fe, snr, reg); - case QAM_256: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1); - return s5h1411_qam256_lookup_snr(fe, snr, reg); - case VSB_8: - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, - 0xf2) & 0x3ff; - return s5h1411_vsb_lookup_snr(fe, snr, reg); - default: - break; - } - - return -EINVAL; -} - -static int s5h1411_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - return s5h1411_read_snr(fe, signal_strength); -} - -static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9); - - return 0; -} - -static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - return s5h1411_read_ucblocks(fe, ber); -} - -static int s5h1411_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1411_state *state = fe->demodulator_priv; - - p->frequency = state->current_frequency; - p->u.vsb.modulation = state->current_modulation; - - return 0; -} - -static int s5h1411_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void s5h1411_release(struct dvb_frontend *fe) -{ - struct s5h1411_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops s5h1411_ops; - -struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, - struct i2c_adapter *i2c) -{ - struct s5h1411_state *state = NULL; - u16 reg; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->current_modulation = VSB_8; - state->inversion = state->config->inversion; - - /* check if the demod exists */ - reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05); - if (reg != 0x0066) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1411_ops, - sizeof(struct dvb_frontend_ops)); - - state->frontend.demodulator_priv = state; - - if (s5h1411_init(&state->frontend) != 0) { - printk(KERN_ERR "%s: Failed to initialize correctly\n", - __func__); - goto error; - } - - /* Note: Leaving the I2C gate open here. */ - s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1); - - /* Put the device into low-power mode until first use */ - s5h1411_set_powerstate(&state->frontend, 1); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(s5h1411_attach); - -static struct dvb_frontend_ops s5h1411_ops = { - - .info = { - .name = "Samsung S5H1411 QAM/8VSB Frontend", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - - .init = s5h1411_init, - .sleep = s5h1411_sleep, - .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl, - .set_frontend = s5h1411_set_frontend, - .get_frontend = s5h1411_get_frontend, - .get_tune_settings = s5h1411_get_tune_settings, - .read_status = s5h1411_read_status, - .read_ber = s5h1411_read_ber, - .read_signal_strength = s5h1411_read_signal_strength, - .read_snr = s5h1411_read_snr, - .read_ucblocks = s5h1411_read_ucblocks, - .release = s5h1411_release, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1411.h b/drivers/media/dvb/frontends/s5h1411.h deleted file mode 100644 index 45ec0f82989..00000000000 --- a/drivers/media/dvb/frontends/s5h1411.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - Samsung S5H1411 VSB/QAM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __S5H1411_H__ -#define __S5H1411_H__ - -#include <linux/dvb/frontend.h> - -#define S5H1411_I2C_TOP_ADDR (0x32 >> 1) -#define S5H1411_I2C_QAM_ADDR (0x34 >> 1) - -struct s5h1411_config { - - /* serial/parallel output */ -#define S5H1411_PARALLEL_OUTPUT 0 -#define S5H1411_SERIAL_OUTPUT 1 - u8 output_mode; - - /* GPIO Setting */ -#define S5H1411_GPIO_OFF 0 -#define S5H1411_GPIO_ON 1 - u8 gpio; - - /* MPEG signal timing */ -#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0 -#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1 -#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2 -#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3 - u16 mpeg_timing; - - /* IF Freq for QAM and VSB in KHz */ -#define S5H1411_IF_3250 3250 -#define S5H1411_IF_3500 3500 -#define S5H1411_IF_4000 4000 -#define S5H1411_IF_5380 5380 -#define S5H1411_IF_44000 44000 -#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000 -#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000 - u16 qam_if; - u16 vsb_if; - - /* Spectral Inversion */ -#define S5H1411_INVERSION_OFF 0 -#define S5H1411_INVERSION_ON 1 - u8 inversion; - - /* Return lock status based on tuner lock, or demod lock */ -#define S5H1411_TUNERLOCKING 0 -#define S5H1411_DEMODLOCKING 1 - u8 status_mode; -}; - -#if defined(CONFIG_DVB_S5H1411) || \ - (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE)) -extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *s5h1411_attach( - const struct s5h1411_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S5H1411 */ - -#endif /* __S5H1411_H__ */ - -/* - * Local variables: - * c-basic-offset: 8 - */ diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c deleted file mode 100644 index 2e9fd2893ed..00000000000 --- a/drivers/media/dvb/frontends/s5h1420.c +++ /dev/null @@ -1,982 +0,0 @@ -/* - * Driver for - * Samsung S5H1420 and - * PnpNetwork PN1010 QPSK Demodulator - * - * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include <linux/i2c.h> - - -#include "dvb_frontend.h" -#include "s5h1420.h" -#include "s5h1420_priv.h" - -#define TONE_FREQ 22000 - -struct s5h1420_state { - struct i2c_adapter* i2c; - const struct s5h1420_config* config; - - struct dvb_frontend frontend; - struct i2c_adapter tuner_i2c_adapter; - - u8 CON_1_val; - - u8 postlocked:1; - u32 fclk; - u32 tunedfreq; - fe_code_rate_t fec_inner; - u32 symbol_rate; - - /* FIXME: ugly workaround for flexcop's incapable i2c-controller - * it does not support repeated-start, workaround: write addr-1 - * and then read - */ - u8 shadow[256]; -}; - -static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); -static int s5h1420_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings); - - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debugging"); - -#define dprintk(x...) do { \ - if (debug) \ - printk(KERN_DEBUG "S5H1420: " x); \ -} while (0) - -static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg) -{ - int ret; - u8 b[2]; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 }, - { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 }, - }; - - b[0] = (reg - 1) & 0xff; - b[1] = state->shadow[(reg - 1) & 0xff]; - - if (state->config->repeated_start_workaround) { - ret = i2c_transfer(state->i2c, msg, 3); - if (ret != 3) - return ret; - } else { - ret = i2c_transfer(state->i2c, &msg[1], 1); - if (ret != 1) - return ret; - ret = i2c_transfer(state->i2c, &msg[2], 1); - if (ret != 1) - return ret; - } - - /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */ - - return b[0]; -} - -static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int err; - - /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */ - err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - state->shadow[reg] = data; - - return 0; -} - -static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - dprintk("enter %s\n", __func__); - - switch(voltage) { - case SEC_VOLTAGE_13: - s5h1420_writereg(state, 0x3c, - (s5h1420_readreg(state, 0x3c) & 0xfe) | 0x02); - break; - - case SEC_VOLTAGE_18: - s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) | 0x03); - break; - - case SEC_VOLTAGE_OFF: - s5h1420_writereg(state, 0x3c, s5h1420_readreg(state, 0x3c) & 0xfd); - break; - } - - dprintk("leave %s\n", __func__); - return 0; -} - -static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - dprintk("enter %s\n", __func__); - switch(tone) { - case SEC_TONE_ON: - s5h1420_writereg(state, 0x3b, - (s5h1420_readreg(state, 0x3b) & 0x74) | 0x08); - break; - - case SEC_TONE_OFF: - s5h1420_writereg(state, 0x3b, - (s5h1420_readreg(state, 0x3b) & 0x74) | 0x01); - break; - } - dprintk("leave %s\n", __func__); - - return 0; -} - -static int s5h1420_send_master_cmd (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - int i; - unsigned long timeout; - int result = 0; - - dprintk("enter %s\n", __func__); - if (cmd->msg_len > 8) - return -EINVAL; - - /* setup for DISEQC */ - val = s5h1420_readreg(state, 0x3b); - s5h1420_writereg(state, 0x3b, 0x02); - msleep(15); - - /* write the DISEQC command bytes */ - for(i=0; i< cmd->msg_len; i++) { - s5h1420_writereg(state, 0x3d + i, cmd->msg[i]); - } - - /* kick off transmission */ - s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | - ((cmd->msg_len-1) << 4) | 0x08); - - /* wait for transmission to complete */ - timeout = jiffies + ((100*HZ) / 1000); - while(time_before(jiffies, timeout)) { - if (!(s5h1420_readreg(state, 0x3b) & 0x08)) - break; - - msleep(5); - } - if (time_after(jiffies, timeout)) - result = -ETIMEDOUT; - - /* restore original settings */ - s5h1420_writereg(state, 0x3b, val); - msleep(15); - dprintk("leave %s\n", __func__); - return result; -} - -static int s5h1420_recv_slave_reply (struct dvb_frontend* fe, - struct dvb_diseqc_slave_reply* reply) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - int i; - int length; - unsigned long timeout; - int result = 0; - - /* setup for DISEQC recieve */ - val = s5h1420_readreg(state, 0x3b); - s5h1420_writereg(state, 0x3b, 0x82); /* FIXME: guess - do we need to set DIS_RDY(0x08) in receive mode? */ - msleep(15); - - /* wait for reception to complete */ - timeout = jiffies + ((reply->timeout*HZ) / 1000); - while(time_before(jiffies, timeout)) { - if (!(s5h1420_readreg(state, 0x3b) & 0x80)) /* FIXME: do we test DIS_RDY(0x08) or RCV_EN(0x80)? */ - break; - - msleep(5); - } - if (time_after(jiffies, timeout)) { - result = -ETIMEDOUT; - goto exit; - } - - /* check error flag - FIXME: not sure what this does - docs do not describe - * beyond "error flag for diseqc receive data :( */ - if (s5h1420_readreg(state, 0x49)) { - result = -EIO; - goto exit; - } - - /* check length */ - length = (s5h1420_readreg(state, 0x3b) & 0x70) >> 4; - if (length > sizeof(reply->msg)) { - result = -EOVERFLOW; - goto exit; - } - reply->msg_len = length; - - /* extract data */ - for(i=0; i< length; i++) { - reply->msg[i] = s5h1420_readreg(state, 0x3d + i); - } - -exit: - /* restore original settings */ - s5h1420_writereg(state, 0x3b, val); - msleep(15); - return result; -} - -static int s5h1420_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - int result = 0; - unsigned long timeout; - - /* setup for tone burst */ - val = s5h1420_readreg(state, 0x3b); - s5h1420_writereg(state, 0x3b, (s5h1420_readreg(state, 0x3b) & 0x70) | 0x01); - - /* set value for B position if requested */ - if (minicmd == SEC_MINI_B) { - s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x04); - } - msleep(15); - - /* start transmission */ - s5h1420_writereg(state, 0x3b, s5h1420_readreg(state, 0x3b) | 0x08); - - /* wait for transmission to complete */ - timeout = jiffies + ((100*HZ) / 1000); - while(time_before(jiffies, timeout)) { - if (!(s5h1420_readreg(state, 0x3b) & 0x08)) - break; - - msleep(5); - } - if (time_after(jiffies, timeout)) - result = -ETIMEDOUT; - - /* restore original settings */ - s5h1420_writereg(state, 0x3b, val); - msleep(15); - return result; -} - -static fe_status_t s5h1420_get_status_bits(struct s5h1420_state* state) -{ - u8 val; - fe_status_t status = 0; - - val = s5h1420_readreg(state, 0x14); - if (val & 0x02) - status |= FE_HAS_SIGNAL; - if (val & 0x01) - status |= FE_HAS_CARRIER; - val = s5h1420_readreg(state, 0x36); - if (val & 0x01) - status |= FE_HAS_VITERBI; - if (val & 0x20) - status |= FE_HAS_SYNC; - if (status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC)) - status |= FE_HAS_LOCK; - - return status; -} - -static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct s5h1420_state* state = fe->demodulator_priv; - u8 val; - - dprintk("enter %s\n", __func__); - - if (status == NULL) - return -EINVAL; - - /* determine lock state */ - *status = s5h1420_get_status_bits(state); - - /* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert - the inversion, wait a bit and check again */ - if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) { - val = s5h1420_readreg(state, Vit10); - if ((val & 0x07) == 0x03) { - if (val & 0x08) - s5h1420_writereg(state, Vit09, 0x13); - else - s5h1420_writereg(state, Vit09, 0x1b); - - /* wait a bit then update lock status */ - mdelay(200); - *status = s5h1420_get_status_bits(state); - } - } - - /* perform post lock setup */ - if ((*status & FE_HAS_LOCK) && !state->postlocked) { - - /* calculate the data rate */ - u32 tmp = s5h1420_getsymbolrate(state); - switch (s5h1420_readreg(state, Vit10) & 0x07) { - case 0: tmp = (tmp * 2 * 1) / 2; break; - case 1: tmp = (tmp * 2 * 2) / 3; break; - case 2: tmp = (tmp * 2 * 3) / 4; break; - case 3: tmp = (tmp * 2 * 5) / 6; break; - case 4: tmp = (tmp * 2 * 6) / 7; break; - case 5: tmp = (tmp * 2 * 7) / 8; break; - } - - if (tmp == 0) { - printk(KERN_ERR "s5h1420: avoided division by 0\n"); - tmp = 1; - } - tmp = state->fclk / tmp; - - - /* set the MPEG_CLK_INTL for the calculated data rate */ - if (tmp < 2) - val = 0x00; - else if (tmp < 5) - val = 0x01; - else if (tmp < 9) - val = 0x02; - else if (tmp < 13) - val = 0x03; - else if (tmp < 17) - val = 0x04; - else if (tmp < 25) - val = 0x05; - else if (tmp < 33) - val = 0x06; - else - val = 0x07; - dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val); - - s5h1420_writereg(state, FEC01, 0x18); - s5h1420_writereg(state, FEC01, 0x10); - s5h1420_writereg(state, FEC01, val); - - /* Enable "MPEG_Out" */ - val = s5h1420_readreg(state, Mpeg02); - s5h1420_writereg(state, Mpeg02, val | (1 << 6)); - - /* kicker disable */ - val = s5h1420_readreg(state, QPSK01) & 0x7f; - s5h1420_writereg(state, QPSK01, val); - - /* DC freeze TODO it was never activated by default or it can stay activated */ - - if (s5h1420_getsymbolrate(state) >= 20000000) { - s5h1420_writereg(state, Loop04, 0x8a); - s5h1420_writereg(state, Loop05, 0x6a); - } else { - s5h1420_writereg(state, Loop04, 0x58); - s5h1420_writereg(state, Loop05, 0x27); - } - - /* post-lock processing has been done! */ - state->postlocked = 1; - } - - dprintk("leave %s\n", __func__); - - return 0; -} - -static int s5h1420_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - s5h1420_writereg(state, 0x46, 0x1d); - mdelay(25); - - *ber = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); - - return 0; -} - -static int s5h1420_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - u8 val = s5h1420_readreg(state, 0x15); - - *strength = (u16) ((val << 8) | val); - - return 0; -} - -static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - s5h1420_writereg(state, 0x46, 0x1f); - mdelay(25); - - *ucblocks = (s5h1420_readreg(state, 0x48) << 8) | s5h1420_readreg(state, 0x47); - - return 0; -} - -static void s5h1420_reset(struct s5h1420_state* state) -{ - dprintk("%s\n", __func__); - s5h1420_writereg (state, 0x01, 0x08); - s5h1420_writereg (state, 0x01, 0x00); - udelay(10); -} - -static void s5h1420_setsymbolrate(struct s5h1420_state* state, - struct dvb_frontend_parameters *p) -{ - u8 v; - u64 val; - - dprintk("enter %s\n", __func__); - - val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24); - if (p->u.qpsk.symbol_rate < 29000000) - val *= 2; - do_div(val, (state->fclk / 1000)); - - dprintk("symbol rate register: %06llx\n", (unsigned long long)val); - - v = s5h1420_readreg(state, Loop01); - s5h1420_writereg(state, Loop01, v & 0x7f); - s5h1420_writereg(state, Tnco01, val >> 16); - s5h1420_writereg(state, Tnco02, val >> 8); - s5h1420_writereg(state, Tnco03, val & 0xff); - s5h1420_writereg(state, Loop01, v | 0x80); - dprintk("leave %s\n", __func__); -} - -static u32 s5h1420_getsymbolrate(struct s5h1420_state* state) -{ - return state->symbol_rate; -} - -static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset) -{ - int val; - u8 v; - - dprintk("enter %s\n", __func__); - - /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so - * divide fclk by 1000000 to get the correct value. */ - val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000)); - - dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val); - - v = s5h1420_readreg(state, Loop01); - s5h1420_writereg(state, Loop01, v & 0xbf); - s5h1420_writereg(state, Pnco01, val >> 16); - s5h1420_writereg(state, Pnco02, val >> 8); - s5h1420_writereg(state, Pnco03, val & 0xff); - s5h1420_writereg(state, Loop01, v | 0x40); - dprintk("leave %s\n", __func__); -} - -static int s5h1420_getfreqoffset(struct s5h1420_state* state) -{ - int val; - - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08); - val = s5h1420_readreg(state, 0x0e) << 16; - val |= s5h1420_readreg(state, 0x0f) << 8; - val |= s5h1420_readreg(state, 0x10); - s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7); - - if (val & 0x800000) - val |= 0xff000000; - - /* remember freqoffset is in kHz, but the chip wants the offset in Hz, so - * divide fclk by 1000000 to get the correct value. */ - val = (((-val) * (state->fclk/1000000)) / (1<<24)); - - return val; -} - -static void s5h1420_setfec_inversion(struct s5h1420_state* state, - struct dvb_frontend_parameters *p) -{ - u8 inversion = 0; - u8 vit08, vit09; - - dprintk("enter %s\n", __func__); - - if (p->inversion == INVERSION_OFF) - inversion = state->config->invert ? 0x08 : 0; - else if (p->inversion == INVERSION_ON) - inversion = state->config->invert ? 0 : 0x08; - - if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) { - vit08 = 0x3f; - vit09 = 0; - } else { - switch(p->u.qpsk.fec_inner) { - case FEC_1_2: - vit08 = 0x01; vit09 = 0x10; - break; - - case FEC_2_3: - vit08 = 0x02; vit09 = 0x11; - break; - - case FEC_3_4: - vit08 = 0x04; vit09 = 0x12; - break; - - case FEC_5_6: - vit08 = 0x08; vit09 = 0x13; - break; - - case FEC_6_7: - vit08 = 0x10; vit09 = 0x14; - break; - - case FEC_7_8: - vit08 = 0x20; vit09 = 0x15; - break; - - default: - return; - } - } - vit09 |= inversion; - dprintk("fec: %02x %02x\n", vit08, vit09); - s5h1420_writereg(state, Vit08, vit08); - s5h1420_writereg(state, Vit09, vit09); - dprintk("leave %s\n", __func__); -} - -static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state) -{ - switch(s5h1420_readreg(state, 0x32) & 0x07) { - case 0: - return FEC_1_2; - - case 1: - return FEC_2_3; - - case 2: - return FEC_3_4; - - case 3: - return FEC_5_6; - - case 4: - return FEC_6_7; - - case 5: - return FEC_7_8; - } - - return FEC_NONE; -} - -static fe_spectral_inversion_t s5h1420_getinversion(struct s5h1420_state* state) -{ - if (s5h1420_readreg(state, 0x32) & 0x08) - return INVERSION_ON; - - return INVERSION_OFF; -} - -static int s5h1420_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1420_state* state = fe->demodulator_priv; - int frequency_delta; - struct dvb_frontend_tune_settings fesettings; - uint8_t clock_settting; - - dprintk("enter %s\n", __func__); - - /* check if we should do a fast-tune */ - memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters)); - s5h1420_get_tune_settings(fe, &fesettings); - frequency_delta = p->frequency - state->tunedfreq; - if ((frequency_delta > -fesettings.max_drift) && - (frequency_delta < fesettings.max_drift) && - (frequency_delta != 0) && - (state->fec_inner == p->u.qpsk.fec_inner) && - (state->symbol_rate == p->u.qpsk.symbol_rate)) { - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.tuner_ops.get_frequency) { - u32 tmp; - fe->ops.tuner_ops.get_frequency(fe, &tmp); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - s5h1420_setfreqoffset(state, p->frequency - tmp); - } else { - s5h1420_setfreqoffset(state, 0); - } - dprintk("simple tune\n"); - return 0; - } - dprintk("tuning demod\n"); - - /* first of all, software reset */ - s5h1420_reset(state); - - /* set s5h1420 fclk PLL according to desired symbol rate */ - if (p->u.qpsk.symbol_rate > 33000000) - state->fclk = 80000000; - else if (p->u.qpsk.symbol_rate > 28500000) - state->fclk = 59000000; - else if (p->u.qpsk.symbol_rate > 25000000) - state->fclk = 86000000; - else if (p->u.qpsk.symbol_rate > 1900000) - state->fclk = 88000000; - else - state->fclk = 44000000; - - /* Clock */ - switch (state->fclk) { - default: - case 88000000: - clock_settting = 80; - break; - case 86000000: - clock_settting = 78; - break; - case 80000000: - clock_settting = 72; - break; - case 59000000: - clock_settting = 51; - break; - case 44000000: - clock_settting = 36; - break; - } - dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8); - s5h1420_writereg(state, PLL02, 0x40); - s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); - - /* TODO DC offset removal, config parameter ? */ - if (p->u.qpsk.symbol_rate > 29000000) - s5h1420_writereg(state, QPSK01, 0xae | 0x10); - else - s5h1420_writereg(state, QPSK01, 0xac | 0x10); - - /* set misc registers */ - s5h1420_writereg(state, CON_1, 0x00); - s5h1420_writereg(state, QPSK02, 0x00); - s5h1420_writereg(state, Pre01, 0xb0); - - s5h1420_writereg(state, Loop01, 0xF0); - s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */ - s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */ - if (p->u.qpsk.symbol_rate > 20000000) - s5h1420_writereg(state, Loop04, 0x79); - else - s5h1420_writereg(state, Loop04, 0x58); - s5h1420_writereg(state, Loop05, 0x6b); - - if (p->u.qpsk.symbol_rate >= 8000000) - s5h1420_writereg(state, Post01, (0 << 6) | 0x10); - else if (p->u.qpsk.symbol_rate >= 4000000) - s5h1420_writereg(state, Post01, (1 << 6) | 0x10); - else - s5h1420_writereg(state, Post01, (3 << 6) | 0x10); - - s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */ - - s5h1420_writereg(state, Sync01, 0x33); - s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity); - s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */ - s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */ - - s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */ - s5h1420_writereg(state, DiS03, 0x00); - s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */ - - /* set tuner PLL */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - s5h1420_setfreqoffset(state, 0); - } - - /* set the reset of the parameters */ - s5h1420_setsymbolrate(state, p); - s5h1420_setfec_inversion(state, p); - - /* start QPSK */ - s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1); - - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; - state->postlocked = 0; - state->tunedfreq = p->frequency; - - dprintk("leave %s\n", __func__); - return 0; -} - -static int s5h1420_get_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - p->frequency = state->tunedfreq + s5h1420_getfreqoffset(state); - p->inversion = s5h1420_getinversion(state); - p->u.qpsk.symbol_rate = s5h1420_getsymbolrate(state); - p->u.qpsk.fec_inner = s5h1420_getfec(state); - - return 0; -} - -static int s5h1420_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { - fesettings->min_delay_ms = 50; - fesettings->step_size = 2000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1500; - fesettings->max_drift = 9000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 500; - fesettings->max_drift = 7000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 14 * fesettings->step_size; - } else { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 18 * fesettings->step_size; - } - - return 0; -} - -static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - if (enable) - return s5h1420_writereg(state, 0x02, state->CON_1_val | 1); - else - return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe); -} - -static int s5h1420_init (struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - - /* disable power down and do reset */ - state->CON_1_val = state->config->serial_mpeg << 4; - s5h1420_writereg(state, 0x02, state->CON_1_val); - msleep(10); - s5h1420_reset(state); - - return 0; -} - -static int s5h1420_sleep(struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - state->CON_1_val = 0x12; - return s5h1420_writereg(state, 0x02, state->CON_1_val); -} - -static void s5h1420_release(struct dvb_frontend* fe) -{ - struct s5h1420_state* state = fe->demodulator_priv; - i2c_del_adapter(&state->tuner_i2c_adapter); - kfree(state); -} - -static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) -{ - struct s5h1420_state *state = i2c_get_adapdata(i2c_adap); - struct i2c_msg m[1 + num]; - u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */ - - memset(m, 0, sizeof(struct i2c_msg) * (1 + num)); - - m[0].addr = state->config->demod_address; - m[0].buf = tx_open; - m[0].len = 2; - - memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); - - return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO; -} - -static struct i2c_algorithm s5h1420_tuner_i2c_algo = { - .master_xfer = s5h1420_tuner_i2c_tuner_xfer, - .functionality = s5h1420_tuner_i2c_func, -}; - -struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - struct s5h1420_state *state = fe->demodulator_priv; - return &state->tuner_i2c_adapter; -} -EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter); - -static struct dvb_frontend_ops s5h1420_ops; - -struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, - struct i2c_adapter *i2c) -{ - /* allocate memory for the internal state */ - struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL); - u8 i; - - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->postlocked = 0; - state->fclk = 88000000; - state->tunedfreq = 0; - state->fec_inner = FEC_NONE; - state->symbol_rate = 0; - - /* check if the demod is there + identify it */ - i = s5h1420_readreg(state, ID01); - if (i != 0x03) - goto error; - - memset(state->shadow, 0xff, sizeof(state->shadow)); - - for (i = 0; i < 0x50; i++) - state->shadow[i] = s5h1420_readreg(state, i); - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* create tuner i2c adapter */ - strlcpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", - sizeof(state->tuner_i2c_adapter.name)); - state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL, - state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo; - state->tuner_i2c_adapter.algo_data = NULL; - i2c_set_adapdata(&state->tuner_i2c_adapter, state); - if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) { - printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n"); - goto error; - } - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(s5h1420_attach); - -static struct dvb_frontend_ops s5h1420_ops = { - - .info = { - .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = s5h1420_release, - - .init = s5h1420_init, - .sleep = s5h1420_sleep, - .i2c_gate_ctrl = s5h1420_i2c_gate_ctrl, - - .set_frontend = s5h1420_set_frontend, - .get_frontend = s5h1420_get_frontend, - .get_tune_settings = s5h1420_get_tune_settings, - - .read_status = s5h1420_read_status, - .read_ber = s5h1420_read_ber, - .read_signal_strength = s5h1420_read_signal_strength, - .read_ucblocks = s5h1420_read_ucblocks, - - .diseqc_send_master_cmd = s5h1420_send_master_cmd, - .diseqc_recv_slave_reply = s5h1420_recv_slave_reply, - .diseqc_send_burst = s5h1420_send_burst, - .set_tone = s5h1420_set_tone, - .set_voltage = s5h1420_set_voltage, -}; - -MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver"); -MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h deleted file mode 100644 index ff308136d86..00000000000 --- a/drivers/media/dvb/frontends/s5h1420.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Driver for - * Samsung S5H1420 and - * PnpNetwork PN1010 QPSK Demodulator - * - * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef S5H1420_H -#define S5H1420_H - -#include <linux/dvb/frontend.h> - -struct s5h1420_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* does the inversion require inversion? */ - u8 invert:1; - - u8 repeated_start_workaround:1; - u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */ - - u8 serial_mpeg:1; -}; - -#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) -extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, - struct i2c_adapter *i2c); -extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe); -#else -static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} - -static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe) -{ - return NULL; -} -#endif // CONFIG_DVB_S5H1420 - -#endif // S5H1420_H diff --git a/drivers/media/dvb/frontends/s5h1420_priv.h b/drivers/media/dvb/frontends/s5h1420_priv.h deleted file mode 100644 index d9c58d28181..00000000000 --- a/drivers/media/dvb/frontends/s5h1420_priv.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Driver for - * Samsung S5H1420 and - * PnpNetwork PN1010 QPSK Demodulator - * - * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> - * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 Mass - * Ave, Cambridge, MA 02139, USA. - */ -#ifndef S5H1420_PRIV -#define S5H1420_PRIV - -#include <asm/types.h> - -enum s5h1420_register { - ID01 = 0x00, - CON_0 = 0x01, - CON_1 = 0x02, - PLL01 = 0x03, - PLL02 = 0x04, - QPSK01 = 0x05, - QPSK02 = 0x06, - Pre01 = 0x07, - Post01 = 0x08, - Loop01 = 0x09, - Loop02 = 0x0a, - Loop03 = 0x0b, - Loop04 = 0x0c, - Loop05 = 0x0d, - Pnco01 = 0x0e, - Pnco02 = 0x0f, - Pnco03 = 0x10, - Tnco01 = 0x11, - Tnco02 = 0x12, - Tnco03 = 0x13, - Monitor01 = 0x14, - Monitor02 = 0x15, - Monitor03 = 0x16, - Monitor04 = 0x17, - Monitor05 = 0x18, - Monitor06 = 0x19, - Monitor07 = 0x1a, - Monitor12 = 0x1f, - - FEC01 = 0x22, - Soft01 = 0x23, - Soft02 = 0x24, - Soft03 = 0x25, - Soft04 = 0x26, - Soft05 = 0x27, - Soft06 = 0x28, - Vit01 = 0x29, - Vit02 = 0x2a, - Vit03 = 0x2b, - Vit04 = 0x2c, - Vit05 = 0x2d, - Vit06 = 0x2e, - Vit07 = 0x2f, - Vit08 = 0x30, - Vit09 = 0x31, - Vit10 = 0x32, - Vit11 = 0x33, - Vit12 = 0x34, - Sync01 = 0x35, - Sync02 = 0x36, - Rs01 = 0x37, - Mpeg01 = 0x38, - Mpeg02 = 0x39, - DiS01 = 0x3a, - DiS02 = 0x3b, - DiS03 = 0x3c, - DiS04 = 0x3d, - DiS05 = 0x3e, - DiS06 = 0x3f, - DiS07 = 0x40, - DiS08 = 0x41, - DiS09 = 0x42, - DiS10 = 0x43, - DiS11 = 0x44, - Rf01 = 0x45, - Err01 = 0x46, - Err02 = 0x47, - Err03 = 0x48, - Err04 = 0x49, -}; - - -#endif diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c deleted file mode 100644 index 974b52be9ae..00000000000 --- a/drivers/media/dvb/frontends/s921_core.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Driver for Sharp s921 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - */ - - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include "s921_core.h" - -static int s921_isdb_init(struct s921_isdb_t *dev); -static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params); -static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params); -static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data); - -static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01, - 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, - 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00, - 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80, - 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12, - 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00, - 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff, - 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00, - 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88, - 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00, - 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06, - 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00, - 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00, - 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20, - 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70, - 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f, - 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00, - 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, - 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30, - 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d, - 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f, - 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00, - 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84, - 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e, - 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba, - 0xf8, 0xd7 }; - -static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b, - 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b, - 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b, - 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b, - 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b, - 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b, - 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b, - 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb, - 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb, - 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb, - 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb, - 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb, - 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb, - 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b, - 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b, - 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b, - 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b }; - -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) { - switch(cmd) { - case ISDB_T_CMD_INIT: - s921_isdb_init(dev); - break; - case ISDB_T_CMD_SET_PARAM: - s921_isdb_set_parameters(dev, data); - break; - case ISDB_T_CMD_TUNE: - s921_isdb_tune(dev, data); - break; - case ISDB_T_CMD_GET_STATUS: - s921_isdb_get_status(dev, data); - break; - default: - printk("unhandled command\n"); - return -EINVAL; - } - return 0; -} - -static int s921_isdb_init(struct s921_isdb_t *dev) { - unsigned int i; - unsigned int ret; - printk("isdb_init\n"); - for (i = 0; i < sizeof(init_table); i+=2) { - ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]); - if (ret != 0) { - printk("i2c write failed\n"); - return ret; - } - } - return 0; -} - -static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) { - - int ret; - /* auto is sufficient for now, lateron this should be reflected in an extra interface */ - - - - ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2); - ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2); - - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7); - if (ret < 0) - return -EINVAL; - - return E_OK; -} - -static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) { - - int ret; - int index; - - index = (params->frequency - 473143000)/6000000; - - if (index > 48) { - return -EINVAL; - } - - dev->i2c_write(dev->priv_dev, 0x47, 0x60); - - ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09); - if (ret < 0) - return -EINVAL; - - dev->i2c_write(dev->priv_dev, 0x01, 0x40); - return 0; -} - -static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) { - unsigned int *ret = (unsigned int*)data; - u8 ifagc_dt; - u8 rfagc_dt; - - mdelay(10); - ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81); - rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82); - if (rfagc_dt == 0x40) { - *ret = 1; - } - return 0; -} diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h deleted file mode 100644 index de2f10a44e7..00000000000 --- a/drivers/media/dvb/frontends/s921_core.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef _S921_CORE_H -#define _S921_CORE_H -//#define u8 unsigned int -//#define u32 unsigned int - - - -//#define EINVAL -1 -#define E_OK 0 - -struct s921_isdb_t { - void *priv_dev; - int (*i2c_write)(void *dev, u8 reg, u8 val); - int (*i2c_read)(void *dev, u8 reg); -}; - -#define ISDB_T_CMD_INIT 0 -#define ISDB_T_CMD_SET_PARAM 1 -#define ISDB_T_CMD_TUNE 2 -#define ISDB_T_CMD_GET_STATUS 3 - -struct s921_isdb_t_tune_params { - u32 frequency; -}; - -struct s921_isdb_t_status { -}; - -struct s921_isdb_t_transmission_mode_params { - u8 mode; - u8 layer_a_mode; -#define ISDB_T_LA_MODE_1 0 -#define ISDB_T_LA_MODE_2 1 -#define ISDB_T_LA_MODE_3 2 - u8 layer_a_carrier_modulation; -#define ISDB_T_LA_CM_DQPSK 0 -#define ISDB_T_LA_CM_QPSK 1 -#define ISDB_T_LA_CM_16QAM 2 -#define ISDB_T_LA_CM_64QAM 3 -#define ISDB_T_LA_CM_NOLAYER 4 - u8 layer_a_code_rate; -#define ISDB_T_LA_CR_1_2 0 -#define ISDB_T_LA_CR_2_3 1 -#define ISDB_T_LA_CR_3_4 2 -#define ISDB_T_LA_CR_5_6 4 -#define ISDB_T_LA_CR_7_8 8 -#define ISDB_T_LA_CR_NOLAYER 16 - u8 layer_a_time_interleave; -#define ISDB_T_LA_TI_0 0 -#define ISDB_T_LA_TI_1 1 -#define ISDB_T_LA_TI_2 2 -#define ISDB_T_LA_TI_4 4 -#define ISDB_T_LA_TI_8 8 -#define ISDB_T_LA_TI_16 16 -#define ISDB_T_LA_TI_32 32 - u8 layer_a_nseg; - - u8 layer_b_mode; -#define ISDB_T_LB_MODE_1 0 -#define ISDB_T_LB_MODE_2 1 -#define ISDB_T_LB_MODE_3 2 - u8 layer_b_carrier_modulation; -#define ISDB_T_LB_CM_DQPSK 0 -#define ISDB_T_LB_CM_QPSK 1 -#define ISDB_T_LB_CM_16QAM 2 -#define ISDB_T_LB_CM_64QAM 3 -#define ISDB_T_LB_CM_NOLAYER 4 - u8 layer_b_code_rate; -#define ISDB_T_LB_CR_1_2 0 -#define ISDB_T_LB_CR_2_3 1 -#define ISDB_T_LB_CR_3_4 2 -#define ISDB_T_LB_CR_5_6 4 -#define ISDB_T_LB_CR_7_8 8 -#define ISDB_T_LB_CR_NOLAYER 16 - u8 layer_b_time_interleave; -#define ISDB_T_LB_TI_0 0 -#define ISDB_T_LB_TI_1 1 -#define ISDB_T_LB_TI_2 2 -#define ISDB_T_LB_TI_4 4 -#define ISDB_T_LB_TI_8 8 -#define ISDB_T_LB_TI_16 16 -#define ISDB_T_LB_TI_32 32 - u8 layer_b_nseg; - - u8 layer_c_mode; -#define ISDB_T_LC_MODE_1 0 -#define ISDB_T_LC_MODE_2 1 -#define ISDB_T_LC_MODE_3 2 - u8 layer_c_carrier_modulation; -#define ISDB_T_LC_CM_DQPSK 0 -#define ISDB_T_LC_CM_QPSK 1 -#define ISDB_T_LC_CM_16QAM 2 -#define ISDB_T_LC_CM_64QAM 3 -#define ISDB_T_LC_CM_NOLAYER 4 - u8 layer_c_code_rate; -#define ISDB_T_LC_CR_1_2 0 -#define ISDB_T_LC_CR_2_3 1 -#define ISDB_T_LC_CR_3_4 2 -#define ISDB_T_LC_CR_5_6 4 -#define ISDB_T_LC_CR_7_8 8 -#define ISDB_T_LC_CR_NOLAYER 16 - u8 layer_c_time_interleave; -#define ISDB_T_LC_TI_0 0 -#define ISDB_T_LC_TI_1 1 -#define ISDB_T_LC_TI_2 2 -#define ISDB_T_LC_TI_4 4 -#define ISDB_T_LC_TI_8 8 -#define ISDB_T_LC_TI_16 16 -#define ISDB_T_LC_TI_32 32 - u8 layer_c_nseg; -}; - -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); -#endif diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c deleted file mode 100644 index 892af8c9ed5..00000000000 --- a/drivers/media/dvb/frontends/s921_module.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Driver for Sharp s921 driver - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - * All rights reserved. - * - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "s921_module.h" -#include "s921_core.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"s921 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("s921 debug: " fmt, ##args); } while (0) - -struct s921_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct s921_isdb_t dev; - struct i2c_adapter *i2c; -}; - -static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - struct s921_isdb_t_transmission_mode_params params; - struct s921_isdb_t_tune_params tune_params; - - tune_params.frequency = param->frequency; - s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms); - s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params); - mdelay(100); - return 0; -} - -static int s921_init(struct dvb_frontend *fe) { - printk("s921 init\n"); - return 0; -} - -static int s921_sleep(struct dvb_frontend *fe) { - printk("s921 sleep\n"); - return 0; -} - -static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - unsigned int ret; - mdelay(5); - s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret); - *status = 0; - - printk("status: %02x\n", ret); - if (ret == 1) { - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - - return 0; -} - -static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void s921_release(struct dvb_frontend *fe) -{ - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_s921={ - .info = { - .name = "SHARP S921", - .type = FE_OFDM, - .frequency_min = 473143000, - .frequency_max = 767143000, - .frequency_stepsize = 6000000, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - .init = s921_init, - .sleep = s921_sleep, - .set_frontend = s921_set_parameters, - .read_snr = s921_read_snr, - .read_ber = s921_read_ber, - .read_status = s921_read_status, - .read_ucblocks = s921_read_ucblocks, - .release = s921_release, -}; - -static int s921_write(void *dev, u8 reg, u8 val) { - struct s921_state *state = dev; - char buf[2]={reg,val}; - int err; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 2, - .buf = buf - }; - - if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __func__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static int s921_read(void *dev, u8 reg) { - struct s921_state *state = dev; - u8 b1; - int ret; - struct i2c_msg msg[2] = { { .addr = state->addr, - .flags = 0, - .buf = ®, .len = 1 }, - { .addr = state->addr, - .flags = I2C_M_RD, - .buf = &b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - return ret; - return b1; -} - -struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c) -{ - - struct s921_state *state; - state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct s921_state)); - - state->addr = config->i2c_address; - state->i2c = i2c; - state->dev.i2c_write = &s921_write; - state->dev.i2c_read = &s921_read; - state->dev.priv_dev = state; - - s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL); - - memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(s921_attach); -MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>"); -MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h deleted file mode 100644 index 78660424ba9..00000000000 --- a/drivers/media/dvb/frontends/s921_module.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Driver for DVB-T s921 demodulator - * - * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef S921_MODULE_H -#define S921_MODULE_H - -#include <linux/dvb/frontend.h> -#include "s921_core.h" - -int s921_isdb_init(struct s921_isdb_t *dev); -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); - -struct s921_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE)) -extern struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S921 */ - -#endif /* S921_H */ diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c deleted file mode 100644 index 0bd16af8a6c..00000000000 --- a/drivers/media/dvb/frontends/si21xx.c +++ /dev/null @@ -1,973 +0,0 @@ -/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -*/ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "si21xx.h" - -#define REVISION_REG 0x00 -#define SYSTEM_MODE_REG 0x01 -#define TS_CTRL_REG_1 0x02 -#define TS_CTRL_REG_2 0x03 -#define PIN_CTRL_REG_1 0x04 -#define PIN_CTRL_REG_2 0x05 -#define LOCK_STATUS_REG_1 0x0f -#define LOCK_STATUS_REG_2 0x10 -#define ACQ_STATUS_REG 0x11 -#define ACQ_CTRL_REG_1 0x13 -#define ACQ_CTRL_REG_2 0x14 -#define PLL_DIVISOR_REG 0x15 -#define COARSE_TUNE_REG 0x16 -#define FINE_TUNE_REG_L 0x17 -#define FINE_TUNE_REG_H 0x18 - -#define ANALOG_AGC_POWER_LEVEL_REG 0x28 -#define CFO_ESTIMATOR_CTRL_REG_1 0x29 -#define CFO_ESTIMATOR_CTRL_REG_2 0x2a -#define CFO_ESTIMATOR_CTRL_REG_3 0x2b - -#define SYM_RATE_ESTIMATE_REG_L 0x31 -#define SYM_RATE_ESTIMATE_REG_M 0x32 -#define SYM_RATE_ESTIMATE_REG_H 0x33 - -#define CFO_ESTIMATOR_OFFSET_REG_L 0x36 -#define CFO_ESTIMATOR_OFFSET_REG_H 0x37 -#define CFO_ERROR_REG_L 0x38 -#define CFO_ERROR_REG_H 0x39 -#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a - -#define SYM_RATE_REG_L 0x3f -#define SYM_RATE_REG_M 0x40 -#define SYM_RATE_REG_H 0x41 -#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42 -#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43 - -#define C_N_ESTIMATOR_CTRL_REG 0x7c -#define C_N_ESTIMATOR_THRSHLD_REG 0x7d -#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e -#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f - -#define BLIND_SCAN_CTRL_REG 0x80 - -#define LSA_CTRL_REG_1 0x8D -#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f -#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90 -#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91 -#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92 -#define INBAND_POWER_THRSHLD_REG 0x93 -#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94 - -#define VIT_SRCH_CTRL_REG_1 0xa0 -#define VIT_SRCH_CTRL_REG_2 0xa1 -#define VIT_SRCH_CTRL_REG_3 0xa2 -#define VIT_SRCH_STATUS_REG 0xa3 -#define VITERBI_BER_COUNT_REG_L 0xab -#define REED_SOLOMON_CTRL_REG 0xb0 -#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1 -#define PRBS_CTRL_REG 0xb5 - -#define LNB_CTRL_REG_1 0xc0 -#define LNB_CTRL_REG_2 0xc1 -#define LNB_CTRL_REG_3 0xc2 -#define LNB_CTRL_REG_4 0xc3 -#define LNB_CTRL_STATUS_REG 0xc4 -#define LNB_FIFO_REGS_0 0xc5 -#define LNB_FIFO_REGS_1 0xc6 -#define LNB_FIFO_REGS_2 0xc7 -#define LNB_FIFO_REGS_3 0xc8 -#define LNB_FIFO_REGS_4 0xc9 -#define LNB_FIFO_REGS_5 0xca -#define LNB_SUPPLY_CTRL_REG_1 0xcb -#define LNB_SUPPLY_CTRL_REG_2 0xcc -#define LNB_SUPPLY_CTRL_REG_3 0xcd -#define LNB_SUPPLY_CTRL_REG_4 0xce -#define LNB_SUPPLY_STATUS_REG 0xcf - -#define FALSE 0 -#define TRUE 1 -#define FAIL -1 -#define PASS 0 - -#define ALLOWABLE_FS_COUNT 10 -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "si21xx: " args); \ - } while (0) - -enum { - ACTIVE_HIGH, - ACTIVE_LOW -}; -enum { - BYTE_WIDE, - BIT_WIDE -}; -enum { - CLK_GAPPED_MODE, - CLK_CONTINUOUS_MODE -}; -enum { - RISING_EDGE, - FALLING_EDGE -}; -enum { - MSB_FIRST, - LSB_FIRST -}; -enum { - SERIAL, - PARALLEL -}; - -struct si21xx_state { - struct i2c_adapter *i2c; - const struct si21xx_config *config; - struct dvb_frontend frontend; - u8 initialised:1; - int errmode; - int fs; /*Sampling rate of the ADC in MHz*/ -}; - -/* register default initialization */ -static u8 serit_sp1511lhb_inittab[] = { - 0x01, 0x28, /* set i2c_inc_disable */ - 0x20, 0x03, - 0x27, 0x20, - 0xe0, 0x45, - 0xe1, 0x08, - 0xfe, 0x01, - 0x01, 0x28, - 0x89, 0x09, - 0x04, 0x80, - 0x05, 0x01, - 0x06, 0x00, - 0x20, 0x03, - 0x24, 0x88, - 0x29, 0x09, - 0x2a, 0x0f, - 0x2c, 0x10, - 0x2d, 0x19, - 0x2e, 0x08, - 0x2f, 0x10, - 0x30, 0x19, - 0x34, 0x20, - 0x35, 0x03, - 0x45, 0x02, - 0x46, 0x45, - 0x47, 0xd0, - 0x48, 0x00, - 0x49, 0x40, - 0x4a, 0x03, - 0x4c, 0xfd, - 0x4f, 0x2e, - 0x50, 0x2e, - 0x51, 0x10, - 0x52, 0x10, - 0x56, 0x92, - 0x59, 0x00, - 0x5a, 0x2d, - 0x5b, 0x33, - 0x5c, 0x1f, - 0x5f, 0x76, - 0x62, 0xc0, - 0x63, 0xc0, - 0x64, 0xf3, - 0x65, 0xf3, - 0x79, 0x40, - 0x6a, 0x40, - 0x6b, 0x0a, - 0x6c, 0x80, - 0x6d, 0x27, - 0x71, 0x06, - 0x75, 0x60, - 0x78, 0x00, - 0x79, 0xb5, - 0x7c, 0x05, - 0x7d, 0x1a, - 0x87, 0x55, - 0x88, 0x72, - 0x8f, 0x08, - 0x90, 0xe0, - 0x94, 0x40, - 0xa0, 0x3f, - 0xa1, 0xc0, - 0xa4, 0xcc, - 0xa5, 0x66, - 0xa6, 0x66, - 0xa7, 0x7b, - 0xa8, 0x7b, - 0xa9, 0x7b, - 0xaa, 0x9a, - 0xed, 0x04, - 0xad, 0x00, - 0xae, 0x03, - 0xcc, 0xab, - 0x01, 0x08, - 0xff, 0xff -}; - -/* low level read/writes */ -static int si21_writeregs(struct si21xx_state *state, u8 reg1, - u8 *data, int len) -{ - int ret; - u8 buf[60];/* = { reg1, data };*/ - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = len + 1 - }; - - msg.buf[0] = reg1; - memcpy(msg.buf + 1, data, len); - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg1, data[0], ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int si21_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct si21xx_state *state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return si21_writereg(state, buf[0], buf[1]); -} - -static u8 si21_readreg(struct si21xx_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = ®1, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b, - .len = len - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - - return ret == 2 ? 0 : -1; -} - -static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout) -{ - unsigned long start = jiffies; - - dprintk("%s\n", __func__); - - while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) { - if (jiffies - start > timeout) { - dprintk("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate) -{ - struct si21xx_state *state = fe->demodulator_priv; - u32 sym_rate, data_rate; - int i; - u8 sym_rate_bytes[3]; - - dprintk("%s : srate = %i\n", __func__ , srate); - - if ((srate < 1000000) || (srate > 45000000)) - return -EINVAL; - - data_rate = srate; - sym_rate = 0; - - for (i = 0; i < 4; ++i) { - sym_rate /= 100; - sym_rate = sym_rate + ((data_rate % 100) * 0x800000) / - state->fs; - data_rate /= 100; - } - for (i = 0; i < 3; ++i) - sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff); - - si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03); - - return 0; -} - -static int si21xx_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *m) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 lnb_status; - u8 LNB_CTRL_1; - int status; - - dprintk("%s\n", __func__); - - status = PASS; - LNB_CTRL_1 = 0; - - status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01); - status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01); - - /*fill the FIFO*/ - status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len); - - LNB_CTRL_1 = (lnb_status & 0x70); - LNB_CTRL_1 |= m->msg_len; - - LNB_CTRL_1 |= 0x80; /* begin LNB signaling */ - - status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01); - - return status; -} - -static int si21xx_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 val; - - dprintk("%s\n", __func__); - - if (si21xx_wait_diseqc_idle(state, 100) < 0) - return -ETIMEDOUT; - - val = (0x80 | si21_readreg(state, 0xc1)); - if (si21_writereg(state, LNB_CTRL_REG_1, - burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10))) - return -EREMOTEIO; - - if (si21xx_wait_diseqc_idle(state, 100) < 0) - return -ETIMEDOUT; - - if (si21_writereg(state, LNB_CTRL_REG_1, val)) - return -EREMOTEIO; - - return 0; -} -/* 30.06.2008 */ -static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 val; - - dprintk("%s\n", __func__); - val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1)); - - switch (tone) { - case SEC_TONE_ON: - return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20); - - case SEC_TONE_OFF: - return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20)); - - default: - return -EINVAL; - } -} - -static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) -{ - struct si21xx_state *state = fe->demodulator_priv; - - u8 val; - dprintk("%s: %s\n", __func__, - volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - - val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1)); - - switch (volt) { - case SEC_VOLTAGE_18: - return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40); - break; - case SEC_VOLTAGE_13: - return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40)); - break; - default: - return -EINVAL; - }; -} - -static int si21xx_init(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - int i; - int status = 0; - u8 reg1; - u8 val; - u8 reg2[2]; - - dprintk("%s\n", __func__); - - for (i = 0; ; i += 2) { - reg1 = serit_sp1511lhb_inittab[i]; - val = serit_sp1511lhb_inittab[i+1]; - if (reg1 == 0xff && val == 0xff) - break; - si21_writeregs(state, reg1, &val, 1); - } - - /*DVB QPSK SYSTEM MODE REG*/ - reg1 = 0x08; - si21_writeregs(state, SYSTEM_MODE_REG, ®1, 0x01); - - /*transport stream config*/ - /* - mode = PARALLEL; - sdata_form = LSB_FIRST; - clk_edge = FALLING_EDGE; - clk_mode = CLK_GAPPED_MODE; - strt_len = BYTE_WIDE; - sync_pol = ACTIVE_HIGH; - val_pol = ACTIVE_HIGH; - err_pol = ACTIVE_HIGH; - sclk_rate = 0x00; - parity = 0x00 ; - data_delay = 0x00; - clk_delay = 0x00; - pclk_smooth = 0x00; - */ - reg2[0] = - PARALLEL + (LSB_FIRST << 1) - + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3) - + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5) - + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7); - - reg2[1] = 0; - /* sclk_rate + (parity << 2) - + (data_delay << 3) + (clk_delay << 4) - + (pclk_smooth << 5); - */ - status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02); - if (status != 0) - dprintk(" %s : TS Set Error\n", __func__); - - return 0; - -} - -static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 regs_read[2]; - u8 reg_read; - u8 i; - u8 lock; - u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG); - - si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02); - reg_read = 0; - - for (i = 0; i < 7; ++i) - reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i); - - lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80)); - - dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock); - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (lock & 0x2) - *status |= FE_HAS_CARRIER; - - if (lock & 0x20) - *status |= FE_HAS_VITERBI; - - if (lock & 0x40) - *status |= FE_HAS_SYNC; - - if ((lock & 0x7b) == 0x7b) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct si21xx_state *state = fe->demodulator_priv; - - /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG, - (u8*)agclevel, 0x01);*/ - - u16 signal = (3 * si21_readreg(state, 0x27) * - si21_readreg(state, 0x28)); - - dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__, - si21_readreg(state, 0x27), - si21_readreg(state, 0x28), (int) signal); - - signal <<= 4; - *strength = signal; - - return 0; -} - -static int si21_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (state->errmode != STATUS_BER) - return 0; - - *ber = (si21_readreg(state, 0x1d) << 8) | - si21_readreg(state, 0x1e); - - return 0; -} - -static int si21_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct si21xx_state *state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) | - si21_readreg(state, 0x25)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - - dprintk("%s\n", __func__); - - return 0; -} - -static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (state->errmode != STATUS_UCBLOCKS) - *ucblocks = 0; - else - *ucblocks = (si21_readreg(state, 0x1d) << 8) | - si21_readreg(state, 0x1e); - - return 0; -} - -/* initiates a channel acquisition sequence - using the specified symbol rate and code rate */ -static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate, - fe_code_rate_t crate) -{ - - struct si21xx_state *state = fe->demodulator_priv; - u8 coderates[] = { - 0x0, 0x01, 0x02, 0x04, 0x00, - 0x8, 0x10, 0x20, 0x00, 0x3f - }; - - u8 coderate_ptr; - int status; - u8 start_acq = 0x80; - u8 reg, regs[3]; - - dprintk("%s\n", __func__); - - status = PASS; - coderate_ptr = coderates[crate]; - - si21xx_set_symbolrate(fe, symbrate); - - /* write code rates to use in the Viterbi search */ - status |= si21_writeregs(state, - VIT_SRCH_CTRL_REG_1, - &coderate_ptr, 0x01); - - /* clear acq_start bit */ - status |= si21_readregs(state, ACQ_CTRL_REG_2, ®, 0x01); - reg &= ~start_acq; - status |= si21_writeregs(state, ACQ_CTRL_REG_2, ®, 0x01); - - /* use new Carrier Frequency Offset Estimator (QuickLock) */ - regs[0] = 0xCB; - regs[1] = 0x40; - regs[2] = 0xCB; - - status |= si21_writeregs(state, - TWO_DB_BNDWDTH_THRSHLD_REG, - ®s[0], 0x03); - reg = 0x56; - status |= si21_writeregs(state, - LSA_CTRL_REG_1, ®, 1); - reg = 0x05; - status |= si21_writeregs(state, - BLIND_SCAN_CTRL_REG, ®, 1); - /* start automatic acq */ - status |= si21_writeregs(state, - ACQ_CTRL_REG_2, &start_acq, 0x01); - - return status; -} - -static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int si21xx_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) -{ - struct si21xx_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz) - datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/ - - /* in MHz */ - unsigned char coarse_tune_freq; - int fine_tune_freq; - unsigned char sample_rate = 0; - /* boolean */ - unsigned int inband_interferer_ind; - - /* INTERMEDIATE VALUES */ - int icoarse_tune_freq; /* MHz */ - int ifine_tune_freq; /* MHz */ - unsigned int band_high; - unsigned int band_low; - unsigned int x1; - unsigned int x2; - int i; - unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = { - FALSE, FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, FALSE - }; - unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = { - FALSE, FALSE, FALSE, FALSE, FALSE, - FALSE, FALSE, FALSE, FALSE, FALSE - }; - - int status; - - /* allowable sample rates for ADC in MHz */ - int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195, - 196, 204, 205, 206, 207 - }; - /* in MHz */ - int if_limit_high; - int if_limit_low; - int lnb_lo; - int lnb_uncertanity; - - int rf_freq; - int data_rate; - unsigned char regs[4]; - - dprintk("%s : FE_SET_FRONTEND\n", __func__); - - if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) - inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE; - - if_limit_high = -700000; - if_limit_low = -100000; - /* in MHz */ - lnb_lo = 0; - lnb_uncertanity = 0; - - rf_freq = 10 * c->frequency ; - data_rate = c->symbol_rate / 100; - - status = PASS; - - band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200) - + (data_rate * 135)) / 200; - - band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200) - + (data_rate * 135)) / 200; - - - icoarse_tune_freq = 100000 * - (((rf_freq - lnb_lo) - - (if_limit_low + if_limit_high) / 2) - / 100000); - - ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ; - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) * - (afs[i] * 2500) + afs[i] * 2500; - - x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) * - (afs[i] * 2500); - - if (((band_low < x1) && (x1 < band_high)) || - ((band_low < x2) && (x2 < band_high))) - inband_interferer_div4[i] = TRUE; - - } - - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) * - (afs[i] * 5000) + afs[i] * 5000; - - x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) * - (afs[i] * 5000); - - if (((band_low < x1) && (x1 < band_high)) || - ((band_low < x2) && (x2 < band_high))) - inband_interferer_div2[i] = TRUE; - } - - inband_interferer_ind = TRUE; - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) - inband_interferer_ind &= inband_interferer_div2[i] | - inband_interferer_div4[i]; - - if (inband_interferer_ind) { - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - if (inband_interferer_div2[i] == FALSE) { - sample_rate = (u8) afs[i]; - break; - } - } - } else { - for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) { - if ((inband_interferer_div2[i] | - inband_interferer_div4[i]) == FALSE) { - sample_rate = (u8) afs[i]; - break; - } - } - - } - - if (sample_rate > 207 || sample_rate < 192) - sample_rate = 200; - - fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) / - ((sample_rate) * 1000)); - - coarse_tune_freq = (u8)(icoarse_tune_freq / 100000); - - regs[0] = sample_rate; - regs[1] = coarse_tune_freq; - regs[2] = fine_tune_freq & 0xFF; - regs[3] = fine_tune_freq >> 8 & 0xFF; - - status |= si21_writeregs(state, PLL_DIVISOR_REG, ®s[0], 0x04); - - state->fs = sample_rate;/*ADC MHz*/ - si21xx_setacquire(fe, c->symbol_rate, c->fec_inner); - - return 0; -} - -static int si21xx_sleep(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - u8 regdata; - - dprintk("%s\n", __func__); - - si21_readregs(state, SYSTEM_MODE_REG, ®data, 0x01); - regdata |= 1 << 6; - si21_writeregs(state, SYSTEM_MODE_REG, ®data, 0x01); - state->initialised = 0; - - return 0; -} - -static void si21xx_release(struct dvb_frontend *fe) -{ - struct si21xx_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - kfree(state); -} - -static struct dvb_frontend_ops si21xx_ops = { - - .info = { - .name = "SL SI21XX DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO - }, - - .release = si21xx_release, - .init = si21xx_init, - .sleep = si21xx_sleep, - .write = si21_write, - .read_status = si21_read_status, - .read_ber = si21_read_ber, - .read_signal_strength = si21_read_signal_strength, - .read_snr = si21_read_snr, - .read_ucblocks = si21_read_ucblocks, - .diseqc_send_master_cmd = si21xx_send_diseqc_msg, - .diseqc_send_burst = si21xx_send_diseqc_burst, - .set_tone = si21xx_set_tone, - .set_voltage = si21xx_set_voltage, - - .set_property = si21xx_set_property, - .get_property = si21xx_get_property, - .set_frontend = si21xx_set_frontend, -}; - -struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, - struct i2c_adapter *i2c) -{ - struct si21xx_state *state = NULL; - int id; - - dprintk("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->errmode = STATUS_BER; - - /* check if the demod is there */ - id = si21_readreg(state, SYSTEM_MODE_REG); - si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */ - msleep(200); - id = si21_readreg(state, 0x00); - - /* register 0x00 contains: - 0x34 for SI2107 - 0x24 for SI2108 - 0x14 for SI2109 - 0x04 for SI2110 - */ - if (id != 0x04 && id != 0x14) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &si21xx_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(si21xx_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver"); -MODULE_AUTHOR("Igor M. Liplianin"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb/frontends/si21xx.h deleted file mode 100644 index 141b5b8a5f6..00000000000 --- a/drivers/media/dvb/frontends/si21xx.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef SI21XX_H -#define SI21XX_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -struct si21xx_config { - /* the demodulator's i2c address */ - u8 demod_address; - - /* minimum delay before retuning */ - int min_delay_ms; -}; - -#if defined(CONFIG_DVB_SI21XX) || \ - (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE)) -extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *si21xx_attach( - const struct si21xx_config *config, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - -static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val) -{ - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c deleted file mode 100644 index 1c9a9b4051b..00000000000 --- a/drivers/media/dvb/frontends/sp8870.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - Driver for Spase SP8870 demodulator - - Copyright (C) 1999 Juergen Peitz - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ -/* - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "sp8870.h" - - -struct sp8870_state { - - struct i2c_adapter* i2c; - - const struct sp8870_config* config; - - struct dvb_frontend frontend; - - /* demodulator private data */ - u8 initialised:1; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "sp8870: " args); \ - } while (0) - -/* firmware size for sp8870 */ -#define SP8870_FIRMWARE_SIZE 16382 - -/* starting point for firmware in file 'Sc_main.mc' */ -#define SP8870_FIRMWARE_OFFSET 0x0A - -static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data) -{ - u8 buf [] = { reg >> 8, reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 4 }; - int err; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static int sp8870_readreg (struct sp8870_state* state, u16 reg) -{ - int ret; - u8 b0 [] = { reg >> 8 , reg & 0xff }; - u8 b1 [] = { 0, 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) { - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - return -1; - } - - return (b1[0] << 8 | b1[1]); -} - -static int sp8870_firmware_upload (struct sp8870_state* state, const struct firmware *fw) -{ - struct i2c_msg msg; - const char *fw_buf = fw->data; - int fw_pos; - u8 tx_buf[255]; - int tx_len; - int err = 0; - - dprintk ("%s: ...\n", __func__); - - if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET) - return -EINVAL; - - // system controller stop - sp8870_writereg(state, 0x0F00, 0x0000); - - // instruction RAM register hiword - sp8870_writereg(state, 0x8F08, ((SP8870_FIRMWARE_SIZE / 2) & 0xFFFF)); - - // instruction RAM MWR - sp8870_writereg(state, 0x8F0A, ((SP8870_FIRMWARE_SIZE / 2) >> 16)); - - // do firmware upload - fw_pos = SP8870_FIRMWARE_OFFSET; - while (fw_pos < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET){ - tx_len = (fw_pos <= SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - 252) ? 252 : SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET - fw_pos; - // write register 0xCF0A - tx_buf[0] = 0xCF; - tx_buf[1] = 0x0A; - memcpy(&tx_buf[2], fw_buf + fw_pos, tx_len); - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = tx_buf; - msg.len = tx_len + 2; - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk("%s: firmware upload failed!\n", __func__); - printk ("%s: i2c error (err == %i)\n", __func__, err); - return err; - } - fw_pos += tx_len; - } - - dprintk ("%s: done!\n", __func__); - return 0; -}; - -static void sp8870_microcontroller_stop (struct sp8870_state* state) -{ - sp8870_writereg(state, 0x0F08, 0x000); - sp8870_writereg(state, 0x0F09, 0x000); - - // microcontroller STOP - sp8870_writereg(state, 0x0F00, 0x000); -} - -static void sp8870_microcontroller_start (struct sp8870_state* state) -{ - sp8870_writereg(state, 0x0F08, 0x000); - sp8870_writereg(state, 0x0F09, 0x000); - - // microcontroller START - sp8870_writereg(state, 0x0F00, 0x001); - // not documented but if we don't read 0x0D01 out here - // we don't get a correct data valid signal - sp8870_readreg(state, 0x0D01); -} - -static int sp8870_read_data_valid_signal(struct sp8870_state* state) -{ - return (sp8870_readreg(state, 0x0D02) > 0); -} - -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) -{ - int known_parameters = 1; - - *reg0xc05 = 0x000; - - switch (p->u.ofdm.constellation) { - case QPSK: - break; - case QAM_16: - *reg0xc05 |= (1 << 10); - break; - case QAM_64: - *reg0xc05 |= (2 << 10); - break; - case QAM_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - *reg0xc05 |= (1 << 7); - break; - case HIERARCHY_2: - *reg0xc05 |= (2 << 7); - break; - case HIERARCHY_4: - *reg0xc05 |= (3 << 7); - break; - case HIERARCHY_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.code_rate_HP) { - case FEC_1_2: - break; - case FEC_2_3: - *reg0xc05 |= (1 << 3); - break; - case FEC_3_4: - *reg0xc05 |= (2 << 3); - break; - case FEC_5_6: - *reg0xc05 |= (3 << 3); - break; - case FEC_7_8: - *reg0xc05 |= (4 << 3); - break; - case FEC_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - if (known_parameters) - *reg0xc05 |= (2 << 1); /* use specified parameters */ - else - *reg0xc05 |= (1 << 1); /* enable autoprobing */ - - return 0; -} - -static int sp8870_wake_up(struct sp8870_state* state) -{ - // enable TS output and interface pins - return sp8870_writereg(state, 0xC18, 0x00D); -} - -static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct sp8870_state* state = fe->demodulator_priv; - int err; - u16 reg0xc05; - - if ((err = configure_reg0xc05(p, ®0xc05))) - return err; - - // system controller stop - sp8870_microcontroller_stop(state); - - // set tuner parameters - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - // sample rate correction bit [23..17] - sp8870_writereg(state, 0x0319, 0x000A); - - // sample rate correction bit [16..0] - sp8870_writereg(state, 0x031A, 0x0AAB); - - // integer carrier offset - sp8870_writereg(state, 0x0309, 0x0400); - - // fractional carrier offset - sp8870_writereg(state, 0x030A, 0x0000); - - // filter for 6/7/8 Mhz channel - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - sp8870_writereg(state, 0x0311, 0x0002); - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - sp8870_writereg(state, 0x0311, 0x0001); - else - sp8870_writereg(state, 0x0311, 0x0000); - - // scan order: 2k first = 0x0000, 8k first = 0x0001 - if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K) - sp8870_writereg(state, 0x0338, 0x0000); - else - sp8870_writereg(state, 0x0338, 0x0001); - - sp8870_writereg(state, 0xc05, reg0xc05); - - // read status reg in order to clear pending irqs - sp8870_readreg(state, 0x200); - - // system controller start - sp8870_microcontroller_start(state); - - return 0; -} - -static int sp8870_init (struct dvb_frontend* fe) -{ - struct sp8870_state* state = fe->demodulator_priv; - const struct firmware *fw = NULL; - - sp8870_wake_up(state); - if (state->initialised) return 0; - state->initialised = 1; - - dprintk ("%s\n", __func__); - - - /* request the firmware, this will block until someone uploads it */ - printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); - if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) { - printk("sp8870: no firmware upload (timeout or file not found?)\n"); - return -EIO; - } - - if (sp8870_firmware_upload(state, fw)) { - printk("sp8870: writing firmware to device failed\n"); - release_firmware(fw); - return -EIO; - } - release_firmware(fw); - printk("sp8870: firmware upload complete\n"); - - /* enable TS output and interface pins */ - sp8870_writereg(state, 0xc18, 0x00d); - - // system controller stop - sp8870_microcontroller_stop(state); - - // ADC mode - sp8870_writereg(state, 0x0301, 0x0003); - - // Reed Solomon parity bytes passed to output - sp8870_writereg(state, 0x0C13, 0x0001); - - // MPEG clock is suppressed if no valid data - sp8870_writereg(state, 0x0C14, 0x0001); - - /* bit 0x010: enable data valid signal */ - sp8870_writereg(state, 0x0D00, 0x010); - sp8870_writereg(state, 0x0D01, 0x000); - - return 0; -} - -static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status) -{ - struct sp8870_state* state = fe->demodulator_priv; - int status; - int signal; - - *fe_status = 0; - - status = sp8870_readreg (state, 0x0200); - if (status < 0) - return -EIO; - - signal = sp8870_readreg (state, 0x0303); - if (signal < 0) - return -EIO; - - if (signal > 0x0F) - *fe_status |= FE_HAS_SIGNAL; - if (status & 0x08) - *fe_status |= FE_HAS_SYNC; - if (status & 0x04) - *fe_status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_VITERBI; - - return 0; -} - -static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) -{ - struct sp8870_state* state = fe->demodulator_priv; - int ret; - u32 tmp; - - *ber = 0; - - ret = sp8870_readreg(state, 0xC08); - if (ret < 0) - return -EIO; - - tmp = ret & 0x3F; - - ret = sp8870_readreg(state, 0xC07); - if (ret < 0) - return -EIO; - - tmp = ret << 6; - - if (tmp >= 0x3FFF0) - tmp = ~0; - - *ber = tmp; - - return 0; -} - -static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) -{ - struct sp8870_state* state = fe->demodulator_priv; - int ret; - u16 tmp; - - *signal = 0; - - ret = sp8870_readreg (state, 0x306); - if (ret < 0) - return -EIO; - - tmp = ret << 8; - - ret = sp8870_readreg (state, 0x303); - if (ret < 0) - return -EIO; - - tmp |= ret; - - if (tmp) - *signal = 0xFFFF - tmp; - - return 0; -} - -static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks) -{ - struct sp8870_state* state = fe->demodulator_priv; - int ret; - - *ublocks = 0; - - ret = sp8870_readreg(state, 0xC0C); - if (ret < 0) - return -EIO; - - if (ret == 0xFFFF) - ret = ~0; - - *ublocks = ret; - - return 0; -} - -/* number of trials to recover from lockup */ -#define MAXTRIALS 5 -/* maximum checks for data valid signal */ -#define MAXCHECKS 100 - -/* only for debugging: counter for detected lockups */ -static int lockups; -/* only for debugging: counter for channel switches */ -static int switches; - -static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct sp8870_state* state = fe->demodulator_priv; - - /* - The firmware of the sp8870 sometimes locks up after setting frontend parameters. - We try to detect this by checking the data valid signal. - If it is not set after MAXCHECKS we try to recover the lockup by setting - the frontend parameters again. - */ - - int err = 0; - int valid = 0; - int trials = 0; - int check_count = 0; - - dprintk("%s: frequency = %i\n", __func__, p->frequency); - - for (trials = 1; trials <= MAXTRIALS; trials++) { - - if ((err = sp8870_set_frontend_parameters(fe, p))) - return err; - - for (check_count = 0; check_count < MAXCHECKS; check_count++) { -// valid = ((sp8870_readreg(i2c, 0x0200) & 4) == 0); - valid = sp8870_read_data_valid_signal(state); - if (valid) { - dprintk("%s: delay = %i usec\n", - __func__, check_count * 10); - break; - } - udelay(10); - } - if (valid) - break; - } - - if (!valid) { - printk("%s: firmware crash!!!!!!\n", __func__); - return -EIO; - } - - if (debug) { - if (valid) { - if (trials > 1) { - printk("%s: firmware lockup!!!\n", __func__); - printk("%s: recovered after %i trial(s))\n", __func__, trials - 1); - lockups++; - } - } - switches++; - printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups); - } - - return 0; -} - -static int sp8870_sleep(struct dvb_frontend* fe) -{ - struct sp8870_state* state = fe->demodulator_priv; - - // tristate TS output and disable interface pins - return sp8870_writereg(state, 0xC18, 0x000); -} - -static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 350; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static int sp8870_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct sp8870_state* state = fe->demodulator_priv; - - if (enable) { - return sp8870_writereg(state, 0x206, 0x001); - } else { - return sp8870_writereg(state, 0x206, 0x000); - } -} - -static void sp8870_release(struct dvb_frontend* fe) -{ - struct sp8870_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops sp8870_ops; - -struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c) -{ - struct sp8870_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - - /* check if the demod is there */ - if (sp8870_readreg(state, 0x0200) < 0) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &sp8870_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops sp8870_ops = { - - .info = { - .name = "Spase SP8870 DVB-T", - .type = FE_OFDM, - .frequency_min = 470000000, - .frequency_max = 860000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | - FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER - }, - - .release = sp8870_release, - - .init = sp8870_init, - .sleep = sp8870_sleep, - .i2c_gate_ctrl = sp8870_i2c_gate_ctrl, - - .set_frontend = sp8870_set_frontend, - .get_tune_settings = sp8870_get_tune_settings, - - .read_status = sp8870_read_status, - .read_ber = sp8870_read_ber, - .read_signal_strength = sp8870_read_signal_strength, - .read_ucblocks = sp8870_read_uncorrected_blocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Spase SP8870 DVB-T Demodulator driver"); -MODULE_AUTHOR("Juergen Peitz"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(sp8870_attach); diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h deleted file mode 100644 index a764a793c7d..00000000000 --- a/drivers/media/dvb/frontends/sp8870.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Driver for Spase SP8870 demodulator - - Copyright (C) 1999 Juergen Peitz - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef SP8870_H -#define SP8870_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct sp8870_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -#if defined(CONFIG_DVB_SP8870) || (defined(CONFIG_DVB_SP8870_MODULE) && defined(MODULE)) -extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_SP8870 - -#endif // SP8870_H diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c deleted file mode 100644 index 559509ab4da..00000000000 --- a/drivers/media/dvb/frontends/sp887x.c +++ /dev/null @@ -1,617 +0,0 @@ -/* - Driver for the Spase sp887x demodulator -*/ - -/* - * This driver needs external firmware. Please use the command - * "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "sp887x.h" - - -struct sp887x_state { - struct i2c_adapter* i2c; - const struct sp887x_config* config; - struct dvb_frontend frontend; - - /* demodulator private data */ - u8 initialised:1; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "sp887x: " args); \ - } while (0) - -static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len) -{ - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = len }; - int err; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - printk ("%s: i2c write error (addr %02x, err == %i)\n", - __func__, state->config->demod_address, err); - return -EREMOTEIO; - } - - return 0; -} - -static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data) -{ - u8 b0 [] = { reg >> 8 , reg & 0xff, data >> 8, data & 0xff }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 4 }; - int ret; - - if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) { - /** - * in case of soft reset we ignore ACK errors... - */ - if (!(reg == 0xf1a && data == 0x000 && - (ret == -EREMOTEIO || ret == -EFAULT))) - { - printk("%s: writereg error " - "(reg %03x, data %03x, ret == %i)\n", - __func__, reg & 0xffff, data & 0xffff, ret); - return ret; - } - } - - return 0; -} - -static int sp887x_readreg (struct sp887x_state* state, u16 reg) -{ - u8 b0 [] = { reg >> 8 , reg & 0xff }; - u8 b1 [2]; - int ret; - struct i2c_msg msg[] = {{ .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }}; - - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - printk("%s: readreg error (ret == %i)\n", __func__, ret); - return -1; - } - - return (((b1[0] << 8) | b1[1]) & 0xfff); -} - -static void sp887x_microcontroller_stop (struct sp887x_state* state) -{ - dprintk("%s\n", __func__); - sp887x_writereg(state, 0xf08, 0x000); - sp887x_writereg(state, 0xf09, 0x000); - - /* microcontroller STOP */ - sp887x_writereg(state, 0xf00, 0x000); -} - -static void sp887x_microcontroller_start (struct sp887x_state* state) -{ - dprintk("%s\n", __func__); - sp887x_writereg(state, 0xf08, 0x000); - sp887x_writereg(state, 0xf09, 0x000); - - /* microcontroller START */ - sp887x_writereg(state, 0xf00, 0x001); -} - -static void sp887x_setup_agc (struct sp887x_state* state) -{ - /* setup AGC parameters */ - dprintk("%s\n", __func__); - sp887x_writereg(state, 0x33c, 0x054); - sp887x_writereg(state, 0x33b, 0x04c); - sp887x_writereg(state, 0x328, 0x000); - sp887x_writereg(state, 0x327, 0x005); - sp887x_writereg(state, 0x326, 0x001); - sp887x_writereg(state, 0x325, 0x001); - sp887x_writereg(state, 0x324, 0x001); - sp887x_writereg(state, 0x318, 0x050); - sp887x_writereg(state, 0x317, 0x3fe); - sp887x_writereg(state, 0x316, 0x001); - sp887x_writereg(state, 0x313, 0x005); - sp887x_writereg(state, 0x312, 0x002); - sp887x_writereg(state, 0x306, 0x000); - sp887x_writereg(state, 0x303, 0x000); -} - -#define BLOCKSIZE 30 -#define FW_SIZE 0x4000 -/** - * load firmware and setup MPEG interface... - */ -static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw) -{ - struct sp887x_state* state = fe->demodulator_priv; - u8 buf [BLOCKSIZE+2]; - int i; - int fw_size = fw->size; - const unsigned char *mem = fw->data; - - dprintk("%s\n", __func__); - - /* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */ - if (fw_size < FW_SIZE+10) - return -ENODEV; - - mem = fw->data + 10; - - /* soft reset */ - sp887x_writereg(state, 0xf1a, 0x000); - - sp887x_microcontroller_stop (state); - - printk ("%s: firmware upload... ", __func__); - - /* setup write pointer to -1 (end of memory) */ - /* bit 0x8000 in address is set to enable 13bit mode */ - sp887x_writereg(state, 0x8f08, 0x1fff); - - /* dummy write (wrap around to start of memory) */ - sp887x_writereg(state, 0x8f0a, 0x0000); - - for (i = 0; i < FW_SIZE; i += BLOCKSIZE) { - int c = BLOCKSIZE; - int err; - - if (i+c > FW_SIZE) - c = FW_SIZE - i; - - /* bit 0x8000 in address is set to enable 13bit mode */ - /* bit 0x4000 enables multibyte read/write transfers */ - /* write register is 0xf0a */ - buf[0] = 0xcf; - buf[1] = 0x0a; - - memcpy(&buf[2], mem + i, c); - - if ((err = i2c_writebytes (state, buf, c+2)) < 0) { - printk ("failed.\n"); - printk ("%s: i2c error (err == %i)\n", __func__, err); - return err; - } - } - - /* don't write RS bytes between packets */ - sp887x_writereg(state, 0xc13, 0x001); - - /* suppress clock if (!data_valid) */ - sp887x_writereg(state, 0xc14, 0x000); - - /* setup MPEG interface... */ - sp887x_writereg(state, 0xc1a, 0x872); - sp887x_writereg(state, 0xc1b, 0x001); - sp887x_writereg(state, 0xc1c, 0x000); /* parallel mode (serial mode == 1) */ - sp887x_writereg(state, 0xc1a, 0x871); - - /* ADC mode, 2 for MT8872, 3 for SP8870/SP8871 */ - sp887x_writereg(state, 0x301, 0x002); - - sp887x_setup_agc(state); - - /* bit 0x010: enable data valid signal */ - sp887x_writereg(state, 0xd00, 0x010); - sp887x_writereg(state, 0x0d1, 0x000); - return 0; -}; - -static int configure_reg0xc05 (struct dvb_frontend_parameters *p, u16 *reg0xc05) -{ - int known_parameters = 1; - - *reg0xc05 = 0x000; - - switch (p->u.ofdm.constellation) { - case QPSK: - break; - case QAM_16: - *reg0xc05 |= (1 << 10); - break; - case QAM_64: - *reg0xc05 |= (2 << 10); - break; - case QAM_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - *reg0xc05 |= (1 << 7); - break; - case HIERARCHY_2: - *reg0xc05 |= (2 << 7); - break; - case HIERARCHY_4: - *reg0xc05 |= (3 << 7); - break; - case HIERARCHY_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - switch (p->u.ofdm.code_rate_HP) { - case FEC_1_2: - break; - case FEC_2_3: - *reg0xc05 |= (1 << 3); - break; - case FEC_3_4: - *reg0xc05 |= (2 << 3); - break; - case FEC_5_6: - *reg0xc05 |= (3 << 3); - break; - case FEC_7_8: - *reg0xc05 |= (4 << 3); - break; - case FEC_AUTO: - known_parameters = 0; - break; - default: - return -EINVAL; - }; - - if (known_parameters) - *reg0xc05 |= (2 << 1); /* use specified parameters */ - else - *reg0xc05 |= (1 << 1); /* enable autoprobing */ - - return 0; -} - -/** - * estimates division of two 24bit numbers, - * derived from the ves1820/stv0299 driver code - */ -static void divide (int n, int d, int *quotient_i, int *quotient_f) -{ - unsigned int q, r; - - r = (n % d) << 8; - q = (r / d); - - if (quotient_i) - *quotient_i = q; - - if (quotient_f) { - r = (r % d) << 8; - q = (q << 8) | (r / d); - r = (r % d) << 8; - *quotient_f = (q << 8) | (r / d); - } -} - -static void sp887x_correct_offsets (struct sp887x_state* state, - struct dvb_frontend_parameters *p, - int actual_freq) -{ - static const u32 srate_correction [] = { 1879617, 4544878, 8098561 }; - int bw_index = p->u.ofdm.bandwidth - BANDWIDTH_8_MHZ; - int freq_offset = actual_freq - p->frequency; - int sysclock = 61003; //[kHz] - int ifreq = 36000000; - int freq; - int frequency_shift; - - if (p->inversion == INVERSION_ON) - freq = ifreq - freq_offset; - else - freq = ifreq + freq_offset; - - divide(freq / 333, sysclock, NULL, &frequency_shift); - - if (p->inversion == INVERSION_ON) - frequency_shift = -frequency_shift; - - /* sample rate correction */ - sp887x_writereg(state, 0x319, srate_correction[bw_index] >> 12); - sp887x_writereg(state, 0x31a, srate_correction[bw_index] & 0xfff); - - /* carrier offset correction */ - sp887x_writereg(state, 0x309, frequency_shift >> 12); - sp887x_writereg(state, 0x30a, frequency_shift & 0xfff); -} - -static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, - struct dvb_frontend_parameters *p) -{ - struct sp887x_state* state = fe->demodulator_priv; - unsigned actual_freq; - int err; - u16 val, reg0xc05; - - if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ && - p->u.ofdm.bandwidth != BANDWIDTH_7_MHZ && - p->u.ofdm.bandwidth != BANDWIDTH_6_MHZ) - return -EINVAL; - - if ((err = configure_reg0xc05(p, ®0xc05))) - return err; - - sp887x_microcontroller_stop(state); - - /* setup the PLL */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - if (fe->ops.tuner_ops.get_frequency) { - fe->ops.tuner_ops.get_frequency(fe, &actual_freq); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } else { - actual_freq = p->frequency; - } - - /* read status reg in order to clear <pending irqs */ - sp887x_readreg(state, 0x200); - - sp887x_correct_offsets(state, p, actual_freq); - - /* filter for 6/7/8 Mhz channel */ - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - val = 2; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - val = 1; - else - val = 0; - - sp887x_writereg(state, 0x311, val); - - /* scan order: 2k first = 0, 8k first = 1 */ - if (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_2K) - sp887x_writereg(state, 0x338, 0x000); - else - sp887x_writereg(state, 0x338, 0x001); - - sp887x_writereg(state, 0xc05, reg0xc05); - - if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) - val = 2 << 3; - else if (p->u.ofdm.bandwidth == BANDWIDTH_7_MHZ) - val = 3 << 3; - else - val = 0 << 3; - - /* enable OFDM and SAW bits as lock indicators in sync register 0xf17, - * optimize algorithm for given bandwidth... - */ - sp887x_writereg(state, 0xf14, 0x160 | val); - sp887x_writereg(state, 0xf15, 0x000); - - sp887x_microcontroller_start(state); - return 0; -} - -static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct sp887x_state* state = fe->demodulator_priv; - u16 snr12 = sp887x_readreg(state, 0xf16); - u16 sync0x200 = sp887x_readreg(state, 0x200); - u16 sync0xf17 = sp887x_readreg(state, 0xf17); - - *status = 0; - - if (snr12 > 0x00f) - *status |= FE_HAS_SIGNAL; - - //if (sync0x200 & 0x004) - // *status |= FE_HAS_SYNC | FE_HAS_CARRIER; - - //if (sync0x200 & 0x008) - // *status |= FE_HAS_VITERBI; - - if ((sync0xf17 & 0x00f) == 0x002) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER; - } - - if (sync0x200 & 0x001) { /* tuner adjustment requested...*/ - int steps = (sync0x200 >> 4) & 0x00f; - if (steps & 0x008) - steps = -steps; - dprintk("sp887x: implement tuner adjustment (%+i steps)!!\n", - steps); - } - - return 0; -} - -static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct sp887x_state* state = fe->demodulator_priv; - - *ber = (sp887x_readreg(state, 0xc08) & 0x3f) | - (sp887x_readreg(state, 0xc07) << 6); - sp887x_writereg(state, 0xc08, 0x000); - sp887x_writereg(state, 0xc07, 0x000); - if (*ber >= 0x3fff0) - *ber = ~0; - - return 0; -} - -static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct sp887x_state* state = fe->demodulator_priv; - - u16 snr12 = sp887x_readreg(state, 0xf16); - u32 signal = 3 * (snr12 << 4); - *strength = (signal < 0xffff) ? signal : 0xffff; - - return 0; -} - -static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct sp887x_state* state = fe->demodulator_priv; - - u16 snr12 = sp887x_readreg(state, 0xf16); - *snr = (snr12 << 4) | (snr12 >> 8); - - return 0; -} - -static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct sp887x_state* state = fe->demodulator_priv; - - *ucblocks = sp887x_readreg(state, 0xc0c); - if (*ucblocks == 0xfff) - *ucblocks = ~0; - - return 0; -} - -static int sp887x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct sp887x_state* state = fe->demodulator_priv; - - if (enable) { - return sp887x_writereg(state, 0x206, 0x001); - } else { - return sp887x_writereg(state, 0x206, 0x000); - } -} - -static int sp887x_sleep(struct dvb_frontend* fe) -{ - struct sp887x_state* state = fe->demodulator_priv; - - /* tristate TS output and disable interface pins */ - sp887x_writereg(state, 0xc18, 0x000); - - return 0; -} - -static int sp887x_init(struct dvb_frontend* fe) -{ - struct sp887x_state* state = fe->demodulator_priv; - const struct firmware *fw = NULL; - int ret; - - if (!state->initialised) { - /* request the firmware, this will block until someone uploads it */ - printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE); - ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE); - if (ret) { - printk("sp887x: no firmware upload (timeout or file not found?)\n"); - return ret; - } - - ret = sp887x_initial_setup(fe, fw); - release_firmware(fw); - if (ret) { - printk("sp887x: writing firmware to device failed\n"); - return ret; - } - printk("sp887x: firmware upload complete\n"); - state->initialised = 1; - } - - /* enable TS output and interface pins */ - sp887x_writereg(state, 0xc18, 0x00d); - - return 0; -} - -static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 350; - fesettings->step_size = 166666*2; - fesettings->max_drift = (166666*2)+1; - return 0; -} - -static void sp887x_release(struct dvb_frontend* fe) -{ - struct sp887x_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops sp887x_ops; - -struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c) -{ - struct sp887x_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct sp887x_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - - /* check if the demod is there */ - if (sp887x_readreg(state, 0x0200) < 0) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &sp887x_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops sp887x_ops = { - - .info = { - .name = "Spase SP887x DVB-T", - .type = FE_OFDM, - .frequency_min = 50500000, - .frequency_max = 858000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_RECOVER - }, - - .release = sp887x_release, - - .init = sp887x_init, - .sleep = sp887x_sleep, - .i2c_gate_ctrl = sp887x_i2c_gate_ctrl, - - .set_frontend = sp887x_setup_frontend_parameters, - .get_tune_settings = sp887x_get_tune_settings, - - .read_status = sp887x_read_status, - .read_ber = sp887x_read_ber, - .read_signal_strength = sp887x_read_signal_strength, - .read_snr = sp887x_read_snr, - .read_ucblocks = sp887x_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(sp887x_attach); diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h deleted file mode 100644 index 04eff6e0eef..00000000000 --- a/drivers/media/dvb/frontends/sp887x.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Driver for the Spase sp887x demodulator -*/ - -#ifndef SP887X_H -#define SP887X_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct sp887x_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -#if defined(CONFIG_DVB_SP887X) || (defined(CONFIG_DVB_SP887X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_SP887X - -#endif // SP887X_H diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c deleted file mode 100644 index 83dc7e12d5f..00000000000 --- a/drivers/media/dvb/frontends/stb0899_algo.c +++ /dev/null @@ -1,1519 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "stb0899_drv.h" -#include "stb0899_priv.h" -#include "stb0899_reg.h" - -inline u32 stb0899_do_div(u64 n, u32 d) -{ - /* wrap do_div() for ease of use */ - - do_div(n, d); - return n; -} - -/* - * stb0899_calc_srate - * Compute symbol rate - */ -static u32 stb0899_calc_srate(u32 master_clk, u8 *sfr) -{ - u64 tmp; - - /* srate = (SFR * master_clk) >> 20 */ - - /* sfr is of size 20 bit, stored with an offset of 4 bit */ - tmp = (((u32)sfr[0]) << 16) | (((u32)sfr[1]) << 8) | sfr[2]; - tmp &= ~0xf; - tmp *= master_clk; - tmp >>= 24; - - return tmp; -} - -/* - * stb0899_get_srate - * Get the current symbol rate - */ -static u32 stb0899_get_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - u8 sfr[3]; - - stb0899_read_regs(state, STB0899_SFRH, sfr, 3); - - return stb0899_calc_srate(internal->master_clk, sfr); -} - -/* - * stb0899_set_srate - * Set symbol frequency - * MasterClock: master clock frequency (hz) - * SymbolRate: symbol rate (bauds) - * return symbol frequency - */ -static u32 stb0899_set_srate(struct stb0899_state *state, u32 master_clk, u32 srate) -{ - u32 tmp; - u8 sfr[3]; - - dprintk(state->verbose, FE_DEBUG, 1, "-->"); - /* - * in order to have the maximum precision, the symbol rate entered into - * the chip is computed as the closest value of the "true value". - * In this purpose, the symbol rate value is rounded (1 is added on the bit - * below the LSB ) - * - * srate = (SFR * master_clk) >> 20 - * <=> - * SFR = srate << 20 / master_clk - * - * rounded: - * SFR = (srate << 21 + master_clk) / (2 * master_clk) - * - * stored as 20 bit number with an offset of 4 bit: - * sfr = SFR << 4; - */ - - tmp = stb0899_do_div((((u64)srate) << 21) + master_clk, 2 * master_clk); - tmp <<= 4; - - sfr[0] = tmp >> 16; - sfr[1] = tmp >> 8; - sfr[2] = tmp; - - stb0899_write_regs(state, STB0899_SFRH, sfr, 3); - - return srate; -} - -/* - * stb0899_calc_derot_time - * Compute the amount of time needed by the derotator to lock - * SymbolRate: Symbol rate - * return: derotator time constant (ms) - */ -static long stb0899_calc_derot_time(long srate) -{ - if (srate > 0) - return (100000 / (srate / 1000)); - else - return 0; -} - -/* - * stb0899_carr_width - * Compute the width of the carrier - * return: width of carrier (kHz or Mhz) - */ -long stb0899_carr_width(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - - return (internal->srate + (internal->srate * internal->rolloff) / 100); -} - -/* - * stb0899_first_subrange - * Compute the first subrange of the search - */ -static void stb0899_first_subrange(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - struct stb0899_config *config = state->config; - - int range = 0; - u32 bandwidth = 0; - - if (config->tuner_get_bandwidth) { - stb0899_i2c_gate_ctrl(&state->frontend, 1); - config->tuner_get_bandwidth(&state->frontend, &bandwidth); - stb0899_i2c_gate_ctrl(&state->frontend, 0); - range = bandwidth - stb0899_carr_width(state) / 2; - } - - if (range > 0) - internal->sub_range = MIN(internal->srch_range, range); - else - internal->sub_range = 0; - - internal->freq = params->freq; - internal->tuner_offst = 0L; - internal->sub_dir = 1; -} - -/* - * stb0899_check_tmg - * check for timing lock - * internal.Ttiming: time to wait for loop lock - */ -static enum stb0899_status stb0899_check_tmg(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - int lock; - u8 reg; - s8 timing; - - msleep(internal->t_derot); - - stb0899_write_reg(state, STB0899_RTF, 0xf2); - reg = stb0899_read_reg(state, STB0899_TLIR); - lock = STB0899_GETFIELD(TLIR_TMG_LOCK_IND, reg); - timing = stb0899_read_reg(state, STB0899_RTF); - - if (lock >= 42) { - if ((lock > 48) && (ABS(timing) >= 110)) { - internal->status = ANALOGCARRIER; - dprintk(state->verbose, FE_DEBUG, 1, "-->ANALOG Carrier !"); - } else { - internal->status = TIMINGOK; - dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK !"); - } - } else { - internal->status = NOTIMING; - dprintk(state->verbose, FE_DEBUG, 1, "-->NO TIMING !"); - } - return internal->status; -} - -/* - * stb0899_search_tmg - * perform a fs/2 zig-zag to find timing - */ -static enum stb0899_status stb0899_search_tmg(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - short int derot_step, derot_freq = 0, derot_limit, next_loop = 3; - int index = 0; - u8 cfr[2]; - - internal->status = NOTIMING; - - /* timing loop computation & symbol rate optimisation */ - derot_limit = (internal->sub_range / 2L) / internal->mclk; - derot_step = (params->srate / 2L) / internal->mclk; - - while ((stb0899_check_tmg(state) != TIMINGOK) && next_loop) { - index++; - derot_freq += index * internal->direction * derot_step; /* next derot zig zag position */ - - if (ABS(derot_freq) > derot_limit) - next_loop--; - - if (next_loop) { - STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq)); - STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ - } - internal->direction = -internal->direction; /* Change zigzag direction */ - } - - if (internal->status == TIMINGOK) { - stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */ - internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]); - dprintk(state->verbose, FE_DEBUG, 1, "------->TIMING OK ! Derot Freq = %d", internal->derot_freq); - } - - return internal->status; -} - -/* - * stb0899_check_carrier - * Check for carrier found - */ -static enum stb0899_status stb0899_check_carrier(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - u8 reg; - - msleep(internal->t_derot); /* wait for derotator ok */ - - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - reg = stb0899_read_reg(state, STB0899_DSTATUS); - dprintk(state->verbose, FE_DEBUG, 1, "--------------------> STB0899_DSTATUS=[0x%02x]", reg); - if (STB0899_GETFIELD(CARRIER_FOUND, reg)) { - internal->status = CARRIEROK; - dprintk(state->verbose, FE_DEBUG, 1, "-------------> CARRIEROK !"); - } else { - internal->status = NOCARRIER; - dprintk(state->verbose, FE_DEBUG, 1, "-------------> NOCARRIER !"); - } - - return internal->status; -} - -/* - * stb0899_search_carrier - * Search for a QPSK carrier with the derotator - */ -static enum stb0899_status stb0899_search_carrier(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - - short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3; - int index = 0; - u8 cfr[2]; - u8 reg; - - internal->status = NOCARRIER; - derot_limit = (internal->sub_range / 2L) / internal->mclk; - derot_freq = internal->derot_freq; - - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - do { - dprintk(state->verbose, FE_DEBUG, 1, "Derot Freq=%d, mclk=%d", derot_freq, internal->mclk); - if (stb0899_check_carrier(state) == NOCARRIER) { - index++; - last_derot_freq = derot_freq; - derot_freq += index * internal->direction * internal->derot_step; /* next zig zag derotator position */ - - if(ABS(derot_freq) > derot_limit) - next_loop--; - - if (next_loop) { - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq)); - STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ - } - } - - internal->direction = -internal->direction; /* Change zigzag direction */ - } while ((internal->status != CARRIEROK) && next_loop); - - if (internal->status == CARRIEROK) { - stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */ - internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]); - dprintk(state->verbose, FE_DEBUG, 1, "----> CARRIER OK !, Derot Freq=%d", internal->derot_freq); - } else { - internal->derot_freq = last_derot_freq; - } - - return internal->status; -} - -/* - * stb0899_check_data - * Check for data found - */ -static enum stb0899_status stb0899_check_data(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - int lock = 0, index = 0, dataTime = 500, loop; - u8 reg; - - internal->status = NODATA; - - /* RESET FEC */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESACS, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - msleep(1); - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESACS, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - if (params->srate <= 2000000) - dataTime = 2000; - else if (params->srate <= 5000000) - dataTime = 1500; - else if (params->srate <= 15000000) - dataTime = 1000; - else - dataTime = 500; - - stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */ - while (1) { - /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */ - reg = stb0899_read_reg(state, STB0899_VSTATUS); - lock = STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg); - loop = STB0899_GETFIELD(VSTATUS_END_LOOPVIT, reg); - - if (lock || loop || (index > dataTime)) - break; - index++; - } - - if (lock) { /* DATA LOCK indicator */ - internal->status = DATAOK; - dprintk(state->verbose, FE_DEBUG, 1, "-----------------> DATA OK !"); - } - - return internal->status; -} - -/* - * stb0899_search_data - * Search for a QPSK carrier with the derotator - */ -static enum stb0899_status stb0899_search_data(struct stb0899_state *state) -{ - short int derot_freq, derot_step, derot_limit, next_loop = 3; - u8 cfr[2]; - u8 reg; - int index = 1; - - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - derot_step = (params->srate / 4L) / internal->mclk; - derot_limit = (internal->sub_range / 2L) / internal->mclk; - derot_freq = internal->derot_freq; - - do { - if ((internal->status != CARRIEROK) || (stb0899_check_data(state) != DATAOK)) { - - derot_freq += index * internal->direction * derot_step; /* next zig zag derotator position */ - if (ABS(derot_freq) > derot_limit) - next_loop--; - - if (next_loop) { - dprintk(state->verbose, FE_DEBUG, 1, "Derot freq=%d, mclk=%d", derot_freq, internal->mclk); - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - STB0899_SETFIELD_VAL(CFRM, cfr[0], MSB(state->config->inversion * derot_freq)); - STB0899_SETFIELD_VAL(CFRL, cfr[1], LSB(state->config->inversion * derot_freq)); - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* derotator frequency */ - - stb0899_check_carrier(state); - index++; - } - } - internal->direction = -internal->direction; /* change zig zag direction */ - } while ((internal->status != DATAOK) && next_loop); - - if (internal->status == DATAOK) { - stb0899_read_regs(state, STB0899_CFRM, cfr, 2); /* get derotator frequency */ - internal->derot_freq = state->config->inversion * MAKEWORD16(cfr[0], cfr[1]); - dprintk(state->verbose, FE_DEBUG, 1, "------> DATAOK ! Derot Freq=%d", internal->derot_freq); - } - - return internal->status; -} - -/* - * stb0899_check_range - * check if the found frequency is in the correct range - */ -static enum stb0899_status stb0899_check_range(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - int range_offst, tp_freq; - - range_offst = internal->srch_range / 2000; - tp_freq = internal->freq + (internal->derot_freq * internal->mclk) / 1000; - - if ((tp_freq >= params->freq - range_offst) && (tp_freq <= params->freq + range_offst)) { - internal->status = RANGEOK; - dprintk(state->verbose, FE_DEBUG, 1, "----> RANGEOK !"); - } else { - internal->status = OUTOFRANGE; - dprintk(state->verbose, FE_DEBUG, 1, "----> OUT OF RANGE !"); - } - - return internal->status; -} - -/* - * NextSubRange - * Compute the next subrange of the search - */ -static void next_sub_range(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_params *params = &state->params; - - long old_sub_range; - - if (internal->sub_dir > 0) { - old_sub_range = internal->sub_range; - internal->sub_range = MIN((internal->srch_range / 2) - - (internal->tuner_offst + internal->sub_range / 2), - internal->sub_range); - - if (internal->sub_range < 0) - internal->sub_range = 0; - - internal->tuner_offst += (old_sub_range + internal->sub_range) / 2; - } - - internal->freq = params->freq + (internal->sub_dir * internal->tuner_offst) / 1000; - internal->sub_dir = -internal->sub_dir; -} - -/* - * stb0899_dvbs_algo - * Search for a signal, timing, carrier and data for a - * given frequency in a given range - */ -enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state) -{ - struct stb0899_params *params = &state->params; - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u8 bclc, reg; - u8 cfr[2]; - u8 eq_const[10]; - s32 clnI = 3; - u32 bandwidth = 0; - - /* BETA values rated @ 99MHz */ - s32 betaTab[5][4] = { - /* 5 10 20 30MBps */ - { 37, 34, 32, 31 }, /* QPSK 1/2 */ - { 37, 35, 33, 31 }, /* QPSK 2/3 */ - { 37, 35, 33, 31 }, /* QPSK 3/4 */ - { 37, 36, 33, 32 }, /* QPSK 5/6 */ - { 37, 36, 33, 32 } /* QPSK 7/8 */ - }; - - internal->direction = 1; - - stb0899_set_srate(state, internal->master_clk, params->srate); - /* Carrier loop optimization versus symbol rate for acquisition*/ - if (params->srate <= 5000000) { - stb0899_write_reg(state, STB0899_ACLC, 0x89); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x1c); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 0; - } else if (params->srate <= 15000000) { - stb0899_write_reg(state, STB0899_ACLC, 0xc9); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x22); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 1; - } else if(params->srate <= 25000000) { - stb0899_write_reg(state, STB0899_ACLC, 0x89); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x27); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 2; - } else { - stb0899_write_reg(state, STB0899_ACLC, 0xc8); - bclc = stb0899_read_reg(state, STB0899_BCLC); - STB0899_SETFIELD_VAL(BETA, bclc, 0x29); - stb0899_write_reg(state, STB0899_BCLC, bclc); - clnI = 3; - } - - dprintk(state->verbose, FE_DEBUG, 1, "Set the timing loop to acquisition"); - /* Set the timing loop to acquisition */ - stb0899_write_reg(state, STB0899_RTC, 0x46); - stb0899_write_reg(state, STB0899_CFD, 0xee); - - /* !! WARNING !! - * Do not read any status variables while acquisition, - * If any needed, read before the acquisition starts - * querying status while acquiring causes the - * acquisition to go bad and hence no locks. - */ - dprintk(state->verbose, FE_DEBUG, 1, "Derot Percent=%d Srate=%d mclk=%d", - internal->derot_percent, params->srate, internal->mclk); - - /* Initial calculations */ - internal->derot_step = internal->derot_percent * (params->srate / 1000L) / internal->mclk; /* DerotStep/1000 * Fsymbol */ - internal->t_derot = stb0899_calc_derot_time(params->srate); - internal->t_data = 500; - - dprintk(state->verbose, FE_DEBUG, 1, "RESET stream merger"); - /* RESET Stream merger */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - /* - * Set KDIVIDER to an intermediate value between - * 1/2 and 7/8 for acquisition - */ - reg = stb0899_read_reg(state, STB0899_DEMAPVIT); - STB0899_SETFIELD_VAL(DEMAPVIT_KDIVIDER, reg, 60); - stb0899_write_reg(state, STB0899_DEMAPVIT, reg); - - stb0899_write_reg(state, STB0899_EQON, 0x01); /* Equalizer OFF while acquiring */ - stb0899_write_reg(state, STB0899_VITSYNC, 0x19); - - stb0899_first_subrange(state); - do { - /* Initialisations */ - cfr[0] = cfr[1] = 0; - stb0899_write_regs(state, STB0899_CFRM, cfr, 2); /* RESET derotator frequency */ - - stb0899_write_reg(state, STB0899_RTF, 0); - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 1); - stb0899_write_reg(state, STB0899_CFD, reg); - - internal->derot_freq = 0; - internal->status = NOAGC1; - - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - /* Move tuner to frequency */ - dprintk(state->verbose, FE_DEBUG, 1, "Tuner set frequency"); - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(&state->frontend, internal->freq); - - if (state->config->tuner_get_frequency) - state->config->tuner_get_frequency(&state->frontend, &internal->freq); - - msleep(internal->t_agc1 + internal->t_agc2 + internal->t_derot); /* AGC1, AGC2 and timing loop */ - dprintk(state->verbose, FE_DEBUG, 1, "current derot freq=%d", internal->derot_freq); - internal->status = AGC1OK; - - /* There is signal in the band */ - if (config->tuner_get_bandwidth) - config->tuner_get_bandwidth(&state->frontend, &bandwidth); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - - if (params->srate <= bandwidth / 2) - stb0899_search_tmg(state); /* For low rates (SCPC) */ - else - stb0899_check_tmg(state); /* For high rates (MCPC) */ - - if (internal->status == TIMINGOK) { - dprintk(state->verbose, FE_DEBUG, 1, - "TIMING OK ! Derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - if (stb0899_search_carrier(state) == CARRIEROK) { /* Search for carrier */ - dprintk(state->verbose, FE_DEBUG, 1, - "CARRIER OK ! Derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - if (stb0899_search_data(state) == DATAOK) { /* Check for data */ - dprintk(state->verbose, FE_DEBUG, 1, - "DATA OK ! Derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - if (stb0899_check_range(state) == RANGEOK) { - dprintk(state->verbose, FE_DEBUG, 1, - "RANGE OK ! derot freq=%d, mclk=%d", - internal->derot_freq, internal->mclk); - - internal->freq = params->freq + ((internal->derot_freq * internal->mclk) / 1000); - reg = stb0899_read_reg(state, STB0899_PLPARM); - internal->fecrate = STB0899_GETFIELD(VITCURPUN, reg); - dprintk(state->verbose, FE_DEBUG, 1, - "freq=%d, internal resultant freq=%d", - params->freq, internal->freq); - - dprintk(state->verbose, FE_DEBUG, 1, - "internal puncture rate=%d", - internal->fecrate); - } - } - } - } - if (internal->status != RANGEOK) - next_sub_range(state); - - } while (internal->sub_range && internal->status != RANGEOK); - - /* Set the timing loop to tracking */ - stb0899_write_reg(state, STB0899_RTC, 0x33); - stb0899_write_reg(state, STB0899_CFD, 0xf7); - /* if locked and range ok, set Kdiv */ - if (internal->status == RANGEOK) { - dprintk(state->verbose, FE_DEBUG, 1, "Locked & Range OK !"); - stb0899_write_reg(state, STB0899_EQON, 0x41); /* Equalizer OFF while acquiring */ - stb0899_write_reg(state, STB0899_VITSYNC, 0x39); /* SN to b'11 for acquisition */ - - /* - * Carrier loop optimization versus - * symbol Rate/Puncture Rate for Tracking - */ - reg = stb0899_read_reg(state, STB0899_BCLC); - switch (internal->fecrate) { - case STB0899_FEC_1_2: /* 13 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 0x1a); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[0][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_2_3: /* 18 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 44); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[1][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_3_4: /* 21 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 60); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[2][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_5_6: /* 24 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 75); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[3][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - case STB0899_FEC_6_7: /* 25 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 88); - stb0899_write_reg(state, STB0899_ACLC, 0x88); - stb0899_write_reg(state, STB0899_BCLC, 0x9a); - break; - case STB0899_FEC_7_8: /* 26 */ - stb0899_write_reg(state, STB0899_DEMAPVIT, 94); - STB0899_SETFIELD_VAL(BETA, reg, betaTab[4][clnI]); - stb0899_write_reg(state, STB0899_BCLC, reg); - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported Puncture Rate"); - break; - } - /* release stream merger RESET */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - /* disable carrier detector */ - reg = stb0899_read_reg(state, STB0899_CFD); - STB0899_SETFIELD_VAL(CFD_ON, reg, 0); - stb0899_write_reg(state, STB0899_CFD, reg); - - stb0899_read_regs(state, STB0899_EQUAI1, eq_const, 10); - } - - return internal->status; -} - -/* - * stb0899_dvbs2_config_uwp - * Configure UWP state machine - */ -static void stb0899_dvbs2_config_uwp(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - u32 uwp1, uwp2, uwp3, reg; - - uwp1 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1); - uwp2 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL2); - uwp3 = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL3); - - STB0899_SETFIELD_VAL(UWP_ESN0_AVE, uwp1, config->esno_ave); - STB0899_SETFIELD_VAL(UWP_ESN0_QUANT, uwp1, config->esno_quant); - STB0899_SETFIELD_VAL(UWP_TH_SOF, uwp1, config->uwp_threshold_sof); - - STB0899_SETFIELD_VAL(FE_COARSE_TRK, uwp2, internal->av_frame_coarse); - STB0899_SETFIELD_VAL(FE_FINE_TRK, uwp2, internal->av_frame_fine); - STB0899_SETFIELD_VAL(UWP_MISS_TH, uwp2, config->miss_threshold); - - STB0899_SETFIELD_VAL(UWP_TH_ACQ, uwp3, config->uwp_threshold_acq); - STB0899_SETFIELD_VAL(UWP_TH_TRACK, uwp3, config->uwp_threshold_track); - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL1, STB0899_OFF0_UWP_CNTRL1, uwp1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL2, STB0899_OFF0_UWP_CNTRL2, uwp2); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_UWP_CNTRL3, STB0899_OFF0_UWP_CNTRL3, uwp3); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, SOF_SRCH_TO); - STB0899_SETFIELD_VAL(SOF_SEARCH_TIMEOUT, reg, config->sof_search_timeout); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_SOF_SRCH_TO, STB0899_OFF0_SOF_SRCH_TO, reg); -} - -/* - * stb0899_dvbs2_config_csm_auto - * Set CSM to AUTO mode - */ -static void stb0899_dvbs2_config_csm_auto(struct stb0899_state *state) -{ - u32 reg; - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, reg); -} - -static long Log2Int(int number) -{ - int i; - - i = 0; - while ((1 << i) <= ABS(number)) - i++; - - if (number == 0) - i = 1; - - return i - 1; -} - -/* - * stb0899_dvbs2_calc_srate - * compute BTR_NOM_FREQ for the symbol rate - */ -static u32 stb0899_dvbs2_calc_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u32 dec_ratio, dec_rate, decim, remain, intval, btr_nom_freq; - u32 master_clk, srate; - - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - dec_rate = Log2Int(dec_ratio); - decim = 1 << dec_rate; - master_clk = internal->master_clk / 1000; - srate = internal->srate / 1000; - - if (decim <= 4) { - intval = (decim * (1 << (config->btr_nco_bits - 1))) / master_clk; - remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk; - } else { - intval = (1 << (config->btr_nco_bits - 1)) / (master_clk / 100) * decim / 100; - remain = (decim * (1 << (config->btr_nco_bits - 1))) % master_clk; - } - btr_nom_freq = (intval * srate) + ((remain * srate) / master_clk); - - return btr_nom_freq; -} - -/* - * stb0899_dvbs2_calc_dev - * compute the correction to be applied to symbol rate - */ -static u32 stb0899_dvbs2_calc_dev(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - u32 dec_ratio, correction, master_clk, srate; - - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - - master_clk = internal->master_clk / 1000; /* for integer Caculation*/ - srate = internal->srate / 1000; /* for integer Caculation*/ - correction = (512 * master_clk) / (2 * dec_ratio * srate); - - return correction; -} - -/* - * stb0899_dvbs2_set_srate - * Set DVBS2 symbol rate - */ -static void stb0899_dvbs2_set_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - - u32 dec_ratio, dec_rate, win_sel, decim, f_sym, btr_nom_freq; - u32 correction, freq_adj, band_lim, decim_cntrl, reg; - u8 anti_alias; - - /*set decimation to 1*/ - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - dec_rate = Log2Int(dec_ratio); - - win_sel = 0; - if (dec_rate >= 5) - win_sel = dec_rate - 4; - - decim = (1 << dec_rate); - /* (FSamp/Fsymbol *100) for integer Caculation */ - f_sym = internal->master_clk / ((decim * internal->srate) / 1000); - - if (f_sym <= 2250) /* don't band limit signal going into btr block*/ - band_lim = 1; - else - band_lim = 0; /* band limit signal going into btr block*/ - - decim_cntrl = ((win_sel << 3) & 0x18) + ((band_lim << 5) & 0x20) + (dec_rate & 0x7); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DECIM_CNTRL, STB0899_OFF0_DECIM_CNTRL, decim_cntrl); - - if (f_sym <= 3450) - anti_alias = 0; - else if (f_sym <= 4250) - anti_alias = 1; - else - anti_alias = 2; - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ANTI_ALIAS_SEL, STB0899_OFF0_ANTI_ALIAS_SEL, anti_alias); - btr_nom_freq = stb0899_dvbs2_calc_srate(state); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_NOM_FREQ, STB0899_OFF0_BTR_NOM_FREQ, btr_nom_freq); - - correction = stb0899_dvbs2_calc_dev(state); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL); - STB0899_SETFIELD_VAL(BTR_FREQ_CORR, reg, correction); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg); - - /* scale UWP+CSM frequency to sample rate*/ - freq_adj = internal->srate / (internal->master_clk / 4096); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_FREQ_ADJ_SCALE, STB0899_OFF0_FREQ_ADJ_SCALE, freq_adj); -} - -/* - * stb0899_dvbs2_set_btr_loopbw - * set bit timing loop bandwidth as a percentage of the symbol rate - */ -static void stb0899_dvbs2_set_btr_loopbw(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u32 sym_peak = 23, zeta = 707, loopbw_percent = 60; - s32 dec_ratio, dec_rate, k_btr1_rshft, k_btr1, k_btr0_rshft; - s32 k_btr0, k_btr2_rshft, k_direct_shift, k_indirect_shift; - u32 decim, K, wn, k_direct, k_indirect; - u32 reg; - - dec_ratio = (internal->master_clk * 2) / (5 * internal->srate); - dec_ratio = (dec_ratio == 0) ? 1 : dec_ratio; - dec_rate = Log2Int(dec_ratio); - decim = (1 << dec_rate); - - sym_peak *= 576000; - K = (1 << config->btr_nco_bits) / (internal->master_clk / 1000); - K *= (internal->srate / 1000000) * decim; /*k=k 10^-8*/ - - if (K != 0) { - K = sym_peak / K; - wn = (4 * zeta * zeta) + 1000000; - wn = (2 * (loopbw_percent * 1000) * 40 * zeta) /wn; /*wn =wn 10^-8*/ - - k_indirect = (wn * wn) / K; - k_indirect = k_indirect; /*kindirect = kindirect 10^-6*/ - k_direct = (2 * wn * zeta) / K; /*kDirect = kDirect 10^-2*/ - k_direct *= 100; - - k_direct_shift = Log2Int(k_direct) - Log2Int(10000) - 2; - k_btr1_rshft = (-1 * k_direct_shift) + config->btr_gain_shift_offset; - k_btr1 = k_direct / (1 << k_direct_shift); - k_btr1 /= 10000; - - k_indirect_shift = Log2Int(k_indirect + 15) - 20 /*- 2*/; - k_btr0_rshft = (-1 * k_indirect_shift) + config->btr_gain_shift_offset; - k_btr0 = k_indirect * (1 << (-k_indirect_shift)); - k_btr0 /= 1000000; - - k_btr2_rshft = 0; - if (k_btr0_rshft > 15) { - k_btr2_rshft = k_btr0_rshft - 15; - k_btr0_rshft = 15; - } - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_LOOP_GAIN); - STB0899_SETFIELD_VAL(KBTR0_RSHFT, reg, k_btr0_rshft); - STB0899_SETFIELD_VAL(KBTR0, reg, k_btr0); - STB0899_SETFIELD_VAL(KBTR1_RSHFT, reg, k_btr1_rshft); - STB0899_SETFIELD_VAL(KBTR1, reg, k_btr1); - STB0899_SETFIELD_VAL(KBTR2_RSHFT, reg, k_btr2_rshft); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, reg); - } else - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_LOOP_GAIN, STB0899_OFF0_BTR_LOOP_GAIN, 0xc4c4f); -} - -/* - * stb0899_dvbs2_set_carr_freq - * set nominal frequency for carrier search - */ -static void stb0899_dvbs2_set_carr_freq(struct stb0899_state *state, s32 carr_freq, u32 master_clk) -{ - struct stb0899_config *config = state->config; - s32 crl_nom_freq; - u32 reg; - - crl_nom_freq = (1 << config->crl_nco_bits) / master_clk; - crl_nom_freq *= carr_freq; - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ); - STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, crl_nom_freq); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg); -} - -/* - * stb0899_dvbs2_init_calc - * Initialize DVBS2 UWP, CSM, carrier and timing loops - */ -static void stb0899_dvbs2_init_calc(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - s32 steps, step_size; - u32 range, reg; - - /* config uwp and csm */ - stb0899_dvbs2_config_uwp(state); - stb0899_dvbs2_config_csm_auto(state); - - /* initialize BTR */ - stb0899_dvbs2_set_srate(state); - stb0899_dvbs2_set_btr_loopbw(state); - - if (internal->srate / 1000000 >= 15) - step_size = (1 << 17) / 5; - else if (internal->srate / 1000000 >= 10) - step_size = (1 << 17) / 7; - else if (internal->srate / 1000000 >= 5) - step_size = (1 << 17) / 10; - else - step_size = (1 << 17) / 4; - - range = internal->srch_range / 1000000; - steps = (10 * range * (1 << 17)) / (step_size * (internal->srate / 1000000)); - steps = (steps + 6) / 10; - steps = (steps == 0) ? 1 : steps; - if (steps % 2 == 0) - stb0899_dvbs2_set_carr_freq(state, internal->center_freq - - (internal->step_size * (internal->srate / 20000000)), - (internal->master_clk) / 1000000); - else - stb0899_dvbs2_set_carr_freq(state, internal->center_freq, (internal->master_clk) / 1000000); - - /*Set Carrier Search params (zigzag, num steps and freq step size*/ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, ACQ_CNTRL2); - STB0899_SETFIELD_VAL(ZIGZAG, reg, 1); - STB0899_SETFIELD_VAL(NUM_STEPS, reg, steps); - STB0899_SETFIELD_VAL(FREQ_STEPSIZE, reg, step_size); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQ_CNTRL2, STB0899_OFF0_ACQ_CNTRL2, reg); -} - -/* - * stb0899_dvbs2_btr_init - * initialize the timing loop - */ -static void stb0899_dvbs2_btr_init(struct stb0899_state *state) -{ - u32 reg; - - /* set enable BTR loopback */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_CNTRL); - STB0899_SETFIELD_VAL(INTRP_PHS_SENSE, reg, 1); - STB0899_SETFIELD_VAL(BTR_ERR_ENA, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_CNTRL, STB0899_OFF0_BTR_CNTRL, reg); - - /* fix btr freq accum at 0 */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x10000000); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_FREQ_INIT, STB0899_OFF0_BTR_FREQ_INIT, 0x00000000); - - /* fix btr freq accum at 0 */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x10000000); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_BTR_PHS_INIT, STB0899_OFF0_BTR_PHS_INIT, 0x00000000); -} - -/* - * stb0899_dvbs2_reacquire - * trigger a DVB-S2 acquisition - */ -static void stb0899_dvbs2_reacquire(struct stb0899_state *state) -{ - u32 reg = 0; - - /* demod soft reset */ - STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg); - - /*Reset Timing Loop */ - stb0899_dvbs2_btr_init(state); - - /* reset Carrier loop */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, (1 << 30)); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_FREQ_INIT, STB0899_OFF0_CRL_FREQ_INIT, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_LOOP_GAIN, STB0899_OFF0_CRL_LOOP_GAIN, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, (1 << 30)); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_PHS_INIT, STB0899_OFF0_CRL_PHS_INIT, 0); - - /*release demod soft reset */ - reg = 0; - STB0899_SETFIELD_VAL(DVBS2_RESET, reg, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_RESET_CNTRL, STB0899_OFF0_RESET_CNTRL, reg); - - /* start acquisition process */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_ACQUIRE_TRIG, STB0899_OFF0_ACQUIRE_TRIG, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_LOCK_LOST, STB0899_OFF0_LOCK_LOST, 0); - - /* equalizer Init */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 1); - - /*Start equilizer */ - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQUALIZER_INIT, STB0899_OFF0_EQUALIZER_INIT, 0); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL); - STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0); - STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 0); - STB0899_SETFIELD_VAL(EQ_DELAY, reg, 0x05); - STB0899_SETFIELD_VAL(EQ_ADAPT_MODE, reg, 0x01); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg); - - /* RESET Packet delineator */ - stb0899_write_reg(state, STB0899_PDELCTRL, 0x4a); -} - -/* - * stb0899_dvbs2_get_dmd_status - * get DVB-S2 Demod LOCK status - */ -static enum stb0899_status stb0899_dvbs2_get_dmd_status(struct stb0899_state *state, int timeout) -{ - int time = -10, lock = 0, uwp, csm; - u32 reg; - - do { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STATUS); - dprintk(state->verbose, FE_DEBUG, 1, "DMD_STATUS=[0x%02x]", reg); - if (STB0899_GETFIELD(IF_AGC_LOCK, reg)) - dprintk(state->verbose, FE_DEBUG, 1, "------------->IF AGC LOCKED !"); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2); - dprintk(state->verbose, FE_DEBUG, 1, "----------->DMD STAT2=[0x%02x]", reg); - uwp = STB0899_GETFIELD(UWP_LOCK, reg); - csm = STB0899_GETFIELD(CSM_LOCK, reg); - if (uwp && csm) - lock = 1; - - time += 10; - msleep(10); - - } while ((!lock) && (time <= timeout)); - - if (lock) { - dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 LOCK !"); - return DVBS2_DEMOD_LOCK; - } else { - return DVBS2_DEMOD_NOLOCK; - } -} - -/* - * stb0899_dvbs2_get_data_lock - * get FEC status - */ -static int stb0899_dvbs2_get_data_lock(struct stb0899_state *state, int timeout) -{ - int time = 0, lock = 0; - u8 reg; - - while ((!lock) && (time < timeout)) { - reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1); - dprintk(state->verbose, FE_DEBUG, 1, "---------> CFGPDELSTATUS=[0x%02x]", reg); - lock = STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg); - time++; - } - - return lock; -} - -/* - * stb0899_dvbs2_get_fec_status - * get DVB-S2 FEC LOCK status - */ -static enum stb0899_status stb0899_dvbs2_get_fec_status(struct stb0899_state *state, int timeout) -{ - int time = 0, Locked; - - do { - Locked = stb0899_dvbs2_get_data_lock(state, 1); - time++; - msleep(1); - - } while ((!Locked) && (time < timeout)); - - if (Locked) { - dprintk(state->verbose, FE_DEBUG, 1, "---------->DVB-S2 FEC LOCK !"); - return DVBS2_FEC_LOCK; - } else { - return DVBS2_FEC_NOLOCK; - } -} - - -/* - * stb0899_dvbs2_init_csm - * set parameters for manual mode - */ -static void stb0899_dvbs2_init_csm(struct stb0899_state *state, int pilots, enum stb0899_modcod modcod) -{ - struct stb0899_internal *internal = &state->internal; - - s32 dvt_tbl = 1, two_pass = 0, agc_gain = 6, agc_shift = 0, loop_shift = 0, phs_diff_thr = 0x80; - s32 gamma_acq, gamma_rho_acq, gamma_trk, gamma_rho_trk, lock_count_thr; - u32 csm1, csm2, csm3, csm4; - - if (((internal->master_clk / internal->srate) <= 4) && (modcod <= 11) && (pilots == 1)) { - switch (modcod) { - case STB0899_QPSK_12: - gamma_acq = 25; - gamma_rho_acq = 2700; - gamma_trk = 12; - gamma_rho_trk = 180; - lock_count_thr = 8; - break; - case STB0899_QPSK_35: - gamma_acq = 38; - gamma_rho_acq = 7182; - gamma_trk = 14; - gamma_rho_trk = 308; - lock_count_thr = 8; - break; - case STB0899_QPSK_23: - gamma_acq = 42; - gamma_rho_acq = 9408; - gamma_trk = 17; - gamma_rho_trk = 476; - lock_count_thr = 8; - break; - case STB0899_QPSK_34: - gamma_acq = 53; - gamma_rho_acq = 16642; - gamma_trk = 19; - gamma_rho_trk = 646; - lock_count_thr = 8; - break; - case STB0899_QPSK_45: - gamma_acq = 53; - gamma_rho_acq = 17119; - gamma_trk = 22; - gamma_rho_trk = 880; - lock_count_thr = 8; - break; - case STB0899_QPSK_56: - gamma_acq = 55; - gamma_rho_acq = 19250; - gamma_trk = 23; - gamma_rho_trk = 989; - lock_count_thr = 8; - break; - case STB0899_QPSK_89: - gamma_acq = 60; - gamma_rho_acq = 24240; - gamma_trk = 24; - gamma_rho_trk = 1176; - lock_count_thr = 8; - break; - case STB0899_QPSK_910: - gamma_acq = 66; - gamma_rho_acq = 29634; - gamma_trk = 24; - gamma_rho_trk = 1176; - lock_count_thr = 8; - break; - default: - gamma_acq = 66; - gamma_rho_acq = 29634; - gamma_trk = 24; - gamma_rho_trk = 1176; - lock_count_thr = 8; - break; - } - - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_AUTO_PARAM, csm1, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - csm2 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL2); - csm3 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL3); - csm4 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL4); - - STB0899_SETFIELD_VAL(CSM_DVT_TABLE, csm1, dvt_tbl); - STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, two_pass); - STB0899_SETFIELD_VAL(CSM_AGC_GAIN, csm1, agc_gain); - STB0899_SETFIELD_VAL(CSM_AGC_SHIFT, csm1, agc_shift); - STB0899_SETFIELD_VAL(FE_LOOP_SHIFT, csm1, loop_shift); - STB0899_SETFIELD_VAL(CSM_GAMMA_ACQ, csm2, gamma_acq); - STB0899_SETFIELD_VAL(CSM_GAMMA_RHOACQ, csm2, gamma_rho_acq); - STB0899_SETFIELD_VAL(CSM_GAMMA_TRACK, csm3, gamma_trk); - STB0899_SETFIELD_VAL(CSM_GAMMA_RHOTRACK, csm3, gamma_rho_trk); - STB0899_SETFIELD_VAL(CSM_LOCKCOUNT_THRESH, csm4, lock_count_thr); - STB0899_SETFIELD_VAL(CSM_PHASEDIFF_THRESH, csm4, phs_diff_thr); - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL2, STB0899_OFF0_CSM_CNTRL2, csm2); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL3, STB0899_OFF0_CSM_CNTRL3, csm3); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL4, STB0899_OFF0_CSM_CNTRL4, csm4); - } -} - -/* - * stb0899_dvbs2_get_srate - * get DVB-S2 Symbol Rate - */ -static u32 stb0899_dvbs2_get_srate(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - u32 bTrNomFreq, srate, decimRate, intval1, intval2, reg; - int div1, div2, rem1, rem2; - - div1 = config->btr_nco_bits / 2; - div2 = config->btr_nco_bits - div1 - 1; - - bTrNomFreq = STB0899_READ_S2REG(STB0899_S2DEMOD, BTR_NOM_FREQ); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DECIM_CNTRL); - decimRate = STB0899_GETFIELD(DECIM_RATE, reg); - decimRate = (1 << decimRate); - - intval1 = internal->master_clk / (1 << div1); - intval2 = bTrNomFreq / (1 << div2); - - rem1 = internal->master_clk % (1 << div1); - rem2 = bTrNomFreq % (1 << div2); - /* only for integer calculation */ - srate = (intval1 * intval2) + ((intval1 * rem2) / (1 << div2)) + ((intval2 * rem1) / (1 << div1)); - srate /= decimRate; /*symbrate = (btrnomfreq_register_val*MasterClock)/2^(27+decim_rate_field) */ - - return srate; -} - -/* - * stb0899_dvbs2_algo - * Search for signal, timing, carrier and data for a given - * frequency in a given range - */ -enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - enum stb0899_modcod modcod; - - s32 offsetfreq, searchTime, FecLockTime, pilots, iqSpectrum; - int i = 0; - u32 reg, csm1; - - if (internal->srate <= 2000000) { - searchTime = 5000; /* 5000 ms max time to lock UWP and CSM, SYMB <= 2Mbs */ - FecLockTime = 350; /* 350 ms max time to lock FEC, SYMB <= 2Mbs */ - } else if (internal->srate <= 5000000) { - searchTime = 2500; /* 2500 ms max time to lock UWP and CSM, 2Mbs < SYMB <= 5Mbs */ - FecLockTime = 170; /* 170 ms max time to lock FEC, 2Mbs< SYMB <= 5Mbs */ - } else if (internal->srate <= 10000000) { - searchTime = 1500; /* 1500 ms max time to lock UWP and CSM, 5Mbs <SYMB <= 10Mbs */ - FecLockTime = 80; /* 80 ms max time to lock FEC, 5Mbs< SYMB <= 10Mbs */ - } else if (internal->srate <= 15000000) { - searchTime = 500; /* 500 ms max time to lock UWP and CSM, 10Mbs <SYMB <= 15Mbs */ - FecLockTime = 50; /* 50 ms max time to lock FEC, 10Mbs< SYMB <= 15Mbs */ - } else if (internal->srate <= 20000000) { - searchTime = 300; /* 300 ms max time to lock UWP and CSM, 15Mbs < SYMB <= 20Mbs */ - FecLockTime = 30; /* 50 ms max time to lock FEC, 15Mbs< SYMB <= 20Mbs */ - } else if (internal->srate <= 25000000) { - searchTime = 250; /* 250 ms max time to lock UWP and CSM, 20 Mbs < SYMB <= 25Mbs */ - FecLockTime = 25; /* 25 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */ - } else { - searchTime = 150; /* 150 ms max time to lock UWP and CSM, SYMB > 25Mbs */ - FecLockTime = 20; /* 20 ms max time to lock FEC, 20Mbs< SYMB <= 25Mbs */ - } - - /* Maintain Stream Merger in reset during acquisition */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - /* Move tuner to frequency */ - if (state->config->tuner_set_frequency) - state->config->tuner_set_frequency(&state->frontend, internal->freq); - if (state->config->tuner_get_frequency) - state->config->tuner_get_frequency(&state->frontend, &internal->freq); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - - /* Set IF AGC to acquisition */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); - STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 4); - STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 32); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2); - STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg); - - /* Initialisation */ - stb0899_dvbs2_init_calc(state); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2); - switch (internal->inversion) { - case IQ_SWAP_OFF: - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 0); - break; - case IQ_SWAP_ON: - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1); - break; - case IQ_SWAP_AUTO: /* use last successful search first */ - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, 1); - break; - } - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg); - stb0899_dvbs2_reacquire(state); - - /* Wait for demod lock (UWP and CSM) */ - internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime); - - if (internal->status == DVBS2_DEMOD_LOCK) { - dprintk(state->verbose, FE_DEBUG, 1, "------------> DVB-S2 DEMOD LOCK !"); - i = 0; - /* Demod Locked, check FEC status */ - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - - /*If false lock (UWP and CSM Locked but no FEC) try 3 time max*/ - while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) { - /* Read the frequency offset*/ - offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ); - - /* Set the Nominal frequency to the found frequency offset for the next reacquire*/ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ); - STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg); - stb0899_dvbs2_reacquire(state); - internal->status = stb0899_dvbs2_get_fec_status(state, searchTime); - i++; - } - } - - if (internal->status != DVBS2_FEC_LOCK) { - if (internal->inversion == IQ_SWAP_AUTO) { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2); - iqSpectrum = STB0899_GETFIELD(SPECTRUM_INVERT, reg); - /* IQ Spectrum Inversion */ - STB0899_SETFIELD_VAL(SPECTRUM_INVERT, reg, !iqSpectrum); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_DMD_CNTRL2, STB0899_OFF0_DMD_CNTRL2, reg); - /* start acquistion process */ - stb0899_dvbs2_reacquire(state); - - /* Wait for demod lock (UWP and CSM) */ - internal->status = stb0899_dvbs2_get_dmd_status(state, searchTime); - if (internal->status == DVBS2_DEMOD_LOCK) { - i = 0; - /* Demod Locked, check FEC */ - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - /*try thrice for false locks, (UWP and CSM Locked but no FEC) */ - while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) { - /* Read the frequency offset*/ - offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ); - - /* Set the Nominal frequency to the found frequency offset for the next reacquire*/ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_NOM_FREQ); - STB0899_SETFIELD_VAL(CRL_NOM_FREQ, reg, offsetfreq); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CRL_NOM_FREQ, STB0899_OFF0_CRL_NOM_FREQ, reg); - - stb0899_dvbs2_reacquire(state); - internal->status = stb0899_dvbs2_get_fec_status(state, searchTime); - i++; - } - } -/* - if (pParams->DVBS2State == FE_DVBS2_FEC_LOCKED) - pParams->IQLocked = !iqSpectrum; -*/ - } - } - if (internal->status == DVBS2_FEC_LOCK) { - dprintk(state->verbose, FE_DEBUG, 1, "----------------> DVB-S2 FEC Lock !"); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); - modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2; - pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01; - - if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) && - (INRANGE(STB0899_QPSK_23, modcod, STB0899_QPSK_910)) && - (pilots == 1)) { - - stb0899_dvbs2_init_csm(state, pilots, modcod); - /* Wait for UWP,CSM and data LOCK 20ms max */ - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - - i = 0; - while ((internal->status != DVBS2_FEC_LOCK) && (i < 3)) { - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - csm1 = STB0899_READ_S2REG(STB0899_S2DEMOD, CSM_CNTRL1); - STB0899_SETFIELD_VAL(CSM_TWO_PASS, csm1, 0); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_CSM_CNTRL1, STB0899_OFF0_CSM_CNTRL1, csm1); - - internal->status = stb0899_dvbs2_get_fec_status(state, FecLockTime); - i++; - } - } - - if ((((10 * internal->master_clk) / (internal->srate / 10)) <= 410) && - (INRANGE(STB0899_QPSK_12, modcod, STB0899_QPSK_35)) && - (pilots == 1)) { - - /* Equalizer Disable update */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL); - STB0899_SETFIELD_VAL(EQ_DISABLE_UPDATE, reg, 1); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg); - } - - /* slow down the Equalizer once locked */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, EQ_CNTRL); - STB0899_SETFIELD_VAL(EQ_SHIFT, reg, 0x02); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_EQ_CNTRL, STB0899_OFF0_EQ_CNTRL, reg); - - /* Store signal parameters */ - offsetfreq = STB0899_READ_S2REG(STB0899_S2DEMOD, CRL_FREQ); - - offsetfreq = offsetfreq / ((1 << 30) / 1000); - offsetfreq *= (internal->master_clk / 1000000); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CNTRL2); - if (STB0899_GETFIELD(SPECTRUM_INVERT, reg)) - offsetfreq *= -1; - - internal->freq = internal->freq - offsetfreq; - internal->srate = stb0899_dvbs2_get_srate(state); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); - internal->modcod = STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 2; - internal->pilots = STB0899_GETFIELD(UWP_DECODE_MOD, reg) & 0x01; - internal->frame_length = (STB0899_GETFIELD(UWP_DECODE_MOD, reg) >> 1) & 0x01; - - /* Set IF AGC to tracking */ - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); - STB0899_SETFIELD_VAL(IF_LOOP_GAIN, reg, 3); - - /* if QPSK 1/2,QPSK 3/5 or QPSK 2/3 set IF AGC reference to 16 otherwise 32*/ - if (INRANGE(STB0899_QPSK_12, internal->modcod, STB0899_QPSK_23)) - STB0899_SETFIELD_VAL(IF_AGC_REF, reg, 16); - - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL2); - STB0899_SETFIELD_VAL(IF_AGC_DUMP_PER, reg, 7); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL2, STB0899_OFF0_IF_AGC_CNTRL2, reg); - } - - /* Release Stream Merger Reset */ - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESRS, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - return internal->status; -} diff --git a/drivers/media/dvb/frontends/stb0899_cfg.h b/drivers/media/dvb/frontends/stb0899_cfg.h deleted file mode 100644 index 0867906d3ff..00000000000 --- a/drivers/media/dvb/frontends/stb0899_cfg.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __STB0899_CFG_H -#define __STB0899_CFG_H - -static const struct stb0899_s2_reg stb0899_s2_init_2[] = { - - { STB0899_OFF0_DMD_STATUS , STB0899_BASE_DMD_STATUS , 0x00000103 }, /* DMDSTATUS */ - { STB0899_OFF0_CRL_FREQ , STB0899_BASE_CRL_FREQ , 0x3ed1da56 }, /* CRLFREQ */ - { STB0899_OFF0_BTR_FREQ , STB0899_BASE_BTR_FREQ , 0x00004000 }, /* BTRFREQ */ - { STB0899_OFF0_IF_AGC_GAIN , STB0899_BASE_IF_AGC_GAIN , 0x00002ade }, /* IFAGCGAIN */ - { STB0899_OFF0_BB_AGC_GAIN , STB0899_BASE_BB_AGC_GAIN , 0x000001bc }, /* BBAGCGAIN */ - { STB0899_OFF0_DC_OFFSET , STB0899_BASE_DC_OFFSET , 0x00000200 }, /* DCOFFSET */ - { STB0899_OFF0_DMD_CNTRL , STB0899_BASE_DMD_CNTRL , 0x0000000f }, /* DMDCNTRL */ - - { STB0899_OFF0_IF_AGC_CNTRL , STB0899_BASE_IF_AGC_CNTRL , 0x03fb4a20 }, /* IFAGCCNTRL */ - { STB0899_OFF0_BB_AGC_CNTRL , STB0899_BASE_BB_AGC_CNTRL , 0x00200c97 }, /* BBAGCCNTRL */ - - { STB0899_OFF0_CRL_CNTRL , STB0899_BASE_CRL_CNTRL , 0x00000016 }, /* CRLCNTRL */ - { STB0899_OFF0_CRL_PHS_INIT , STB0899_BASE_CRL_PHS_INIT , 0x00000000 }, /* CRLPHSINIT */ - { STB0899_OFF0_CRL_FREQ_INIT , STB0899_BASE_CRL_FREQ_INIT , 0x00000000 }, /* CRLFREQINIT */ - { STB0899_OFF0_CRL_LOOP_GAIN , STB0899_BASE_CRL_LOOP_GAIN , 0x00000000 }, /* CRLLOOPGAIN */ - { STB0899_OFF0_CRL_NOM_FREQ , STB0899_BASE_CRL_NOM_FREQ , 0x3ed097b6 }, /* CRLNOMFREQ */ - { STB0899_OFF0_CRL_SWP_RATE , STB0899_BASE_CRL_SWP_RATE , 0x00000000 }, /* CRLSWPRATE */ - { STB0899_OFF0_CRL_MAX_SWP , STB0899_BASE_CRL_MAX_SWP , 0x00000000 }, /* CRLMAXSWP */ - { STB0899_OFF0_CRL_LK_CNTRL , STB0899_BASE_CRL_LK_CNTRL , 0x0f6cdc01 }, /* CRLLKCNTRL */ - { STB0899_OFF0_DECIM_CNTRL , STB0899_BASE_DECIM_CNTRL , 0x00000000 }, /* DECIMCNTRL */ - { STB0899_OFF0_BTR_CNTRL , STB0899_BASE_BTR_CNTRL , 0x00003993 }, /* BTRCNTRL */ - { STB0899_OFF0_BTR_LOOP_GAIN , STB0899_BASE_BTR_LOOP_GAIN , 0x000d3c6f }, /* BTRLOOPGAIN */ - { STB0899_OFF0_BTR_PHS_INIT , STB0899_BASE_BTR_PHS_INIT , 0x00000000 }, /* BTRPHSINIT */ - { STB0899_OFF0_BTR_FREQ_INIT , STB0899_BASE_BTR_FREQ_INIT , 0x00000000 }, /* BTRFREQINIT */ - { STB0899_OFF0_BTR_NOM_FREQ , STB0899_BASE_BTR_NOM_FREQ , 0x0238e38e }, /* BTRNOMFREQ */ - { STB0899_OFF0_BTR_LK_CNTRL , STB0899_BASE_BTR_LK_CNTRL , 0x00000000 }, /* BTRLKCNTRL */ - { STB0899_OFF0_DECN_CNTRL , STB0899_BASE_DECN_CNTRL , 0x00000000 }, /* DECNCNTRL */ - { STB0899_OFF0_TP_CNTRL , STB0899_BASE_TP_CNTRL , 0x00000000 }, /* TPCNTRL */ - { STB0899_OFF0_TP_BUF_STATUS , STB0899_BASE_TP_BUF_STATUS , 0x00000000 }, /* TPBUFSTATUS */ - { STB0899_OFF0_DC_ESTIM , STB0899_BASE_DC_ESTIM , 0x00000000 }, /* DCESTIM */ - { STB0899_OFF0_FLL_CNTRL , STB0899_BASE_FLL_CNTRL , 0x00000000 }, /* FLLCNTRL */ - { STB0899_OFF0_FLL_FREQ_WD , STB0899_BASE_FLL_FREQ_WD , 0x40070000 }, /* FLLFREQWD */ - { STB0899_OFF0_ANTI_ALIAS_SEL , STB0899_BASE_ANTI_ALIAS_SEL , 0x00000001 }, /* ANTIALIASSEL */ - { STB0899_OFF0_RRC_ALPHA , STB0899_BASE_RRC_ALPHA , 0x00000002 }, /* RRCALPHA */ - { STB0899_OFF0_DC_ADAPT_LSHFT , STB0899_BASE_DC_ADAPT_LSHFT , 0x00000000 }, /* DCADAPTISHFT */ - { STB0899_OFF0_IMB_OFFSET , STB0899_BASE_IMB_OFFSET , 0x0000fe01 }, /* IMBOFFSET */ - { STB0899_OFF0_IMB_ESTIMATE , STB0899_BASE_IMB_ESTIMATE , 0x00000000 }, /* IMBESTIMATE */ - { STB0899_OFF0_IMB_CNTRL , STB0899_BASE_IMB_CNTRL , 0x00000001 }, /* IMBCNTRL */ - { STB0899_OFF0_IF_AGC_CNTRL2 , STB0899_BASE_IF_AGC_CNTRL2 , 0x00005007 }, /* IFAGCCNTRL2 */ - { STB0899_OFF0_DMD_CNTRL2 , STB0899_BASE_DMD_CNTRL2 , 0x00000002 }, /* DMDCNTRL2 */ - { STB0899_OFF0_TP_BUFFER , STB0899_BASE_TP_BUFFER , 0x00000000 }, /* TPBUFFER */ - { STB0899_OFF0_TP_BUFFER1 , STB0899_BASE_TP_BUFFER1 , 0x00000000 }, /* TPBUFFER1 */ - { STB0899_OFF0_TP_BUFFER2 , STB0899_BASE_TP_BUFFER2 , 0x00000000 }, /* TPBUFFER2 */ - { STB0899_OFF0_TP_BUFFER3 , STB0899_BASE_TP_BUFFER3 , 0x00000000 }, /* TPBUFFER3 */ - { STB0899_OFF0_TP_BUFFER4 , STB0899_BASE_TP_BUFFER4 , 0x00000000 }, /* TPBUFFER4 */ - { STB0899_OFF0_TP_BUFFER5 , STB0899_BASE_TP_BUFFER5 , 0x00000000 }, /* TPBUFFER5 */ - { STB0899_OFF0_TP_BUFFER6 , STB0899_BASE_TP_BUFFER6 , 0x00000000 }, /* TPBUFFER6 */ - { STB0899_OFF0_TP_BUFFER7 , STB0899_BASE_TP_BUFFER7 , 0x00000000 }, /* TPBUFFER7 */ - { STB0899_OFF0_TP_BUFFER8 , STB0899_BASE_TP_BUFFER8 , 0x00000000 }, /* TPBUFFER8 */ - { STB0899_OFF0_TP_BUFFER9 , STB0899_BASE_TP_BUFFER9 , 0x00000000 }, /* TPBUFFER9 */ - { STB0899_OFF0_TP_BUFFER10 , STB0899_BASE_TP_BUFFER10 , 0x00000000 }, /* TPBUFFER10 */ - { STB0899_OFF0_TP_BUFFER11 , STB0899_BASE_TP_BUFFER11 , 0x00000000 }, /* TPBUFFER11 */ - { STB0899_OFF0_TP_BUFFER12 , STB0899_BASE_TP_BUFFER12 , 0x00000000 }, /* TPBUFFER12 */ - { STB0899_OFF0_TP_BUFFER13 , STB0899_BASE_TP_BUFFER13 , 0x00000000 }, /* TPBUFFER13 */ - { STB0899_OFF0_TP_BUFFER14 , STB0899_BASE_TP_BUFFER14 , 0x00000000 }, /* TPBUFFER14 */ - { STB0899_OFF0_TP_BUFFER15 , STB0899_BASE_TP_BUFFER15 , 0x00000000 }, /* TPBUFFER15 */ - { STB0899_OFF0_TP_BUFFER16 , STB0899_BASE_TP_BUFFER16 , 0x0000ff00 }, /* TPBUFFER16 */ - { STB0899_OFF0_TP_BUFFER17 , STB0899_BASE_TP_BUFFER17 , 0x00000100 }, /* TPBUFFER17 */ - { STB0899_OFF0_TP_BUFFER18 , STB0899_BASE_TP_BUFFER18 , 0x0000fe01 }, /* TPBUFFER18 */ - { STB0899_OFF0_TP_BUFFER19 , STB0899_BASE_TP_BUFFER19 , 0x000004fe }, /* TPBUFFER19 */ - { STB0899_OFF0_TP_BUFFER20 , STB0899_BASE_TP_BUFFER20 , 0x0000cfe7 }, /* TPBUFFER20 */ - { STB0899_OFF0_TP_BUFFER21 , STB0899_BASE_TP_BUFFER21 , 0x0000bec6 }, /* TPBUFFER21 */ - { STB0899_OFF0_TP_BUFFER22 , STB0899_BASE_TP_BUFFER22 , 0x0000c2bf }, /* TPBUFFER22 */ - { STB0899_OFF0_TP_BUFFER23 , STB0899_BASE_TP_BUFFER23 , 0x0000c1c1 }, /* TPBUFFER23 */ - { STB0899_OFF0_TP_BUFFER24 , STB0899_BASE_TP_BUFFER24 , 0x0000c1c1 }, /* TPBUFFER24 */ - { STB0899_OFF0_TP_BUFFER25 , STB0899_BASE_TP_BUFFER25 , 0x0000c1c1 }, /* TPBUFFER25 */ - { STB0899_OFF0_TP_BUFFER26 , STB0899_BASE_TP_BUFFER26 , 0x0000c1c1 }, /* TPBUFFER26 */ - { STB0899_OFF0_TP_BUFFER27 , STB0899_BASE_TP_BUFFER27 , 0x0000c1c0 }, /* TPBUFFER27 */ - { STB0899_OFF0_TP_BUFFER28 , STB0899_BASE_TP_BUFFER28 , 0x0000c0c0 }, /* TPBUFFER28 */ - { STB0899_OFF0_TP_BUFFER29 , STB0899_BASE_TP_BUFFER29 , 0x0000c1c1 }, /* TPBUFFER29 */ - { STB0899_OFF0_TP_BUFFER30 , STB0899_BASE_TP_BUFFER30 , 0x0000c1c1 }, /* TPBUFFER30 */ - { STB0899_OFF0_TP_BUFFER31 , STB0899_BASE_TP_BUFFER31 , 0x0000c0c1 }, /* TPBUFFER31 */ - { STB0899_OFF0_TP_BUFFER32 , STB0899_BASE_TP_BUFFER32 , 0x0000c0c1 }, /* TPBUFFER32 */ - { STB0899_OFF0_TP_BUFFER33 , STB0899_BASE_TP_BUFFER33 , 0x0000c1c1 }, /* TPBUFFER33 */ - { STB0899_OFF0_TP_BUFFER34 , STB0899_BASE_TP_BUFFER34 , 0x0000c1c1 }, /* TPBUFFER34 */ - { STB0899_OFF0_TP_BUFFER35 , STB0899_BASE_TP_BUFFER35 , 0x0000c0c1 }, /* TPBUFFER35 */ - { STB0899_OFF0_TP_BUFFER36 , STB0899_BASE_TP_BUFFER36 , 0x0000c1c1 }, /* TPBUFFER36 */ - { STB0899_OFF0_TP_BUFFER37 , STB0899_BASE_TP_BUFFER37 , 0x0000c0c1 }, /* TPBUFFER37 */ - { STB0899_OFF0_TP_BUFFER38 , STB0899_BASE_TP_BUFFER38 , 0x0000c1c1 }, /* TPBUFFER38 */ - { STB0899_OFF0_TP_BUFFER39 , STB0899_BASE_TP_BUFFER39 , 0x0000c0c0 }, /* TPBUFFER39 */ - { STB0899_OFF0_TP_BUFFER40 , STB0899_BASE_TP_BUFFER40 , 0x0000c1c0 }, /* TPBUFFER40 */ - { STB0899_OFF0_TP_BUFFER41 , STB0899_BASE_TP_BUFFER41 , 0x0000c1c1 }, /* TPBUFFER41 */ - { STB0899_OFF0_TP_BUFFER42 , STB0899_BASE_TP_BUFFER42 , 0x0000c0c0 }, /* TPBUFFER42 */ - { STB0899_OFF0_TP_BUFFER43 , STB0899_BASE_TP_BUFFER43 , 0x0000c1c0 }, /* TPBUFFER43 */ - { STB0899_OFF0_TP_BUFFER44 , STB0899_BASE_TP_BUFFER44 , 0x0000c0c1 }, /* TPBUFFER44 */ - { STB0899_OFF0_TP_BUFFER45 , STB0899_BASE_TP_BUFFER45 , 0x0000c1be }, /* TPBUFFER45 */ - { STB0899_OFF0_TP_BUFFER46 , STB0899_BASE_TP_BUFFER46 , 0x0000c1c9 }, /* TPBUFFER46 */ - { STB0899_OFF0_TP_BUFFER47 , STB0899_BASE_TP_BUFFER47 , 0x0000c0da }, /* TPBUFFER47 */ - { STB0899_OFF0_TP_BUFFER48 , STB0899_BASE_TP_BUFFER48 , 0x0000c0ba }, /* TPBUFFER48 */ - { STB0899_OFF0_TP_BUFFER49 , STB0899_BASE_TP_BUFFER49 , 0x0000c1c4 }, /* TPBUFFER49 */ - { STB0899_OFF0_TP_BUFFER50 , STB0899_BASE_TP_BUFFER50 , 0x0000c1bf }, /* TPBUFFER50 */ - { STB0899_OFF0_TP_BUFFER51 , STB0899_BASE_TP_BUFFER51 , 0x0000c0c1 }, /* TPBUFFER51 */ - { STB0899_OFF0_TP_BUFFER52 , STB0899_BASE_TP_BUFFER52 , 0x0000c1c0 }, /* TPBUFFER52 */ - { STB0899_OFF0_TP_BUFFER53 , STB0899_BASE_TP_BUFFER53 , 0x0000c0c1 }, /* TPBUFFER53 */ - { STB0899_OFF0_TP_BUFFER54 , STB0899_BASE_TP_BUFFER54 , 0x0000c1c1 }, /* TPBUFFER54 */ - { STB0899_OFF0_TP_BUFFER55 , STB0899_BASE_TP_BUFFER55 , 0x0000c1c1 }, /* TPBUFFER55 */ - { STB0899_OFF0_TP_BUFFER56 , STB0899_BASE_TP_BUFFER56 , 0x0000c1c1 }, /* TPBUFFER56 */ - { STB0899_OFF0_TP_BUFFER57 , STB0899_BASE_TP_BUFFER57 , 0x0000c1c1 }, /* TPBUFFER57 */ - { STB0899_OFF0_TP_BUFFER58 , STB0899_BASE_TP_BUFFER58 , 0x0000c1c1 }, /* TPBUFFER58 */ - { STB0899_OFF0_TP_BUFFER59 , STB0899_BASE_TP_BUFFER59 , 0x0000c1c1 }, /* TPBUFFER59 */ - { STB0899_OFF0_TP_BUFFER60 , STB0899_BASE_TP_BUFFER60 , 0x0000c1c1 }, /* TPBUFFER60 */ - { STB0899_OFF0_TP_BUFFER61 , STB0899_BASE_TP_BUFFER61 , 0x0000c1c1 }, /* TPBUFFER61 */ - { STB0899_OFF0_TP_BUFFER62 , STB0899_BASE_TP_BUFFER62 , 0x0000c1c1 }, /* TPBUFFER62 */ - { STB0899_OFF0_TP_BUFFER63 , STB0899_BASE_TP_BUFFER63 , 0x0000c1c0 }, /* TPBUFFER63 */ - { STB0899_OFF0_RESET_CNTRL , STB0899_BASE_RESET_CNTRL , 0x00000001 }, /* RESETCNTRL */ - { STB0899_OFF0_ACM_ENABLE , STB0899_BASE_ACM_ENABLE , 0x00005654 }, /* ACMENABLE */ - { STB0899_OFF0_DESCR_CNTRL , STB0899_BASE_DESCR_CNTRL , 0x00000000 }, /* DESCRCNTRL */ - { STB0899_OFF0_CSM_CNTRL1 , STB0899_BASE_CSM_CNTRL1 , 0x00020019 }, /* CSMCNTRL1 */ - { STB0899_OFF0_CSM_CNTRL2 , STB0899_BASE_CSM_CNTRL2 , 0x004b3237 }, /* CSMCNTRL2 */ - { STB0899_OFF0_CSM_CNTRL3 , STB0899_BASE_CSM_CNTRL3 , 0x0003dd17 }, /* CSMCNTRL3 */ - { STB0899_OFF0_CSM_CNTRL4 , STB0899_BASE_CSM_CNTRL4 , 0x00008008 }, /* CSMCNTRL4 */ - { STB0899_OFF0_UWP_CNTRL1 , STB0899_BASE_UWP_CNTRL1 , 0x002a3106 }, /* UWPCNTRL1 */ - { STB0899_OFF0_UWP_CNTRL2 , STB0899_BASE_UWP_CNTRL2 , 0x0006140a }, /* UWPCNTRL2 */ - { STB0899_OFF0_UWP_STAT1 , STB0899_BASE_UWP_STAT1 , 0x00008000 }, /* UWPSTAT1 */ - { STB0899_OFF0_UWP_STAT2 , STB0899_BASE_UWP_STAT2 , 0x00000000 }, /* UWPSTAT2 */ - { STB0899_OFF0_DMD_STAT2 , STB0899_BASE_DMD_STAT2 , 0x00000000 }, /* DMDSTAT2 */ - { STB0899_OFF0_FREQ_ADJ_SCALE , STB0899_BASE_FREQ_ADJ_SCALE , 0x00000471 }, /* FREQADJSCALE */ - { STB0899_OFF0_UWP_CNTRL3 , STB0899_BASE_UWP_CNTRL3 , 0x017b0465 }, /* UWPCNTRL3 */ - { STB0899_OFF0_SYM_CLK_SEL , STB0899_BASE_SYM_CLK_SEL , 0x00000002 }, /* SYMCLKSEL */ - { STB0899_OFF0_SOF_SRCH_TO , STB0899_BASE_SOF_SRCH_TO , 0x00196464 }, /* SOFSRCHTO */ - { STB0899_OFF0_ACQ_CNTRL1 , STB0899_BASE_ACQ_CNTRL1 , 0x00000603 }, /* ACQCNTRL1 */ - { STB0899_OFF0_ACQ_CNTRL2 , STB0899_BASE_ACQ_CNTRL2 , 0x02046666 }, /* ACQCNTRL2 */ - { STB0899_OFF0_ACQ_CNTRL3 , STB0899_BASE_ACQ_CNTRL3 , 0x10046583 }, /* ACQCNTRL3 */ - { STB0899_OFF0_FE_SETTLE , STB0899_BASE_FE_SETTLE , 0x00010404 }, /* FESETTLE */ - { STB0899_OFF0_AC_DWELL , STB0899_BASE_AC_DWELL , 0x0002aa8a }, /* ACDWELL */ - { STB0899_OFF0_ACQUIRE_TRIG , STB0899_BASE_ACQUIRE_TRIG , 0x00000000 }, /* ACQUIRETRIG */ - { STB0899_OFF0_LOCK_LOST , STB0899_BASE_LOCK_LOST , 0x00000001 }, /* LOCKLOST */ - { STB0899_OFF0_ACQ_STAT1 , STB0899_BASE_ACQ_STAT1 , 0x00000500 }, /* ACQSTAT1 */ - { STB0899_OFF0_ACQ_TIMEOUT , STB0899_BASE_ACQ_TIMEOUT , 0x0028a0a0 }, /* ACQTIMEOUT */ - { STB0899_OFF0_ACQ_TIME , STB0899_BASE_ACQ_TIME , 0x00000000 }, /* ACQTIME */ - { STB0899_OFF0_FINAL_AGC_CNTRL , STB0899_BASE_FINAL_AGC_CNTRL , 0x00800c17 }, /* FINALAGCCNTRL*/ - { STB0899_OFF0_FINAL_AGC_GAIN , STB0899_BASE_FINAL_AGC_GAIN , 0x00000000 }, /* FINALAGCCGAIN*/ - { STB0899_OFF0_EQUALIZER_INIT , STB0899_BASE_EQUALIZER_INIT , 0x00000000 }, /* EQUILIZERINIT*/ - { STB0899_OFF0_EQ_CNTRL , STB0899_BASE_EQ_CNTRL , 0x00054802 }, /* EQCNTL */ - { STB0899_OFF0_EQ_I_INIT_COEFF_0, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF0 */ - { STB0899_OFF1_EQ_I_INIT_COEFF_1, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF1 */ - { STB0899_OFF2_EQ_I_INIT_COEFF_2, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF2 */ - { STB0899_OFF3_EQ_I_INIT_COEFF_3, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF3 */ - { STB0899_OFF4_EQ_I_INIT_COEFF_4, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF4 */ - { STB0899_OFF5_EQ_I_INIT_COEFF_5, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000400 }, /* EQIINITCOEFF5 */ - { STB0899_OFF6_EQ_I_INIT_COEFF_6, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF6 */ - { STB0899_OFF7_EQ_I_INIT_COEFF_7, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF7 */ - { STB0899_OFF8_EQ_I_INIT_COEFF_8, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF8 */ - { STB0899_OFF9_EQ_I_INIT_COEFF_9, STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF9 */ - { STB0899_OFFa_EQ_I_INIT_COEFF_10,STB0899_BASE_EQ_I_INIT_COEFF_N, 0x00000000 }, /* EQIINITCOEFF10*/ - { STB0899_OFF0_EQ_Q_INIT_COEFF_0, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF0 */ - { STB0899_OFF1_EQ_Q_INIT_COEFF_1, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF1 */ - { STB0899_OFF2_EQ_Q_INIT_COEFF_2, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF2 */ - { STB0899_OFF3_EQ_Q_INIT_COEFF_3, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF3 */ - { STB0899_OFF4_EQ_Q_INIT_COEFF_4, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF4 */ - { STB0899_OFF5_EQ_Q_INIT_COEFF_5, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF5 */ - { STB0899_OFF6_EQ_Q_INIT_COEFF_6, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF6 */ - { STB0899_OFF7_EQ_Q_INIT_COEFF_7, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF7 */ - { STB0899_OFF8_EQ_Q_INIT_COEFF_8, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF8 */ - { STB0899_OFF9_EQ_Q_INIT_COEFF_9, STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF9 */ - { STB0899_OFFa_EQ_Q_INIT_COEFF_10,STB0899_BASE_EQ_Q_INIT_COEFF_N, 0x00000000 }, /* EQQINITCOEFF10*/ - { STB0899_OFF0_EQ_I_OUT_COEFF_0 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT0 */ - { STB0899_OFF1_EQ_I_OUT_COEFF_1 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT1 */ - { STB0899_OFF2_EQ_I_OUT_COEFF_2 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT2 */ - { STB0899_OFF3_EQ_I_OUT_COEFF_3 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT3 */ - { STB0899_OFF4_EQ_I_OUT_COEFF_4 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT4 */ - { STB0899_OFF5_EQ_I_OUT_COEFF_5 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT5 */ - { STB0899_OFF6_EQ_I_OUT_COEFF_6 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT6 */ - { STB0899_OFF7_EQ_I_OUT_COEFF_7 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT7 */ - { STB0899_OFF8_EQ_I_OUT_COEFF_8 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT8 */ - { STB0899_OFF9_EQ_I_OUT_COEFF_9 , STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT9 */ - { STB0899_OFFa_EQ_I_OUT_COEFF_10,STB0899_BASE_EQ_I_OUT_COEFF_N , 0x00000000 }, /* EQICOEFFSOUT10*/ - { STB0899_OFF0_EQ_Q_OUT_COEFF_0 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT0 */ - { STB0899_OFF1_EQ_Q_OUT_COEFF_1 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT1 */ - { STB0899_OFF2_EQ_Q_OUT_COEFF_2 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT2 */ - { STB0899_OFF3_EQ_Q_OUT_COEFF_3 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT3 */ - { STB0899_OFF4_EQ_Q_OUT_COEFF_4 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT4 */ - { STB0899_OFF5_EQ_Q_OUT_COEFF_5 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT5 */ - { STB0899_OFF6_EQ_Q_OUT_COEFF_6 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT6 */ - { STB0899_OFF7_EQ_Q_OUT_COEFF_7 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT7 */ - { STB0899_OFF8_EQ_Q_OUT_COEFF_8 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT8 */ - { STB0899_OFF9_EQ_Q_OUT_COEFF_9 , STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT9 */ - { STB0899_OFFa_EQ_Q_OUT_COEFF_10, STB0899_BASE_EQ_Q_OUT_COEFF_N , 0x00000000 }, /* EQQCOEFFSOUT10*/ - { 0xffff , 0xffffffff , 0xffffffff }, -}; -static const struct stb0899_s2_reg stb0899_s2_init_4[] = { - { STB0899_OFF0_BLOCK_LNGTH , STB0899_BASE_BLOCK_LNGTH , 0x00000008 }, /* BLOCKLNGTH */ - { STB0899_OFF0_ROW_STR , STB0899_BASE_ROW_STR , 0x000000b4 }, /* ROWSTR */ - { STB0899_OFF0_BN_END_ADDR , STB0899_BASE_BN_END_ADDR , 0x000004b5 }, /* BNANDADDR */ - { STB0899_OFF0_CN_END_ADDR , STB0899_BASE_CN_END_ADDR , 0x00000b4b }, /* CNANDADDR */ - { STB0899_OFF0_INFO_LENGTH , STB0899_BASE_INFO_LENGTH , 0x00000078 }, /* INFOLENGTH */ - { STB0899_OFF0_BOT_ADDR , STB0899_BASE_BOT_ADDR , 0x000001e0 }, /* BOT_ADDR */ - { STB0899_OFF0_BCH_BLK_LN , STB0899_BASE_BCH_BLK_LN , 0x0000a8c0 }, /* BCHBLKLN */ - { STB0899_OFF0_BCH_T , STB0899_BASE_BCH_T , 0x0000000c }, /* BCHT */ - { STB0899_OFF0_CNFG_MODE , STB0899_BASE_CNFG_MODE , 0x00000001 }, /* CNFGMODE */ - { STB0899_OFF0_LDPC_STAT , STB0899_BASE_LDPC_STAT , 0x0000000d }, /* LDPCSTAT */ - { STB0899_OFF0_ITER_SCALE , STB0899_BASE_ITER_SCALE , 0x00000040 }, /* ITERSCALE */ - { STB0899_OFF0_INPUT_MODE , STB0899_BASE_INPUT_MODE , 0x00000000 }, /* INPUTMODE */ - { STB0899_OFF0_LDPCDECRST , STB0899_BASE_LDPCDECRST , 0x00000000 }, /* LDPCDECRST */ - { STB0899_OFF0_CLK_PER_BYTE_RW , STB0899_BASE_CLK_PER_BYTE_RW , 0x00000008 }, /* CLKPERBYTE */ - { STB0899_OFF0_BCH_ERRORS , STB0899_BASE_BCH_ERRORS , 0x00000000 }, /* BCHERRORS */ - { STB0899_OFF0_LDPC_ERRORS , STB0899_BASE_LDPC_ERRORS , 0x00000000 }, /* LDPCERRORS */ - { STB0899_OFF0_BCH_MODE , STB0899_BASE_BCH_MODE , 0x00000000 }, /* BCHMODE */ - { STB0899_OFF0_ERR_ACC_PER , STB0899_BASE_ERR_ACC_PER , 0x00000008 }, /* ERRACCPER */ - { STB0899_OFF0_BCH_ERR_ACC , STB0899_BASE_BCH_ERR_ACC , 0x00000000 }, /* BCHERRACC */ - { STB0899_OFF0_FEC_TP_SEL , STB0899_BASE_FEC_TP_SEL , 0x00000000 }, /* FECTPSEL */ - { 0xffff , 0xffffffff , 0xffffffff }, -}; - -static const struct stb0899_s1_reg stb0899_s1_init_5[] = { - { STB0899_TSTCK , 0x00 }, - { STB0899_TSTRES , 0x00 }, - { STB0899_TSTOUT , 0x00 }, - { STB0899_TSTIN , 0x00 }, - { STB0899_TSTSYS , 0x00 }, - { STB0899_TSTCHIP , 0x00 }, - { STB0899_TSTFREE , 0x00 }, - { STB0899_TSTI2C , 0x00 }, - { STB0899_BITSPEEDM , 0x00 }, - { STB0899_BITSPEEDL , 0x00 }, - { STB0899_TBUSBIT , 0x00 }, - { STB0899_TSTDIS , 0x00 }, - { STB0899_TSTDISRX , 0x00 }, - { STB0899_TSTJETON , 0x00 }, - { STB0899_TSTDCADJ , 0x00 }, - { STB0899_TSTAGC1 , 0x00 }, - { STB0899_TSTAGC1N , 0x00 }, - { STB0899_TSTPOLYPH , 0x00 }, - { STB0899_TSTR , 0x00 }, - { STB0899_TSTAGC2 , 0x00 }, - { STB0899_TSTCTL1 , 0x00 }, - { STB0899_TSTCTL2 , 0x00 }, - { STB0899_TSTCTL3 , 0x00 }, - { STB0899_TSTDEMAP , 0x00 }, - { STB0899_TSTDEMAP2 , 0x00 }, - { STB0899_TSTDEMMON , 0x00 }, - { STB0899_TSTRATE , 0x00 }, - { STB0899_TSTSELOUT , 0x00 }, - { STB0899_TSYNC , 0x00 }, - { STB0899_TSTERR , 0x00 }, - { STB0899_TSTRAM1 , 0x00 }, - { STB0899_TSTVSELOUT , 0x00 }, - { STB0899_TSTFORCEIN , 0x00 }, - { STB0899_TSTRS1 , 0x00 }, - { STB0899_TSTRS2 , 0x00 }, - { STB0899_TSTRS3 , 0x00 }, - { STB0899_GHOSTREG , 0x81 }, - { 0xffff , 0xff }, -}; - -#define STB0899_DVBS2_ESNO_AVE 3 -#define STB0899_DVBS2_ESNO_QUANT 32 -#define STB0899_DVBS2_AVFRAMES_COARSE 10 -#define STB0899_DVBS2_AVFRAMES_FINE 20 -#define STB0899_DVBS2_MISS_THRESHOLD 6 -#define STB0899_DVBS2_UWP_THRESHOLD_ACQ 1125 -#define STB0899_DVBS2_UWP_THRESHOLD_TRACK 758 -#define STB0899_DVBS2_UWP_THRESHOLD_SOF 1350 -#define STB0899_DVBS2_SOF_SEARCH_TIMEOUT 1664100 - -#define STB0899_DVBS2_BTR_NCO_BITS 28 -#define STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET 15 -#define STB0899_DVBS2_CRL_NCO_BITS 30 -#define STB0899_DVBS2_LDPC_MAX_ITER 70 - -#endif //__STB0899_CFG_H diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c deleted file mode 100644 index 10613acf18f..00000000000 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ /dev/null @@ -1,1685 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -#include "stb0899_drv.h" -#include "stb0899_priv.h" -#include "stb0899_reg.h" - -static unsigned int verbose = 0;//1; -module_param(verbose, int, 0644); - -/* C/N in dB/10, NIRM/NIRL */ -static const struct stb0899_tab stb0899_cn_tab[] = { - { 200, 2600 }, - { 190, 2700 }, - { 180, 2860 }, - { 170, 3020 }, - { 160, 3210 }, - { 150, 3440 }, - { 140, 3710 }, - { 130, 4010 }, - { 120, 4360 }, - { 110, 4740 }, - { 100, 5190 }, - { 90, 5670 }, - { 80, 6200 }, - { 70, 6770 }, - { 60, 7360 }, - { 50, 7970 }, - { 40, 8250 }, - { 30, 9000 }, - { 20, 9450 }, - { 15, 9600 }, -}; - -/* DVB-S AGCIQ_VALUE vs. signal level in dBm/10. - * As measured, connected to a modulator. - * -8.0 to -50.0 dBm directly connected, - * -52.0 to -74.8 with extra attenuation. - * Cut-off to AGCIQ_VALUE = 0x80 below -74.8dBm. - * Crude linear extrapolation below -84.8dBm and above -8.0dBm. - */ -static const struct stb0899_tab stb0899_dvbsrf_tab[] = { - { -950, -128 }, - { -748, -94 }, - { -745, -92 }, - { -735, -90 }, - { -720, -87 }, - { -670, -77 }, - { -640, -70 }, - { -610, -62 }, - { -600, -60 }, - { -590, -56 }, - { -560, -41 }, - { -540, -25 }, - { -530, -17 }, - { -520, -11 }, - { -500, 1 }, - { -490, 6 }, - { -480, 10 }, - { -440, 22 }, - { -420, 27 }, - { -400, 31 }, - { -380, 34 }, - { -340, 40 }, - { -320, 43 }, - { -280, 48 }, - { -250, 52 }, - { -230, 55 }, - { -180, 61 }, - { -140, 66 }, - { -90, 73 }, - { -80, 74 }, - { 500, 127 } -}; - -/* DVB-S2 IF_AGC_GAIN vs. signal level in dBm/10. - * As measured, connected to a modulator. - * -8.0 to -50.1 dBm directly connected, - * -53.0 to -76.6 with extra attenuation. - * Cut-off to IF_AGC_GAIN = 0x3fff below -76.6dBm. - * Crude linear extrapolation below -76.6dBm and above -8.0dBm. - */ -static const struct stb0899_tab stb0899_dvbs2rf_tab[] = { - { 700, 0 }, - { -80, 3217 }, - { -150, 3893 }, - { -190, 4217 }, - { -240, 4621 }, - { -280, 4945 }, - { -320, 5273 }, - { -350, 5545 }, - { -370, 5741 }, - { -410, 6147 }, - { -450, 6671 }, - { -490, 7413 }, - { -501, 7665 }, - { -530, 8767 }, - { -560, 10219 }, - { -580, 10939 }, - { -590, 11518 }, - { -600, 11723 }, - { -650, 12659 }, - { -690, 13219 }, - { -730, 13645 }, - { -750, 13909 }, - { -766, 14153 }, - { -999, 16383 } -}; - -/* DVB-S2 Es/N0 quant in dB/100 vs read value * 100*/ -static struct stb0899_tab stb0899_quant_tab[] = { - { 0, 0 }, - { 0, 100 }, - { 600, 200 }, - { 950, 299 }, - { 1200, 398 }, - { 1400, 501 }, - { 1560, 603 }, - { 1690, 700 }, - { 1810, 804 }, - { 1910, 902 }, - { 2000, 1000 }, - { 2080, 1096 }, - { 2160, 1202 }, - { 2230, 1303 }, - { 2350, 1496 }, - { 2410, 1603 }, - { 2460, 1698 }, - { 2510, 1799 }, - { 2600, 1995 }, - { 2650, 2113 }, - { 2690, 2213 }, - { 2720, 2291 }, - { 2760, 2399 }, - { 2800, 2512 }, - { 2860, 2692 }, - { 2930, 2917 }, - { 2960, 3020 }, - { 3010, 3199 }, - { 3040, 3311 }, - { 3060, 3388 }, - { 3120, 3631 }, - { 3190, 3936 }, - { 3400, 5012 }, - { 3610, 6383 }, - { 3800, 7943 }, - { 4210, 12735 }, - { 4500, 17783 }, - { 4690, 22131 }, - { 4810, 25410 } -}; - -/* DVB-S2 Es/N0 estimate in dB/100 vs read value */ -static struct stb0899_tab stb0899_est_tab[] = { - { 0, 0 }, - { 0, 1 }, - { 301, 2 }, - { 1204, 16 }, - { 1806, 64 }, - { 2408, 256 }, - { 2709, 512 }, - { 3010, 1023 }, - { 3311, 2046 }, - { 3612, 4093 }, - { 3823, 6653 }, - { 3913, 8185 }, - { 4010, 10233 }, - { 4107, 12794 }, - { 4214, 16368 }, - { 4266, 18450 }, - { 4311, 20464 }, - { 4353, 22542 }, - { 4391, 24604 }, - { 4425, 26607 }, - { 4457, 28642 }, - { 4487, 30690 }, - { 4515, 32734 }, - { 4612, 40926 }, - { 4692, 49204 }, - { 4816, 65464 }, - { 4913, 81846 }, - { 4993, 98401 }, - { 5060, 114815 }, - { 5118, 131220 }, - { 5200, 158489 }, - { 5300, 199526 }, - { 5400, 251189 }, - { 5500, 316228 }, - { 5600, 398107 }, - { 5720, 524807 }, - { 5721, 526017 }, -}; - -static int _stb0899_read_reg(struct stb0899_state *state, unsigned int reg) -{ - int ret; - - u8 b0[] = { reg >> 8, reg & 0xff }; - u8 buf; - - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 2 - },{ - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = &buf, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) { - if (ret != -ERESTARTSYS) - dprintk(state->verbose, FE_ERROR, 1, - "Read error, Reg=[0x%02x], Status=%d", - reg, ret); - - return ret < 0 ? ret : -EREMOTEIO; - } - if (unlikely(*state->verbose >= FE_DEBUGREG)) - dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%02x], data=%02x", - reg, buf); - - return (unsigned int)buf; -} - -int stb0899_read_reg(struct stb0899_state *state, unsigned int reg) -{ - int result; - - result = _stb0899_read_reg(state, reg); - /* - * Bug ID 9: - * access to 0xf2xx/0xf6xx - * must be followed by read from 0xf2ff/0xf6ff. - */ - if ((reg != 0xf2ff) && (reg != 0xf6ff) && - (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) - _stb0899_read_reg(state, (reg | 0x00ff)); - - return result; -} - -u32 _stb0899_read_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset) -{ - int status; - u32 data; - u8 buf[7] = { 0 }; - u16 tmpaddr; - - u8 buf_0[] = { - GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */ - GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */ - GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */ - }; - u8 buf_1[] = { - 0x00, /* 0xf3 Reg Offset */ - 0x00, /* 0x44 Reg Offset */ - }; - - struct i2c_msg msg_0 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_0, - .len = 6 - }; - - struct i2c_msg msg_1 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_1, - .len = 2 - }; - - struct i2c_msg msg_r = { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = buf, - .len = 4 - }; - - tmpaddr = stb0899_reg_offset & 0xff00; - if (!(stb0899_reg_offset & 0x8)) - tmpaddr = stb0899_reg_offset | 0x20; - - buf_1[0] = GETBYTE(tmpaddr, BYTE1); - buf_1[1] = GETBYTE(tmpaddr, BYTE0); - - status = i2c_transfer(state->i2c, &msg_0, 1); - if (status < 1) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR(1), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); - - goto err; - } - - /* Dummy */ - status = i2c_transfer(state->i2c, &msg_1, 1); - if (status < 1) - goto err; - - status = i2c_transfer(state->i2c, &msg_r, 1); - if (status < 1) - goto err; - - buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1); - buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0); - - /* Actual */ - status = i2c_transfer(state->i2c, &msg_1, 1); - if (status < 1) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR(2), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); - goto err; - } - - status = i2c_transfer(state->i2c, &msg_r, 1); - if (status < 1) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR(3), Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, status); - return status < 0 ? status : -EREMOTEIO; - } - - data = MAKEWORD32(buf[3], buf[2], buf[1], buf[0]); - if (unlikely(*state->verbose >= FE_DEBUGREG)) - printk(KERN_DEBUG "%s Device=[0x%04x], Base address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, data); - - return data; - -err: - return status < 0 ? status : -EREMOTEIO; -} - -int stb0899_write_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset, - u32 stb0899_data) -{ - int status; - - /* Base Address Setup */ - u8 buf_0[] = { - GETBYTE(stb0899_i2cdev, BYTE1), /* 0xf3 S2 Base Address (MSB) */ - GETBYTE(stb0899_i2cdev, BYTE0), /* 0xfc S2 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE0), /* 0x00 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE1), /* 0x04 Base Address (LSB) */ - GETBYTE(stb0899_base_addr, BYTE2), /* 0x00 Base Address (MSB) */ - GETBYTE(stb0899_base_addr, BYTE3), /* 0x00 Base Address (MSB) */ - }; - u8 buf_1[] = { - 0x00, /* 0xf3 Reg Offset */ - 0x00, /* 0x44 Reg Offset */ - 0x00, /* data */ - 0x00, /* data */ - 0x00, /* data */ - 0x00, /* data */ - }; - - struct i2c_msg msg_0 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_0, - .len = 6 - }; - - struct i2c_msg msg_1 = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf_1, - .len = 6 - }; - - buf_1[0] = GETBYTE(stb0899_reg_offset, BYTE1); - buf_1[1] = GETBYTE(stb0899_reg_offset, BYTE0); - buf_1[2] = GETBYTE(stb0899_data, BYTE0); - buf_1[3] = GETBYTE(stb0899_data, BYTE1); - buf_1[4] = GETBYTE(stb0899_data, BYTE2); - buf_1[5] = GETBYTE(stb0899_data, BYTE3); - - if (unlikely(*state->verbose >= FE_DEBUGREG)) - printk(KERN_DEBUG "%s Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x]\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data); - - status = i2c_transfer(state->i2c, &msg_0, 1); - if (unlikely(status < 1)) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR (1), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status); - goto err; - } - status = i2c_transfer(state->i2c, &msg_1, 1); - if (unlikely(status < 1)) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s ERR (2), Device=[0x%04x], Base Address=[0x%08x], Offset=[0x%04x], Data=[0x%08x], status=%d\n", - __func__, stb0899_i2cdev, stb0899_base_addr, stb0899_reg_offset, stb0899_data, status); - - return status < 0 ? status : -EREMOTEIO; - } - - return 0; - -err: - return status < 0 ? status : -EREMOTEIO; -} - -int stb0899_read_regs(struct stb0899_state *state, unsigned int reg, u8 *buf, u32 count) -{ - int status; - - u8 b0[] = { reg >> 8, reg & 0xff }; - - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 2 - },{ - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = buf, - .len = count - } - }; - - status = i2c_transfer(state->i2c, msg, 2); - if (status != 2) { - if (status != -ERESTARTSYS) - printk(KERN_ERR "%s Read error, Reg=[0x%04x], Count=%u, Status=%d\n", - __func__, reg, count, status); - goto err; - } - /* - * Bug ID 9: - * access to 0xf2xx/0xf6xx - * must be followed by read from 0xf2ff/0xf6ff. - */ - if ((reg != 0xf2ff) && (reg != 0xf6ff) && - (((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) - _stb0899_read_reg(state, (reg | 0x00ff)); - - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) { - printk(" %02x", buf[i]); - } - printk("\n"); - } - - return 0; -err: - return status < 0 ? status : -EREMOTEIO; -} - -int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data, u32 count) -{ - int ret; - u8 buf[2 + count]; - struct i2c_msg i2c_msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 + count - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - memcpy(&buf[2], data, count); - - if (unlikely(*state->verbose >= FE_DEBUGREG)) { - int i; - - printk(KERN_DEBUG "%s [0x%04x]:", __func__, reg); - for (i = 0; i < count; i++) - printk(" %02x", data[i]); - printk("\n"); - } - ret = i2c_transfer(state->i2c, &i2c_msg, 1); - - /* - * Bug ID 9: - * access to 0xf2xx/0xf6xx - * must be followed by read from 0xf2ff/0xf6ff. - */ - if ((((reg & 0xff00) == 0xf200) || ((reg & 0xff00) == 0xf600))) - stb0899_read_reg(state, (reg | 0x00ff)); - - if (ret != 1) { - if (ret != -ERESTARTSYS) - dprintk(state->verbose, FE_ERROR, 1, "Reg=[0x%04x], Data=[0x%02x ...], Count=%u, Status=%d", - reg, data[0], count, ret); - return ret < 0 ? ret : -EREMOTEIO; - } - - return 0; -} - -int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data) -{ - return stb0899_write_regs(state, reg, &data, 1); -} - -/* - * stb0899_get_mclk - * Get STB0899 master clock frequency - * ExtClk: external clock frequency (Hz) - */ -static u32 stb0899_get_mclk(struct stb0899_state *state) -{ - u32 mclk = 0, div = 0; - - div = stb0899_read_reg(state, STB0899_NCOARSE); - mclk = (div + 1) * state->config->xtal_freq / 6; - dprintk(state->verbose, FE_DEBUG, 1, "div=%d, mclk=%d", div, mclk); - - return mclk; -} - -/* - * stb0899_set_mclk - * Set STB0899 master Clock frequency - * Mclk: demodulator master clock - * ExtClk: external clock frequency (Hz) - */ -static void stb0899_set_mclk(struct stb0899_state *state, u32 Mclk) -{ - struct stb0899_internal *internal = &state->internal; - u8 mdiv = 0; - - dprintk(state->verbose, FE_DEBUG, 1, "state->config=%p", state->config); - mdiv = ((6 * Mclk) / state->config->xtal_freq) - 1; - dprintk(state->verbose, FE_DEBUG, 1, "mdiv=%d", mdiv); - - stb0899_write_reg(state, STB0899_NCOARSE, mdiv); - internal->master_clk = stb0899_get_mclk(state); - - dprintk(state->verbose, FE_DEBUG, 1, "MasterCLOCK=%d", internal->master_clk); -} - -static int stb0899_postproc(struct stb0899_state *state, u8 ctl, int enable) -{ - struct stb0899_config *config = state->config; - const struct stb0899_postproc *postproc = config->postproc; - - /* post process event */ - if (postproc) { - if (enable) { - if (postproc[ctl].level == STB0899_GPIOPULLUP) - stb0899_write_reg(state, postproc[ctl].gpio, 0x02); - else - stb0899_write_reg(state, postproc[ctl].gpio, 0x82); - } else { - if (postproc[ctl].level == STB0899_GPIOPULLUP) - stb0899_write_reg(state, postproc[ctl].gpio, 0x82); - else - stb0899_write_reg(state, postproc[ctl].gpio, 0x02); - } - } - return 0; -} - -static void stb0899_release(struct dvb_frontend *fe) -{ - struct stb0899_state *state = fe->demodulator_priv; - - dprintk(state->verbose, FE_DEBUG, 1, "Release Frontend"); - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); - kfree(state); -} - -/* - * stb0899_get_alpha - * return: rolloff - */ -static int stb0899_get_alpha(struct stb0899_state *state) -{ - u8 mode_coeff; - - mode_coeff = stb0899_read_reg(state, STB0899_DEMOD); - - if (STB0899_GETFIELD(MODECOEFF, mode_coeff) == 1) - return 20; - else - return 35; -} - -/* - * stb0899_init_calc - */ -static void stb0899_init_calc(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - int master_clk; - u8 agc[2]; - u8 agc1cn; - u32 reg; - - /* Read registers (in burst mode) */ - agc1cn = stb0899_read_reg(state, STB0899_AGC1CN); - stb0899_read_regs(state, STB0899_AGC1REF, agc, 2); /* AGC1R and AGC2O */ - - /* Initial calculations */ - master_clk = stb0899_get_mclk(state); - internal->t_agc1 = 0; - internal->t_agc2 = 0; - internal->master_clk = master_clk; - internal->mclk = master_clk / 65536L; - internal->rolloff = stb0899_get_alpha(state); - - /* DVBS2 Initial calculations */ - /* Set AGC value to the middle */ - internal->agc_gain = 8154; - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, IF_AGC_CNTRL); - STB0899_SETFIELD_VAL(IF_GAIN_INIT, reg, internal->agc_gain); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_IF_AGC_CNTRL, STB0899_OFF0_IF_AGC_CNTRL, reg); - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, RRC_ALPHA); - internal->rrc_alpha = STB0899_GETFIELD(RRC_ALPHA, reg); - - internal->center_freq = 0; - internal->av_frame_coarse = 10; - internal->av_frame_fine = 20; - internal->step_size = 2; -/* - if ((pParams->SpectralInv == FE_IQ_NORMAL) || (pParams->SpectralInv == FE_IQ_AUTO)) - pParams->IQLocked = 0; - else - pParams->IQLocked = 1; -*/ -} - -static int stb0899_wait_diseqc_fifo_empty(struct stb0899_state *state, int timeout) -{ - u8 reg = 0; - unsigned long start = jiffies; - - while (1) { - reg = stb0899_read_reg(state, STB0899_DISSTATUS); - if (!STB0899_GETFIELD(FIFOFULL, reg)) - break; - if ((jiffies - start) > timeout) { - dprintk(state->verbose, FE_ERROR, 1, "timed out !!"); - return -ETIMEDOUT; - } - } - - return 0; -} - -static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_master_cmd *cmd) -{ - struct stb0899_state *state = fe->demodulator_priv; - u8 reg, i; - - if (cmd->msg_len > 8) - return -EINVAL; - - /* enable FIFO precharge */ - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 1); - 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) - return -ETIMEDOUT; - - stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]); - } - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - - return 0; -} - -static int stb0899_wait_diseqc_rxidle(struct stb0899_state *state, int timeout) -{ - u8 reg = 0; - unsigned long start = jiffies; - - while (!STB0899_GETFIELD(RXEND, reg)) { - reg = stb0899_read_reg(state, STB0899_DISRX_ST0); - if (jiffies - start > timeout) { - dprintk(state->verbose, FE_ERROR, 1, "timed out!!"); - return -ETIMEDOUT; - } - msleep(10); - } - - return 0; -} - -static int stb0899_recv_slave_reply(struct dvb_frontend *fe, struct dvb_diseqc_slave_reply *reply) -{ - struct stb0899_state *state = fe->demodulator_priv; - u8 reg, length = 0, i; - int result; - - if (stb0899_wait_diseqc_rxidle(state, 100) < 0) - return -ETIMEDOUT; - - reg = stb0899_read_reg(state, STB0899_DISRX_ST0); - if (STB0899_GETFIELD(RXEND, reg)) { - - reg = stb0899_read_reg(state, STB0899_DISRX_ST1); - length = STB0899_GETFIELD(FIFOBYTENBR, reg); - - if (length > sizeof (reply->msg)) { - result = -EOVERFLOW; - goto exit; - } - reply->msg_len = length; - - /* extract data */ - for (i = 0; i < length; i++) - reply->msg[i] = stb0899_read_reg(state, STB0899_DISFIFO); - } - - return 0; -exit: - - return result; -} - -static int stb0899_wait_diseqc_txidle(struct stb0899_state *state, int timeout) -{ - u8 reg = 0; - unsigned long start = jiffies; - - while (!STB0899_GETFIELD(TXIDLE, reg)) { - reg = stb0899_read_reg(state, STB0899_DISSTATUS); - if (jiffies - start > timeout) { - dprintk(state->verbose, FE_ERROR, 1, "timed out!!"); - return -ETIMEDOUT; - } - msleep(10); - } - return 0; -} - -static int stb0899_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) -{ - struct stb0899_state *state = fe->demodulator_priv; - u8 reg, old_state; - - /* wait for diseqc idle */ - if (stb0899_wait_diseqc_txidle(state, 100) < 0) - return -ETIMEDOUT; - - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - old_state = reg; - /* set to burst mode */ - STB0899_SETFIELD_VAL(DISEQCMODE, reg, 0x02); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x01); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - switch (burst) { - case SEC_MINI_A: - /* unmodulated */ - stb0899_write_reg(state, STB0899_DISFIFO, 0x00); - break; - case SEC_MINI_B: - /* modulated */ - stb0899_write_reg(state, STB0899_DISFIFO, 0xff); - break; - } - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISPRECHARGE, reg, 0x00); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - /* wait for diseqc idle */ - if (stb0899_wait_diseqc_txidle(state, 100) < 0) - return -ETIMEDOUT; - - /* restore state */ - stb0899_write_reg(state, STB0899_DISCNTRL1, old_state); - - return 0; -} - -static int stb0899_diseqc_init(struct stb0899_state *state) -{ - struct dvb_diseqc_master_cmd tx_data; -/* - struct dvb_diseqc_slave_reply rx_data; -*/ - u8 f22_tx, f22_rx, reg; - - u32 mclk, tx_freq = 22000;/* count = 0, i; */ - tx_data.msg[0] = 0xe2; - tx_data.msg_len = 3; - reg = stb0899_read_reg(state, STB0899_DISCNTRL2); - STB0899_SETFIELD_VAL(ONECHIP_TRX, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL2, reg); - - /* disable Tx spy */ - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISEQCRESET, reg, 1); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - - reg = stb0899_read_reg(state, STB0899_DISCNTRL1); - STB0899_SETFIELD_VAL(DISEQCRESET, reg, 0); - stb0899_write_reg(state, STB0899_DISCNTRL1, reg); - - mclk = stb0899_get_mclk(state); - f22_tx = mclk / (tx_freq * 32); - stb0899_write_reg(state, STB0899_DISF22, f22_tx); /* DiSEqC Tx freq */ - state->rx_freq = 20000; - f22_rx = mclk / (state->rx_freq * 32); - - return 0; -} - -static int stb0899_sleep(struct dvb_frontend *fe) -{ - struct stb0899_state *state = fe->demodulator_priv; -/* - u8 reg; -*/ - dprintk(state->verbose, FE_DEBUG, 1, "Going to Sleep .. (Really tired .. :-))"); - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 0); - - return 0; -} - -static int stb0899_wakeup(struct dvb_frontend *fe) -{ - int rc; - struct stb0899_state *state = fe->demodulator_priv; - - if ((rc = stb0899_write_reg(state, STB0899_SYNTCTRL, STB0899_SELOSCI))) - return rc; - /* Activate all clocks; DVB-S2 registers are inaccessible otherwise. */ - if ((rc = stb0899_write_reg(state, STB0899_STOPCLK1, 0x00))) - return rc; - if ((rc = stb0899_write_reg(state, STB0899_STOPCLK2, 0x00))) - return rc; - - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_POWER, 1); - - return 0; -} - -static int stb0899_init(struct dvb_frontend *fe) -{ - int i; - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_config *config = state->config; - - dprintk(state->verbose, FE_DEBUG, 1, "Initializing STB0899 ... "); - - /* init device */ - dprintk(state->verbose, FE_DEBUG, 1, "init device"); - for (i = 0; config->init_dev[i].address != 0xffff; i++) - stb0899_write_reg(state, config->init_dev[i].address, config->init_dev[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init S2 demod"); - /* init S2 demod */ - for (i = 0; config->init_s2_demod[i].offset != 0xffff; i++) - stb0899_write_s2reg(state, STB0899_S2DEMOD, - config->init_s2_demod[i].base_address, - config->init_s2_demod[i].offset, - config->init_s2_demod[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init S1 demod"); - /* init S1 demod */ - for (i = 0; config->init_s1_demod[i].address != 0xffff; i++) - stb0899_write_reg(state, config->init_s1_demod[i].address, config->init_s1_demod[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init S2 FEC"); - /* init S2 fec */ - for (i = 0; config->init_s2_fec[i].offset != 0xffff; i++) - stb0899_write_s2reg(state, STB0899_S2FEC, - config->init_s2_fec[i].base_address, - config->init_s2_fec[i].offset, - config->init_s2_fec[i].data); - - dprintk(state->verbose, FE_DEBUG, 1, "init TST"); - /* init test */ - for (i = 0; config->init_tst[i].address != 0xffff; i++) - stb0899_write_reg(state, config->init_tst[i].address, config->init_tst[i].data); - - stb0899_init_calc(state); - stb0899_diseqc_init(state); - - return 0; -} - -static int stb0899_table_lookup(const struct stb0899_tab *tab, int max, int val) -{ - int res = 0; - int min = 0, med; - - if (val < tab[min].read) - res = tab[min].real; - else if (val >= tab[max].read) - res = tab[max].real; - else { - while ((max - min) > 1) { - med = (max + min) / 2; - if (val >= tab[min].read && val < tab[med].read) - max = med; - else - min = med; - } - res = ((val - tab[min].read) * - (tab[max].real - tab[min].real) / - (tab[max].read - tab[min].read)) + - tab[min].real; - } - - return res; -} - -static int stb0899_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - int val; - u32 reg; - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - if (internal->lock) { - reg = stb0899_read_reg(state, STB0899_VSTATUS); - if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { - - reg = stb0899_read_reg(state, STB0899_AGCIQIN); - val = (s32)(s8)STB0899_GETFIELD(AGCIQVALUE, reg); - - *strength = stb0899_table_lookup(stb0899_dvbsrf_tab, ARRAY_SIZE(stb0899_dvbsrf_tab) - 1, val); - *strength += 750; - dprintk(state->verbose, FE_DEBUG, 1, "AGCIQVALUE = 0x%02x, C = %d * 0.1 dBm", - val & 0xff, *strength); - } - } - break; - case SYS_DVBS2: - if (internal->lock) { - reg = STB0899_READ_S2REG(STB0899_DEMOD, IF_AGC_GAIN); - val = STB0899_GETFIELD(IF_AGC_GAIN, reg); - - *strength = stb0899_table_lookup(stb0899_dvbs2rf_tab, ARRAY_SIZE(stb0899_dvbs2rf_tab) - 1, val); - *strength += 750; - dprintk(state->verbose, FE_DEBUG, 1, "IF_AGC_GAIN = 0x%04x, C = %d * 0.1 dBm", - val & 0x3fff, *strength); - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - - return 0; -} - -static int stb0899_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - unsigned int val, quant, quantn = -1, est, estn = -1; - u8 buf[2]; - u32 reg; - - reg = stb0899_read_reg(state, STB0899_VSTATUS); - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - if (internal->lock) { - if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { - - stb0899_read_regs(state, STB0899_NIRM, buf, 2); - val = MAKEWORD16(buf[0], buf[1]); - - *snr = stb0899_table_lookup(stb0899_cn_tab, ARRAY_SIZE(stb0899_cn_tab) - 1, val); - dprintk(state->verbose, FE_DEBUG, 1, "NIR = 0x%02x%02x = %u, C/N = %d * 0.1 dBm\n", - buf[0], buf[1], val, *snr); - } - } - break; - case SYS_DVBS2: - if (internal->lock) { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_CNTRL1); - quant = STB0899_GETFIELD(UWP_ESN0_QUANT, reg); - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, UWP_STAT2); - est = STB0899_GETFIELD(ESN0_EST, reg); - if (est == 1) - val = 301; /* C/N = 30.1 dB */ - else if (est == 2) - val = 270; /* C/N = 27.0 dB */ - else { - /* quantn = 100 * log(quant^2) */ - quantn = stb0899_table_lookup(stb0899_quant_tab, ARRAY_SIZE(stb0899_quant_tab) - 1, quant * 100); - /* estn = 100 * log(est) */ - estn = stb0899_table_lookup(stb0899_est_tab, ARRAY_SIZE(stb0899_est_tab) - 1, est); - /* snr(dBm/10) = -10*(log(est)-log(quant^2)) => snr(dBm/10) = (100*log(quant^2)-100*log(est))/10 */ - val = (quantn - estn) / 10; - } - *snr = val; - dprintk(state->verbose, FE_DEBUG, 1, "Es/N0 quant = %d (%d) estimate = %u (%d), C/N = %d * 0.1 dBm", - quant, quantn, est, estn, val); - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - - return 0; -} - -static int stb0899_read_status(struct dvb_frontend *fe, enum fe_status *status) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - u8 reg; - *status = 0; - - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S/DSS"); - if (internal->lock) { - reg = stb0899_read_reg(state, STB0899_VSTATUS); - if (STB0899_GETFIELD(VSTATUS_LOCKEDVIT, reg)) { - dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_CARRIER | FE_HAS_LOCK"); - *status |= FE_HAS_CARRIER | FE_HAS_LOCK; - - reg = stb0899_read_reg(state, STB0899_PLPARM); - if (STB0899_GETFIELD(VITCURPUN, reg)) { - dprintk(state->verbose, FE_DEBUG, 1, "--------> FE_HAS_VITERBI | FE_HAS_SYNC"); - *status |= FE_HAS_VITERBI | FE_HAS_SYNC; - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1); - } - } - } - break; - case SYS_DVBS2: - dprintk(state->verbose, FE_DEBUG, 1, "Delivery system DVB-S2"); - if (internal->lock) { - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_STAT2); - if (STB0899_GETFIELD(UWP_LOCK, reg) && STB0899_GETFIELD(CSM_LOCK, reg)) { - *status |= FE_HAS_CARRIER; - dprintk(state->verbose, FE_DEBUG, 1, - "UWP & CSM Lock ! ---> DVB-S2 FE_HAS_CARRIER"); - - reg = stb0899_read_reg(state, STB0899_CFGPDELSTATUS1); - if (STB0899_GETFIELD(CFGPDELSTATUS_LOCK, reg)) { - *status |= FE_HAS_LOCK; - dprintk(state->verbose, FE_DEBUG, 1, - "Packet Delineator Locked ! -----> DVB-S2 FE_HAS_LOCK"); - - } - if (STB0899_GETFIELD(CONTINUOUS_STREAM, reg)) { - *status |= FE_HAS_VITERBI; - dprintk(state->verbose, FE_DEBUG, 1, - "Packet Delineator found VITERBI ! -----> DVB-S2 FE_HAS_VITERBI"); - } - if (STB0899_GETFIELD(ACCEPTED_STREAM, reg)) { - *status |= FE_HAS_SYNC; - dprintk(state->verbose, FE_DEBUG, 1, - "Packet Delineator found SYNC ! -----> DVB-S2 FE_HAS_SYNC"); - /* post process event */ - stb0899_postproc(state, STB0899_POSTPROC_GPIO_LOCK, 1); - } - } - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - return 0; -} - -/* - * stb0899_get_error - * viterbi error for DVB-S/DSS - * packet error for DVB-S2 - * Bit Error Rate or Packet Error Rate * 10 ^ 7 - */ -static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - u8 lsb, msb; - u32 i; - - *ber = 0; - - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - if (internal->lock) { - /* average 5 BER values */ - for (i = 0; i < 5; i++) { - msleep(100); - lsb = stb0899_read_reg(state, STB0899_ECNT1L); - msb = stb0899_read_reg(state, STB0899_ECNT1M); - *ber += MAKEWORD16(msb, lsb); - } - *ber /= 5; - /* Viterbi Check */ - if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) { - /* Error Rate */ - *ber *= 9766; - /* ber = ber * 10 ^ 7 */ - *ber /= (-1 + (1 << (2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); - *ber /= 8; - } - } - break; - case SYS_DVBS2: - if (internal->lock) { - /* Average 5 PER values */ - for (i = 0; i < 5; i++) { - msleep(100); - lsb = stb0899_read_reg(state, STB0899_ECNT1L); - msb = stb0899_read_reg(state, STB0899_ECNT1M); - *ber += MAKEWORD16(msb, lsb); - } - /* ber = ber * 10 ^ 7 */ - *ber *= 10000000; - *ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl)))); - } - break; - default: - dprintk(state->verbose, FE_DEBUG, 1, "Unsupported delivery system"); - return -EINVAL; - } - - return 0; -} - -static int stb0899_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - struct stb0899_state *state = fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82); - stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02); - stb0899_write_reg(state, STB0899_GPIO02CFG, 0x00); - break; - case SEC_VOLTAGE_18: - stb0899_write_reg(state, STB0899_GPIO00CFG, 0x02); - stb0899_write_reg(state, STB0899_GPIO01CFG, 0x02); - stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82); - break; - case SEC_VOLTAGE_OFF: - stb0899_write_reg(state, STB0899_GPIO00CFG, 0x82); - stb0899_write_reg(state, STB0899_GPIO01CFG, 0x82); - stb0899_write_reg(state, STB0899_GPIO02CFG, 0x82); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int stb0899_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - u8 div, reg; - - /* wait for diseqc idle */ - if (stb0899_wait_diseqc_txidle(state, 100) < 0) - return -ETIMEDOUT; - - switch (tone) { - case SEC_TONE_ON: - div = (internal->master_clk / 100) / 5632; - div = (div + 5) / 10; - stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x66); - reg = stb0899_read_reg(state, STB0899_ACRPRESC); - STB0899_SETFIELD_VAL(ACRPRESC, reg, 0x03); - stb0899_write_reg(state, STB0899_ACRPRESC, reg); - stb0899_write_reg(state, STB0899_ACRDIV1, div); - break; - case SEC_TONE_OFF: - stb0899_write_reg(state, STB0899_DISEQCOCFG, 0x20); - break; - default: - return -EINVAL; - } - return 0; -} - -int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - int i2c_stat; - struct stb0899_state *state = fe->demodulator_priv; - - i2c_stat = stb0899_read_reg(state, STB0899_I2CRPT); - if (i2c_stat < 0) - goto err; - - if (enable) { - dprintk(state->verbose, FE_DEBUG, 1, "Enabling I2C Repeater ..."); - i2c_stat |= STB0899_I2CTON; - if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) - goto err; - } else { - dprintk(state->verbose, FE_DEBUG, 1, "Disabling I2C Repeater ..."); - i2c_stat &= ~STB0899_I2CTON; - if (stb0899_write_reg(state, STB0899_I2CRPT, i2c_stat) < 0) - goto err; - } - return 0; -err: - dprintk(state->verbose, FE_ERROR, 1, "I2C Repeater control failed"); - return -EREMOTEIO; -} - - -static inline void CONVERT32(u32 x, char *str) -{ - *str++ = (x >> 24) & 0xff; - *str++ = (x >> 16) & 0xff; - *str++ = (x >> 8) & 0xff; - *str++ = (x >> 0) & 0xff; - *str = '\0'; -} - -int stb0899_get_dev_id(struct stb0899_state *state) -{ - u8 chip_id, release; - u16 id; - u32 demod_ver = 0, fec_ver = 0; - char demod_str[5] = { 0 }; - char fec_str[5] = { 0 }; - - id = stb0899_read_reg(state, STB0899_DEV_ID); - dprintk(state->verbose, FE_DEBUG, 1, "ID reg=[0x%02x]", id); - chip_id = STB0899_GETFIELD(CHIP_ID, id); - release = STB0899_GETFIELD(CHIP_REL, id); - - dprintk(state->verbose, FE_ERROR, 1, "Device ID=[%d], Release=[%d]", - chip_id, release); - - CONVERT32(STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_CORE_ID), (char *)&demod_str); - - demod_ver = STB0899_READ_S2REG(STB0899_S2DEMOD, DMD_VERSION_ID); - dprintk(state->verbose, FE_ERROR, 1, "Demodulator Core ID=[%s], Version=[%d]", (char *) &demod_str, demod_ver); - CONVERT32(STB0899_READ_S2REG(STB0899_S2FEC, FEC_CORE_ID_REG), (char *)&fec_str); - fec_ver = STB0899_READ_S2REG(STB0899_S2FEC, FEC_VER_ID_REG); - if (! (chip_id > 0)) { - dprintk(state->verbose, FE_ERROR, 1, "couldn't find a STB 0899"); - - return -ENODEV; - } - dprintk(state->verbose, FE_ERROR, 1, "FEC Core ID=[%s], Version=[%d]", (char*) &fec_str, fec_ver); - - return 0; -} - -static void stb0899_set_delivery(struct stb0899_state *state) -{ - u8 reg; - u8 stop_clk[2]; - - stop_clk[0] = stb0899_read_reg(state, STB0899_STOPCLK1); - stop_clk[1] = stb0899_read_reg(state, STB0899_STOPCLK2); - - switch (state->delsys) { - case SYS_DVBS: - dprintk(state->verbose, FE_DEBUG, 1, "Delivery System -- DVB-S"); - /* FECM/Viterbi ON */ - reg = stb0899_read_reg(state, STB0899_FECM); - STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); - STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1); - stb0899_write_reg(state, STB0899_FECM, reg); - - stb0899_write_reg(state, STB0899_RSULC, 0xb1); - stb0899_write_reg(state, STB0899_TSULC, 0x40); - stb0899_write_reg(state, STB0899_RSLLC, 0x42); - stb0899_write_reg(state, STB0899_TSLPL, 0x12); - - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESLDPC, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1); - - STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1); - STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); - - STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); - break; - case SYS_DVBS2: - /* FECM/Viterbi OFF */ - reg = stb0899_read_reg(state, STB0899_FECM); - STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 0); - STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 0); - stb0899_write_reg(state, STB0899_FECM, reg); - - stb0899_write_reg(state, STB0899_RSULC, 0xb1); - stb0899_write_reg(state, STB0899_TSULC, 0x42); - stb0899_write_reg(state, STB0899_RSLLC, 0x40); - stb0899_write_reg(state, STB0899_TSLPL, 0x02); - - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESLDPC, reg, 0); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 0); - STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 0); - STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 0); - - STB0899_SETFIELD_VAL(STOP_CKINTBUF216, stop_clk[0], 0); - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 0); - break; - case SYS_DSS: - /* FECM/Viterbi ON */ - reg = stb0899_read_reg(state, STB0899_FECM); - STB0899_SETFIELD_VAL(FECM_RSVD0, reg, 1); - STB0899_SETFIELD_VAL(FECM_VITERBI_ON, reg, 1); - stb0899_write_reg(state, STB0899_FECM, reg); - - stb0899_write_reg(state, STB0899_RSULC, 0xa1); - stb0899_write_reg(state, STB0899_TSULC, 0x61); - stb0899_write_reg(state, STB0899_RSLLC, 0x42); - - reg = stb0899_read_reg(state, STB0899_TSTRES); - STB0899_SETFIELD_VAL(FRESLDPC, reg, 1); - stb0899_write_reg(state, STB0899_TSTRES, reg); - - STB0899_SETFIELD_VAL(STOP_CHK8PSK, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC108, stop_clk[0], 1); - STB0899_SETFIELD_VAL(STOP_CKFEC216, stop_clk[0], 1); - - STB0899_SETFIELD_VAL(STOP_CKPKDLIN108, stop_clk[1], 1); - STB0899_SETFIELD_VAL(STOP_CKPKDLIN216, stop_clk[1], 1); - - STB0899_SETFIELD_VAL(STOP_CKCORE216, stop_clk[0], 0); - - STB0899_SETFIELD_VAL(STOP_CKS2DMD108, stop_clk[1], 1); - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - break; - } - STB0899_SETFIELD_VAL(STOP_CKADCI108, stop_clk[0], 0); - stb0899_write_regs(state, STB0899_STOPCLK1, stop_clk, 2); -} - -/* - * stb0899_set_iterations - * set the LDPC iteration scale function - */ -static void stb0899_set_iterations(struct stb0899_state *state) -{ - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - - s32 iter_scale; - u32 reg; - - iter_scale = 17 * (internal->master_clk / 1000); - iter_scale += 410000; - iter_scale /= (internal->srate / 1000000); - iter_scale /= 1000; - - if (iter_scale > config->ldpc_max_iter) - iter_scale = config->ldpc_max_iter; - - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, 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); -} - -static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_params *i_params = &state->params; - struct stb0899_internal *internal = &state->internal; - struct stb0899_config *config = state->config; - struct dtv_frontend_properties *props = &fe->dtv_property_cache; - - u32 SearchRange, gain; - - i_params->freq = p->frequency; - i_params->srate = p->u.qpsk.symbol_rate; - state->delsys = props->delivery_system; - dprintk(state->verbose, FE_DEBUG, 1, "delivery system=%d", state->delsys); - - SearchRange = 10000000; - dprintk(state->verbose, FE_DEBUG, 1, "Frequency=%d, Srate=%d", i_params->freq, i_params->srate); - /* checking Search Range is meaningless for a fixed 3 Mhz */ - if (INRANGE(i_params->srate, 1000000, 45000000)) { - dprintk(state->verbose, FE_DEBUG, 1, "Parameters IN RANGE"); - stb0899_set_delivery(state); - - if (state->config->tuner_set_rfsiggain) { - if (internal->srate > 15000000) - gain = 8; /* 15Mb < srate < 45Mb, gain = 8dB */ - else if (internal->srate > 5000000) - gain = 12; /* 5Mb < srate < 15Mb, gain = 12dB */ - else - gain = 14; /* 1Mb < srate < 5Mb, gain = 14db */ - state->config->tuner_set_rfsiggain(fe, gain); - } - - if (i_params->srate <= 5000000) - stb0899_set_mclk(state, config->lo_clk); - else - stb0899_set_mclk(state, config->hi_clk); - - switch (state->delsys) { - case SYS_DVBS: - case SYS_DSS: - dprintk(state->verbose, FE_DEBUG, 1, "DVB-S delivery system"); - internal->freq = i_params->freq; - internal->srate = i_params->srate; - /* - * search = user search range + - * 500Khz + - * 2 * Tuner_step_size + - * 10% of the symbol rate - */ - internal->srch_range = SearchRange + 1500000 + (i_params->srate / 5); - internal->derot_percent = 30; - - /* What to do for tuners having no bandwidth setup ? */ - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (13 * (stb0899_carr_width(state) + SearchRange)) / 10); - if (state->config->tuner_get_bandwidth) - state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - - /* Set DVB-S1 AGC */ - stb0899_write_reg(state, STB0899_AGCRFCFG, 0x11); - - /* Run the search algorithm */ - dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S search algo .."); - if (stb0899_dvbs_algo(state) == RANGEOK) { - internal->lock = 1; - dprintk(state->verbose, FE_DEBUG, 1, - "-------------------------------------> DVB-S LOCK !"); - -// stb0899_write_reg(state, STB0899_ERRCTRL1, 0x3d); /* Viterbi Errors */ -// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); -// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); -// dprintk(state->verbose, FE_DEBUG, 1, "VSTATUS=0x%02x", internal->v_status); -// dprintk(state->verbose, FE_DEBUG, 1, "ERR_CTRL=0x%02x", internal->err_ctrl); - - return DVBFE_ALGO_SEARCH_SUCCESS; - } else { - internal->lock = 0; - - return DVBFE_ALGO_SEARCH_FAILED; - } - break; - case SYS_DVBS2: - internal->freq = i_params->freq; - internal->srate = i_params->srate; - internal->srch_range = SearchRange; - - /* enable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 1); - - if (state->config->tuner_set_bandwidth) - state->config->tuner_set_bandwidth(fe, (stb0899_carr_width(state) + SearchRange)); - if (state->config->tuner_get_bandwidth) - state->config->tuner_get_bandwidth(fe, &internal->tuner_bw); - - /* disable tuner I/O */ - stb0899_i2c_gate_ctrl(&state->frontend, 0); - -// pParams->SpectralInv = pSearch->IQ_Inversion; - - /* Set DVB-S2 AGC */ - stb0899_write_reg(state, STB0899_AGCRFCFG, 0x1c); - - /* Set IterScale =f(MCLK,SYMB) */ - stb0899_set_iterations(state); - - /* Run the search algorithm */ - dprintk(state->verbose, FE_DEBUG, 1, "running DVB-S2 search algo .."); - if (stb0899_dvbs2_algo(state) == DVBS2_FEC_LOCK) { - internal->lock = 1; - dprintk(state->verbose, FE_DEBUG, 1, - "-------------------------------------> DVB-S2 LOCK !"); - -// stb0899_write_reg(state, STB0899_ERRCTRL1, 0xb6); /* Packet Errors */ -// internal->v_status = stb0899_read_reg(state, STB0899_VSTATUS); -// internal->err_ctrl = stb0899_read_reg(state, STB0899_ERRCTRL1); - - return DVBFE_ALGO_SEARCH_SUCCESS; - } else { - internal->lock = 0; - - return DVBFE_ALGO_SEARCH_FAILED; - } - break; - default: - dprintk(state->verbose, FE_ERROR, 1, "Unsupported delivery system"); - return DVBFE_ALGO_SEARCH_INVALID; - } - } - - return DVBFE_ALGO_SEARCH_ERROR; -} -/* - * stb0899_track - * periodically check the signal level against a specified - * threshold level and perform derotator centering. - * called once we have a lock from a succesful search - * event. - * - * Will be called periodically called to maintain the - * lock. - * - * Will be used to get parameters as well as info from - * the decoded baseband header - * - * Once a new lock has established, the internal state - * frequency (internal->freq) is updated - */ -static int stb0899_track(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - return 0; -} - -static int stb0899_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stb0899_state *state = fe->demodulator_priv; - struct stb0899_internal *internal = &state->internal; - - dprintk(state->verbose, FE_DEBUG, 1, "Get params"); - p->u.qpsk.symbol_rate = internal->srate; - - return 0; -} - -static enum dvbfe_algo stb0899_frontend_algo(struct dvb_frontend *fe) -{ - return DVBFE_ALGO_CUSTOM; -} - -static struct dvb_frontend_ops stb0899_ops = { - - .info = { - .name = "STB0899 Multistandard", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 0, - .frequency_tolerance = 0, - .symbol_rate_min = 5000000, - .symbol_rate_max = 45000000, - - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_AUTO | - FE_CAN_2G_MODULATION | - FE_CAN_QPSK - }, - - .release = stb0899_release, - .init = stb0899_init, - .sleep = stb0899_sleep, -// .wakeup = stb0899_wakeup, - - .i2c_gate_ctrl = stb0899_i2c_gate_ctrl, - - .get_frontend_algo = stb0899_frontend_algo, - .search = stb0899_search, - .track = stb0899_track, - .get_frontend = stb0899_get_frontend, - - - .read_status = stb0899_read_status, - .read_snr = stb0899_read_snr, - .read_signal_strength = stb0899_read_signal_strength, - .read_ber = stb0899_read_ber, - - .set_voltage = stb0899_set_voltage, - .set_tone = stb0899_set_tone, - - .diseqc_send_master_cmd = stb0899_send_diseqc_msg, - .diseqc_recv_slave_reply = stb0899_recv_slave_reply, - .diseqc_send_burst = stb0899_send_diseqc_burst, -}; - -struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_adapter *i2c) -{ - struct stb0899_state *state = NULL; - enum stb0899_inversion inversion; - - state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL); - if (state == NULL) - goto error; - - inversion = config->inversion; - state->verbose = &verbose; - state->config = config; - state->i2c = i2c; - state->frontend.ops = stb0899_ops; - state->frontend.demodulator_priv = state; - state->internal.inversion = inversion; - - stb0899_wakeup(&state->frontend); - if (stb0899_get_dev_id(state) == -ENODEV) { - printk("%s: Exiting .. !\n", __func__); - goto error; - } - - printk("%s: Attaching STB0899 \n", __func__); - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(stb0899_attach); -MODULE_PARM_DESC(verbose, "Set Verbosity level"); -MODULE_AUTHOR("Manu Abraham"); -MODULE_DESCRIPTION("STB0899 Multi-Std frontend"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stb0899_drv.h b/drivers/media/dvb/frontends/stb0899_drv.h deleted file mode 100644 index 98b200ce0c3..00000000000 --- a/drivers/media/dvb/frontends/stb0899_drv.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __STB0899_DRV_H -#define __STB0899_DRV_H - -#include <linux/kernel.h> -#include <linux/module.h> - -#include "dvb_frontend.h" - -#define STB0899_TSMODE_SERIAL 1 -#define STB0899_CLKPOL_FALLING 2 -#define STB0899_CLKNULL_PARITY 3 -#define STB0899_SYNC_FORCED 4 -#define STB0899_FECMODE_DSS 5 - -struct stb0899_s1_reg { - u16 address; - u8 data; -}; - -struct stb0899_s2_reg { - u16 offset; - u32 base_address; - u32 data; -}; - -enum stb0899_inversion { - IQ_SWAP_OFF = 0, - IQ_SWAP_ON, - IQ_SWAP_AUTO -}; - -#define STB0899_GPIO00 0xf140 -#define STB0899_GPIO01 0xf141 -#define STB0899_GPIO02 0xf142 -#define STB0899_GPIO03 0xf143 -#define STB0899_GPIO04 0xf144 -#define STB0899_GPIO05 0xf145 -#define STB0899_GPIO06 0xf146 -#define STB0899_GPIO07 0xf147 -#define STB0899_GPIO08 0xf148 -#define STB0899_GPIO09 0xf149 -#define STB0899_GPIO10 0xf14a -#define STB0899_GPIO11 0xf14b -#define STB0899_GPIO12 0xf14c -#define STB0899_GPIO13 0xf14d -#define STB0899_GPIO14 0xf14e -#define STB0899_GPIO15 0xf14f -#define STB0899_GPIO16 0xf150 -#define STB0899_GPIO17 0xf151 -#define STB0899_GPIO18 0xf152 -#define STB0899_GPIO19 0xf153 -#define STB0899_GPIO20 0xf154 - -#define STB0899_GPIOPULLUP 0x01 /* Output device is connected to Vdd */ -#define STB0899_GPIOPULLDN 0x00 /* Output device is connected to Vss */ - -#define STB0899_POSTPROC_GPIO_POWER 0x00 -#define STB0899_POSTPROC_GPIO_LOCK 0x01 - -/* - * Post process output configuration control - * 1. POWER ON/OFF (index 0) - * 2. FE_HAS_LOCK/LOCK_LOSS (index 1) - * - * @gpio = one of the above listed GPIO's - * @level = output state: pulled up or low - */ -struct stb0899_postproc { - u16 gpio; - u8 level; -}; - -struct stb0899_config { - const struct stb0899_s1_reg *init_dev; - const struct stb0899_s2_reg *init_s2_demod; - const struct stb0899_s1_reg *init_s1_demod; - const struct stb0899_s2_reg *init_s2_fec; - const struct stb0899_s1_reg *init_tst; - - const struct stb0899_postproc *postproc; - - enum stb0899_inversion inversion; - - u32 xtal_freq; - - u8 demod_address; - u8 ts_output_mode; - u8 block_sync_mode; - u8 ts_pfbit_toggle; - - u8 clock_polarity; - u8 data_clk_parity; - u8 fec_mode; - u8 data_output_ctl; - u8 data_fifo_mode; - u8 out_rate_comp; - u8 i2c_repeater; -// int inversion; - int lo_clk; - int hi_clk; - - u32 esno_ave; - u32 esno_quant; - u32 avframes_coarse; - u32 avframes_fine; - u32 miss_threshold; - u32 uwp_threshold_acq; - u32 uwp_threshold_track; - u32 uwp_threshold_sof; - u32 sof_search_timeout; - - u32 btr_nco_bits; - u32 btr_gain_shift_offset; - u32 crl_nco_bits; - u32 ldpc_max_iter; - - int (*tuner_set_frequency)(struct dvb_frontend *fe, u32 frequency); - int (*tuner_get_frequency)(struct dvb_frontend *fe, u32 *frequency); - int (*tuner_set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); - int (*tuner_get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); - int (*tuner_set_rfsiggain)(struct dvb_frontend *fe, u32 rf_gain); -}; - -#if defined(CONFIG_DVB_STB0899) || (defined(CONFIG_DVB_STB0899_MODULE) && defined(MODULE)) - -extern struct dvb_frontend *stb0899_attach(struct stb0899_config *config, - struct i2c_adapter *i2c); - -#else - -static inline struct dvb_frontend *stb0899_attach(struct stb0899_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); - return NULL; -} - -#endif //CONFIG_DVB_STB0899 - - -#endif diff --git a/drivers/media/dvb/frontends/stb0899_priv.h b/drivers/media/dvb/frontends/stb0899_priv.h deleted file mode 100644 index 24619e3689d..00000000000 --- a/drivers/media/dvb/frontends/stb0899_priv.h +++ /dev/null @@ -1,267 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __STB0899_PRIV_H -#define __STB0899_PRIV_H - -#include "dvb_frontend.h" -#include "stb0899_drv.h" - -#define FE_ERROR 0 -#define FE_NOTICE 1 -#define FE_INFO 2 -#define FE_DEBUG 3 -#define FE_DEBUGREG 4 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((*x > FE_ERROR) && (*x > y)) \ - printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ - else if ((*x > FE_NOTICE) && (*x > y)) \ - printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ - else if ((*x > FE_INFO) && (*x > y)) \ - printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ - else if ((*x > FE_DEBUG) && (*x > y)) \ - printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ - } else { \ - if (*x > y) \ - printk(format, ##arg); \ - } \ -} while(0) - -#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \ - ((y <= val) && (val <= x)) ? 1 : 0) - -#define BYTE0 0 -#define BYTE1 8 -#define BYTE2 16 -#define BYTE3 24 - -#define GETBYTE(x, y) (((x) >> (y)) & 0xff) -#define MAKEWORD32(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) -#define MAKEWORD16(a, b) (((a) << 8) | (b)) - -#define MIN(x, y) ((x) <= (y) ? (x) : (y)) -#define MAX(x, y) ((x) >= (y) ? (x) : (y)) -#define ABS(x) ((x) >= 0 ? (x) : -(x)) - -#define LSB(x) ((x & 0xff)) -#define MSB(y) ((y >> 8) & 0xff) - - -#define STB0899_GETFIELD(bitf, val) ((val >> STB0899_OFFST_##bitf) & ((1 << STB0899_WIDTH_##bitf) - 1)) - - -#define STB0899_SETFIELD(mask, val, width, offset) (mask & (~(((1 << width) - 1) << \ - offset))) | ((val & \ - ((1 << width) - 1)) << offset) - -#define STB0899_SETFIELD_VAL(bitf, mask, val) (mask = (mask & (~(((1 << STB0899_WIDTH_##bitf) - 1) <<\ - STB0899_OFFST_##bitf))) | \ - (val << STB0899_OFFST_##bitf)) - - -enum stb0899_status { - NOAGC1 = 0, - AGC1OK, - NOTIMING, - ANALOGCARRIER, - TIMINGOK, - NOAGC2, - AGC2OK, - NOCARRIER, - CARRIEROK, - NODATA, - FALSELOCK, - DATAOK, - OUTOFRANGE, - RANGEOK, - DVBS2_DEMOD_LOCK, - DVBS2_DEMOD_NOLOCK, - DVBS2_FEC_LOCK, - DVBS2_FEC_NOLOCK -}; - -enum stb0899_modcod { - STB0899_DUMMY_PLF, - STB0899_QPSK_14, - STB0899_QPSK_13, - STB0899_QPSK_25, - STB0899_QPSK_12, - STB0899_QPSK_35, - STB0899_QPSK_23, - STB0899_QPSK_34, - STB0899_QPSK_45, - STB0899_QPSK_56, - STB0899_QPSK_89, - STB0899_QPSK_910, - STB0899_8PSK_35, - STB0899_8PSK_23, - STB0899_8PSK_34, - STB0899_8PSK_56, - STB0899_8PSK_89, - STB0899_8PSK_910, - STB0899_16APSK_23, - STB0899_16APSK_34, - STB0899_16APSK_45, - STB0899_16APSK_56, - STB0899_16APSK_89, - STB0899_16APSK_910, - STB0899_32APSK_34, - STB0899_32APSK_45, - STB0899_32APSK_56, - STB0899_32APSK_89, - STB0899_32APSK_910 -}; - -enum stb0899_frame { - STB0899_LONG_FRAME, - STB0899_SHORT_FRAME -}; - -enum stb0899_alpha { - RRC_20, - RRC_25, - RRC_35 -}; - -struct stb0899_tab { - s32 real; - s32 read; -}; - -enum stb0899_fec { - STB0899_FEC_1_2 = 13, - STB0899_FEC_2_3 = 18, - STB0899_FEC_3_4 = 21, - STB0899_FEC_5_6 = 24, - STB0899_FEC_6_7 = 25, - STB0899_FEC_7_8 = 26 -}; - -struct stb0899_params { - u32 freq; /* Frequency */ - u32 srate; /* Symbol rate */ - enum fe_code_rate fecrate; -}; - -struct stb0899_internal { - u32 master_clk; - u32 freq; /* Demod internal Frequency */ - u32 srate; /* Demod internal Symbol rate */ - enum stb0899_fec fecrate; /* Demod internal FEC rate */ - u32 srch_range; /* Demod internal Search Range */ - u32 sub_range; /* Demod current sub range (Hz) */ - u32 tuner_step; /* Tuner step (Hz) */ - u32 tuner_offst; /* Relative offset to carrier (Hz) */ - u32 tuner_bw; /* Current bandwidth of the tuner (Hz) */ - - s32 mclk; /* Masterclock Divider factor (binary) */ - s32 rolloff; /* Current RollOff of the filter (x100) */ - - s16 derot_freq; /* Current derotator frequency (Hz) */ - s16 derot_percent; - - s16 direction; /* Current derotator search direction */ - s16 derot_step; /* Derotator step (binary value) */ - s16 t_derot; /* Derotator time constant (ms) */ - s16 t_data; /* Data recovery time constant (ms) */ - s16 sub_dir; /* Direction of the next sub range */ - - s16 t_agc1; /* Agc1 time constant (ms) */ - s16 t_agc2; /* Agc2 time constant (ms) */ - - u32 lock; /* Demod internal lock state */ - enum stb0899_status status; /* Demod internal status */ - - /* DVB-S2 */ - s32 agc_gain; /* RF AGC Gain */ - s32 center_freq; /* Nominal carrier frequency */ - s32 av_frame_coarse; /* Coarse carrier freq search frames */ - s32 av_frame_fine; /* Fine carrier freq search frames */ - - s16 step_size; /* Carrier frequency search step size */ - - enum stb0899_alpha rrc_alpha; - enum stb0899_inversion inversion; - enum stb0899_modcod modcod; - u8 pilots; /* Pilots found */ - - enum stb0899_frame frame_length; - u8 v_status; /* VSTATUS */ - u8 err_ctrl; /* ERRCTRLn */ -}; - -struct stb0899_state { - struct i2c_adapter *i2c; - struct stb0899_config *config; - struct dvb_frontend frontend; - - u32 *verbose; /* Cached module verbosity level */ - - struct stb0899_internal internal; /* Device internal parameters */ - - /* cached params from API */ - enum fe_delivery_system delsys; - struct stb0899_params params; - - u32 rx_freq; /* DiSEqC 2.0 receiver freq */ - struct mutex search_lock; -}; -/* stb0899.c */ -extern int stb0899_read_reg(struct stb0899_state *state, - unsigned int reg); - -extern u32 _stb0899_read_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset); - -extern int stb0899_read_regs(struct stb0899_state *state, - unsigned int reg, u8 *buf, - u32 count); - -extern int stb0899_write_regs(struct stb0899_state *state, - unsigned int reg, u8 *data, - u32 count); - -extern int stb0899_write_reg(struct stb0899_state *state, - unsigned int reg, - u8 data); - -extern int stb0899_write_s2reg(struct stb0899_state *state, - u32 stb0899_i2cdev, - u32 stb0899_base_addr, - u16 stb0899_reg_offset, - u32 stb0899_data); - -extern int stb0899_i2c_gate_ctrl(struct dvb_frontend *fe, int enable); - - -#define STB0899_READ_S2REG(DEVICE, REG) (_stb0899_read_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG)) -//#define STB0899_WRITE_S2REG(DEVICE, REG, DATA) (_stb0899_write_s2reg(state, DEVICE, STB0899_BASE_##REG, STB0899_OFF0_##REG, DATA)) - -/* stb0899_algo.c */ -extern enum stb0899_status stb0899_dvbs_algo(struct stb0899_state *state); -extern enum stb0899_status stb0899_dvbs2_algo(struct stb0899_state *state); -extern long stb0899_carr_width(struct stb0899_state *state); - -#endif //__STB0899_PRIV_H diff --git a/drivers/media/dvb/frontends/stb0899_reg.h b/drivers/media/dvb/frontends/stb0899_reg.h deleted file mode 100644 index ba1ed56304a..00000000000 --- a/drivers/media/dvb/frontends/stb0899_reg.h +++ /dev/null @@ -1,2027 +0,0 @@ -/* - STB0899 Multistandard Frontend driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __STB0899_REG_H -#define __STB0899_REG_H - -/* S1 */ -#define STB0899_DEV_ID 0xf000 -#define STB0899_CHIP_ID (0x0f << 4) -#define STB0899_OFFST_CHIP_ID 4 -#define STB0899_WIDTH_CHIP_ID 4 -#define STB0899_CHIP_REL (0x0f << 0) -#define STB0899_OFFST_CHIP_REL 0 -#define STB0899_WIDTH_CHIP_REL 4 - -#define STB0899_DEMOD 0xf40e -#define STB0899_MODECOEFF (0x01 << 0) -#define STB0899_OFFST_MODECOEFF 0 -#define STB0899_WIDTH_MODECOEFF 1 - -#define STB0899_RCOMPC 0xf410 -#define STB0899_AGC1CN 0xf412 -#define STB0899_AGC1REF 0xf413 -#define STB0899_RTC 0xf417 -#define STB0899_TMGCFG 0xf418 -#define STB0899_AGC2REF 0xf419 -#define STB0899_TLSR 0xf41a - -#define STB0899_CFD 0xf41b -#define STB0899_CFD_ON (0x01 << 7) -#define STB0899_OFFST_CFD_ON 7 -#define STB0899_WIDTH_CFD_ON 1 - -#define STB0899_ACLC 0xf41c - -#define STB0899_BCLC 0xf41d -#define STB0899_OFFST_ALGO 6 -#define STB0899_WIDTH_ALGO_QPSK2 2 -#define STB0899_ALGO_QPSK2 (2 << 6) -#define STB0899_ALGO_QPSK1 (1 << 6) -#define STB0899_ALGO_BPSK (0 << 6) -#define STB0899_OFFST_BETA 0 -#define STB0899_WIDTH_BETA 6 - -#define STB0899_EQON 0xf41e -#define STB0899_LDT 0xf41f -#define STB0899_LDT2 0xf420 -#define STB0899_EQUALREF 0xf425 -#define STB0899_TMGRAMP 0xf426 -#define STB0899_TMGTHD 0xf427 -#define STB0899_IDCCOMP 0xf428 -#define STB0899_QDCCOMP 0xf429 -#define STB0899_POWERI 0xf42a -#define STB0899_POWERQ 0xf42b -#define STB0899_RCOMP 0xf42c - -#define STB0899_AGCIQIN 0xf42e -#define STB0899_AGCIQVALUE (0xff << 0) -#define STB0899_OFFST_AGCIQVALUE 0 -#define STB0899_WIDTH_AGCIQVALUE 8 - -#define STB0899_AGC2I1 0xf436 -#define STB0899_AGC2I2 0xf437 - -#define STB0899_TLIR 0xf438 -#define STB0899_TLIR_TMG_LOCK_IND (0xff << 0) -#define STB0899_OFFST_TLIR_TMG_LOCK_IND 0 -#define STB0899_WIDTH_TLIR_TMG_LOCK_IND 8 - -#define STB0899_RTF 0xf439 -#define STB0899_RTF_TIMING_LOOP_FREQ (0xff << 0) -#define STB0899_OFFST_RTF_TIMING_LOOP_FREQ 0 -#define STB0899_WIDTH_RTF_TIMING_LOOP_FREQ 8 - -#define STB0899_DSTATUS 0xf43a -#define STB0899_CARRIER_FOUND (0x01 << 7) -#define STB0899_OFFST_CARRIER_FOUND 7 -#define STB0899_WIDTH_CARRIER_FOUND 1 -#define STB0899_TMG_LOCK (0x01 << 6) -#define STB0899_OFFST_TMG_LOCK 6 -#define STB0899_WIDTH_TMG_LOCK 1 -#define STB0899_DEMOD_LOCK (0x01 << 5) -#define STB0899_OFFST_DEMOD_LOCK 5 -#define STB0899_WIDTH_DEMOD_LOCK 1 -#define STB0899_TMG_AUTO (0x01 << 4) -#define STB0899_OFFST_TMG_AUTO 4 -#define STB0899_WIDTH_TMG_AUTO 1 -#define STB0899_END_MAIN (0x01 << 3) -#define STB0899_OFFST_END_MAIN 3 -#define STB0899_WIDTH_END_MAIN 1 - -#define STB0899_LDI 0xf43b -#define STB0899_OFFST_LDI 0 -#define STB0899_WIDTH_LDI 8 - -#define STB0899_CFRM 0xf43e -#define STB0899_OFFST_CFRM 0 -#define STB0899_WIDTH_CFRM 8 - -#define STB0899_CFRL 0xf43f -#define STB0899_OFFST_CFRL 0 -#define STB0899_WIDTH_CFRL 8 - -#define STB0899_NIRM 0xf440 -#define STB0899_OFFST_NIRM 0 -#define STB0899_WIDTH_NIRM 8 - -#define STB0899_NIRL 0xf441 -#define STB0899_OFFST_NIRL 0 -#define STB0899_WIDTH_NIRL 8 - -#define STB0899_ISYMB 0xf444 -#define STB0899_QSYMB 0xf445 - -#define STB0899_SFRH 0xf446 -#define STB0899_OFFST_SFRH 0 -#define STB0899_WIDTH_SFRH 8 - -#define STB0899_SFRM 0xf447 -#define STB0899_OFFST_SFRM 0 -#define STB0899_WIDTH_SFRM 8 - -#define STB0899_SFRL 0xf448 -#define STB0899_OFFST_SFRL 4 -#define STB0899_WIDTH_SFRL 4 - -#define STB0899_SFRUPH 0xf44c -#define STB0899_SFRUPM 0xf44d -#define STB0899_SFRUPL 0xf44e - -#define STB0899_EQUAI1 0xf4e0 -#define STB0899_EQUAQ1 0xf4e1 -#define STB0899_EQUAI2 0xf4e2 -#define STB0899_EQUAQ2 0xf4e3 -#define STB0899_EQUAI3 0xf4e4 -#define STB0899_EQUAQ3 0xf4e5 -#define STB0899_EQUAI4 0xf4e6 -#define STB0899_EQUAQ4 0xf4e7 -#define STB0899_EQUAI5 0xf4e8 -#define STB0899_EQUAQ5 0xf4e9 - -#define STB0899_DSTATUS2 0xf50c -#define STB0899_DS2_TMG_AUTOSRCH (0x01 << 7) -#define STB8999_OFFST_DS2_TMG_AUTOSRCH 7 -#define STB0899_WIDTH_DS2_TMG_AUTOSRCH 1 -#define STB0899_DS2_END_MAINLOOP (0x01 << 6) -#define STB0899_OFFST_DS2_END_MAINLOOP 6 -#define STB0899_WIDTH_DS2_END_MAINLOOP 1 -#define STB0899_DS2_CFSYNC (0x01 << 5) -#define STB0899_OFFST_DS2_CFSYNC 5 -#define STB0899_WIDTH_DS2_CFSYNC 1 -#define STB0899_DS2_TMGLOCK (0x01 << 4) -#define STB0899_OFFST_DS2_TMGLOCK 4 -#define STB0899_WIDTH_DS2_TMGLOCK 1 -#define STB0899_DS2_DEMODWAIT (0x01 << 3) -#define STB0899_OFFST_DS2_DEMODWAIT 3 -#define STB0899_WIDTH_DS2_DEMODWAIT 1 -#define STB0899_DS2_FECON (0x01 << 1) -#define STB0899_OFFST_DS2_FECON 1 -#define STB0899_WIDTH_DS2_FECON 1 - -/* S1 FEC */ -#define STB0899_VSTATUS 0xf50d -#define STB0899_VSTATUS_VITERBI_ON (0x01 << 7) -#define STB0899_OFFST_VSTATUS_VITERBI_ON 7 -#define STB0899_WIDTH_VSTATUS_VITERBI_ON 1 -#define STB0899_VSTATUS_END_LOOPVIT (0x01 << 6) -#define STB0899_OFFST_VSTATUS_END_LOOPVIT 6 -#define STB0899_WIDTH_VSTATUS_END_LOOPVIT 1 -#define STB0899_VSTATUS_PRFVIT (0x01 << 4) -#define STB0899_OFFST_VSTATUS_PRFVIT 4 -#define STB0899_WIDTH_VSTATUS_PRFVIT 1 -#define STB0899_VSTATUS_LOCKEDVIT (0x01 << 3) -#define STB0899_OFFST_VSTATUS_LOCKEDVIT 3 -#define STB0899_WIDTH_VSTATUS_LOCKEDVIT 1 - -#define STB0899_VERROR 0xf50f - -#define STB0899_IQSWAP 0xf523 -#define STB0899_SYM (0x01 << 3) -#define STB0899_OFFST_SYM 3 -#define STB0899_WIDTH_SYM 1 - -#define STB0899_FECAUTO1 0xf530 -#define STB0899_DSSSRCH (0x01 << 3) -#define STB0899_OFFST_DSSSRCH 3 -#define STB0899_WIDTH_DSSSRCH 1 -#define STB0899_SYMSRCH (0x01 << 2) -#define STB0899_OFFST_SYMSRCH 2 -#define STB0899_WIDTH_SYMSRCH 1 -#define STB0899_QPSKSRCH (0x01 << 1) -#define STB0899_OFFST_QPSKSRCH 1 -#define STB0899_WIDTH_QPSKSRCH 1 -#define STB0899_BPSKSRCH (0x01 << 0) -#define STB0899_OFFST_BPSKSRCH 0 -#define STB0899_WIDTH_BPSKSRCH 1 - -#define STB0899_FECM 0xf533 -#define STB0899_FECM_NOT_DVB (0x01 << 7) -#define STB0899_OFFST_FECM_NOT_DVB 7 -#define STB0899_WIDTH_FECM_NOT_DVB 1 -#define STB0899_FECM_RSVD1 (0x07 << 4) -#define STB0899_OFFST_FECM_RSVD1 4 -#define STB0899_WIDTH_FECM_RSVD1 3 -#define STB0899_FECM_VITERBI_ON (0x01 << 3) -#define STB0899_OFFST_FECM_VITERBI_ON 3 -#define STB0899_WIDTH_FECM_VITERBI_ON 1 -#define STB0899_FECM_RSVD0 (0x01 << 2) -#define STB0899_OFFST_FECM_RSVD0 2 -#define STB0899_WIDTH_FECM_RSVD0 1 -#define STB0899_FECM_SYNCDIS (0x01 << 1) -#define STB0899_OFFST_FECM_SYNCDIS 1 -#define STB0899_WIDTH_FECM_SYNCDIS 1 -#define STB0899_FECM_SYMI (0x01 << 0) -#define STB0899_OFFST_FECM_SYMI 0 -#define STB0899_WIDTH_FECM_SYMI 1 - -#define STB0899_VTH12 0xf534 -#define STB0899_VTH23 0xf535 -#define STB0899_VTH34 0xf536 -#define STB0899_VTH56 0xf537 -#define STB0899_VTH67 0xf538 -#define STB0899_VTH78 0xf539 - -#define STB0899_PRVIT 0xf53c -#define STB0899_PR_7_8 (0x01 << 5) -#define STB0899_OFFST_PR_7_8 5 -#define STB0899_WIDTH_PR_7_8 1 -#define STB0899_PR_6_7 (0x01 << 4) -#define STB0899_OFFST_PR_6_7 4 -#define STB0899_WIDTH_PR_6_7 1 -#define STB0899_PR_5_6 (0x01 << 3) -#define STB0899_OFFST_PR_5_6 3 -#define STB0899_WIDTH_PR_5_6 1 -#define STB0899_PR_3_4 (0x01 << 2) -#define STB0899_OFFST_PR_3_4 2 -#define STB0899_WIDTH_PR_3_4 1 -#define STB0899_PR_2_3 (0x01 << 1) -#define STB0899_OFFST_PR_2_3 1 -#define STB0899_WIDTH_PR_2_3 1 -#define STB0899_PR_1_2 (0x01 << 0) -#define STB0899_OFFST_PR_1_2 0 -#define STB0899_WIDTH_PR_1_2 1 - -#define STB0899_VITSYNC 0xf53d -#define STB0899_AM (0x01 << 7) -#define STB0899_OFFST_AM 7 -#define STB0899_WIDTH_AM 1 -#define STB0899_FREEZE (0x01 << 6) -#define STB0899_OFFST_FREEZE 6 -#define STB0899_WIDTH_FREEZE 1 -#define STB0899_SN_65536 (0x03 << 4) -#define STB0899_OFFST_SN_65536 4 -#define STB0899_WIDTH_SN_65536 2 -#define STB0899_SN_16384 (0x01 << 5) -#define STB0899_OFFST_SN_16384 5 -#define STB0899_WIDTH_SN_16384 1 -#define STB0899_SN_4096 (0x01 << 4) -#define STB0899_OFFST_SN_4096 4 -#define STB0899_WIDTH_SN_4096 1 -#define STB0899_SN_1024 (0x00 << 4) -#define STB0899_OFFST_SN_1024 4 -#define STB0899_WIDTH_SN_1024 0 -#define STB0899_TO_128 (0x03 << 2) -#define STB0899_OFFST_TO_128 2 -#define STB0899_WIDTH_TO_128 2 -#define STB0899_TO_64 (0x01 << 3) -#define STB0899_OFFST_TO_64 3 -#define STB0899_WIDTH_TO_64 1 -#define STB0899_TO_32 (0x01 << 2) -#define STB0899_OFFST_TO_32 2 -#define STB0899_WIDTH_TO_32 1 -#define STB0899_TO_16 (0x00 << 2) -#define STB0899_OFFST_TO_16 2 -#define STB0899_WIDTH_TO_16 0 -#define STB0899_HYST_128 (0x03 << 1) -#define STB0899_OFFST_HYST_128 1 -#define STB0899_WIDTH_HYST_128 2 -#define STB0899_HYST_64 (0x01 << 1) -#define STB0899_OFFST_HYST_64 1 -#define STB0899_WIDTH_HYST_64 1 -#define STB0899_HYST_32 (0x01 << 0) -#define STB0899_OFFST_HYST_32 0 -#define STB0899_WIDTH_HYST_32 1 -#define STB0899_HYST_16 (0x00 << 0) -#define STB0899_OFFST_HYST_16 0 -#define STB0899_WIDTH_HYST_16 0 - -#define STB0899_RSULC 0xf548 -#define STB0899_ULDIL_ON (0x01 << 7) -#define STB0899_OFFST_ULDIL_ON 7 -#define STB0899_WIDTH_ULDIL_ON 1 -#define STB0899_ULAUTO_ON (0x01 << 6) -#define STB0899_OFFST_ULAUTO_ON 6 -#define STB0899_WIDTH_ULAUTO_ON 1 -#define STB0899_ULRS_ON (0x01 << 5) -#define STB0899_OFFST_ULRS_ON 5 -#define STB0899_WIDTH_ULRS_ON 1 -#define STB0899_ULDESCRAM_ON (0x01 << 4) -#define STB0899_OFFST_ULDESCRAM_ON 4 -#define STB0899_WIDTH_ULDESCRAM_ON 1 -#define STB0899_UL_DISABLE (0x01 << 2) -#define STB0899_OFFST_UL_DISABLE 2 -#define STB0899_WIDTH_UL_DISABLE 1 -#define STB0899_NOFTHRESHOLD (0x01 << 0) -#define STB0899_OFFST_NOFTHRESHOLD 0 -#define STB0899_WIDTH_NOFTHRESHOLD 1 - -#define STB0899_RSLLC 0xf54a -#define STB0899_DEMAPVIT 0xf583 -#define STB0899_DEMAPVIT_RSVD (0x01 << 7) -#define STB0899_OFFST_DEMAPVIT_RSVD 7 -#define STB0899_WIDTH_DEMAPVIT_RSVD 1 -#define STB0899_DEMAPVIT_KDIVIDER (0x7f << 0) -#define STB0899_OFFST_DEMAPVIT_KDIVIDER 0 -#define STB0899_WIDTH_DEMAPVIT_KDIVIDER 7 - -#define STB0899_PLPARM 0xf58c -#define STB0899_VITMAPPING (0x07 << 5) -#define STB0899_OFFST_VITMAPPING 5 -#define STB0899_WIDTH_VITMAPPING 3 -#define STB0899_VITMAPPING_BPSK (0x01 << 5) -#define STB0899_OFFST_VITMAPPING_BPSK 5 -#define STB0899_WIDTH_VITMAPPING_BPSK 1 -#define STB0899_VITMAPPING_QPSK (0x00 << 5) -#define STB0899_OFFST_VITMAPPING_QPSK 5 -#define STB0899_WIDTH_VITMAPPING_QPSK 0 -#define STB0899_VITCURPUN (0x1f << 0) -#define STB0899_OFFST_VITCURPUN 0 -#define STB0899_WIDTH_VITCURPUN 5 -#define STB0899_VITCURPUN_1_2 (0x0d << 0) -#define STB0899_VITCURPUN_2_3 (0x12 << 0) -#define STB0899_VITCURPUN_3_4 (0x15 << 0) -#define STB0899_VITCURPUN_5_6 (0x18 << 0) -#define STB0899_VITCURPUN_6_7 (0x19 << 0) -#define STB0899_VITCURPUN_7_8 (0x1a << 0) - -/* S2 DEMOD */ -#define STB0899_OFF0_DMD_STATUS 0xf300 -#define STB0899_BASE_DMD_STATUS 0x00000000 -#define STB0899_IF_AGC_LOCK (0x01 << 8) -#define STB0899_OFFST_IF_AGC_LOCK 0 -#define STB0899_WIDTH_IF_AGC_LOCK 1 - -#define STB0899_OFF0_CRL_FREQ 0xf304 -#define STB0899_BASE_CRL_FREQ 0x00000000 -#define STB0899_CARR_FREQ (0x3fffffff << 0) -#define STB0899_OFFST_CARR_FREQ 0 -#define STB0899_WIDTH_CARR_FREQ 30 - -#define STB0899_OFF0_BTR_FREQ 0xf308 -#define STB0899_BASE_BTR_FREQ 0x00000000 -#define STB0899_BTR_FREQ (0xfffffff << 0) -#define STB0899_OFFST_BTR_FREQ 0 -#define STB0899_WIDTH_BTR_FREQ 28 - -#define STB0899_OFF0_IF_AGC_GAIN 0xf30c -#define STB0899_BASE_IF_AGC_GAIN 0x00000000 -#define STB0899_IF_AGC_GAIN (0x3fff < 0) -#define STB0899_OFFST_IF_AGC_GAIN 0 -#define STB0899_WIDTH_IF_AGC_GAIN 14 - -#define STB0899_OFF0_BB_AGC_GAIN 0xf310 -#define STB0899_BASE_BB_AGC_GAIN 0x00000000 -#define STB0899_BB_AGC_GAIN (0x3fff < 0) -#define STB0899_OFFST_BB_AGC_GAIN 0 -#define STB0899_WIDTH_BB_AGC_GAIN 14 - -#define STB0899_OFF0_DC_OFFSET 0xf314 -#define STB0899_BASE_DC_OFFSET 0x00000000 -#define STB0899_I (0xff < 8) -#define STB0899_OFFST_I 8 -#define STB0899_WIDTH_I 8 -#define STB0899_Q (0xff < 0) -#define STB0899_OFFST_Q 8 -#define STB0899_WIDTH_Q 8 - -#define STB0899_OFF0_DMD_CNTRL 0xf31c -#define STB0899_BASE_DMD_CNTRL 0x00000000 -#define STB0899_ADC0_PINS1IN (0x01 << 6) -#define STB0899_OFFST_ADC0_PINS1IN 6 -#define STB0899_WIDTH_ADC0_PINS1IN 1 -#define STB0899_IN2COMP1_OFFBIN0 (0x01 << 3) -#define STB0899_OFFST_IN2COMP1_OFFBIN0 3 -#define STB0899_WIDTH_IN2COMP1_OFFBIN0 1 -#define STB0899_DC_COMP (0x01 << 2) -#define STB0899_OFFST_DC_COMP 2 -#define STB0899_WIDTH_DC_COMP 1 -#define STB0899_MODMODE (0x03 << 0) -#define STB0899_OFFST_MODMODE 0 -#define STB0899_WIDTH_MODMODE 2 - -#define STB0899_OFF0_IF_AGC_CNTRL 0xf320 -#define STB0899_BASE_IF_AGC_CNTRL 0x00000000 -#define STB0899_IF_GAIN_INIT (0x3fff << 13) -#define STB0899_OFFST_IF_GAIN_INIT 13 -#define STB0899_WIDTH_IF_GAIN_INIT 14 -#define STB0899_IF_GAIN_SENSE (0x01 << 12) -#define STB0899_OFFST_IF_GAIN_SENSE 12 -#define STB0899_WIDTH_IF_GAIN_SENSE 1 -#define STB0899_IF_LOOP_GAIN (0x0f << 8) -#define STB0899_OFFST_IF_LOOP_GAIN 8 -#define STB0899_WIDTH_IF_LOOP_GAIN 4 -#define STB0899_IF_LD_GAIN_INIT (0x01 << 7) -#define STB0899_OFFST_IF_LD_GAIN_INIT 7 -#define STB0899_WIDTH_IF_LD_GAIN_INIT 1 -#define STB0899_IF_AGC_REF (0x7f << 0) -#define STB0899_OFFST_IF_AGC_REF 0 -#define STB0899_WIDTH_IF_AGC_REF 7 - -#define STB0899_OFF0_BB_AGC_CNTRL 0xf324 -#define STB0899_BASE_BB_AGC_CNTRL 0x00000000 -#define STB0899_BB_GAIN_INIT (0x3fff << 12) -#define STB0899_OFFST_BB_GAIN_INIT 12 -#define STB0899_WIDTH_BB_GAIN_INIT 14 -#define STB0899_BB_LOOP_GAIN (0x0f << 8) -#define STB0899_OFFST_BB_LOOP_GAIN 8 -#define STB0899_WIDTH_BB_LOOP_GAIN 4 -#define STB0899_BB_LD_GAIN_INIT (0x01 << 7) -#define STB0899_OFFST_BB_LD_GAIN_INIT 7 -#define STB0899_WIDTH_BB_LD_GAIN_INIT 1 -#define STB0899_BB_AGC_REF (0x7f << 0) -#define STB0899_OFFST_BB_AGC_REF 0 -#define STB0899_WIDTH_BB_AGC_REF 7 - -#define STB0899_OFF0_CRL_CNTRL 0xf328 -#define STB0899_BASE_CRL_CNTRL 0x00000000 -#define STB0899_CRL_LOCK_CLEAR (0x01 << 5) -#define STB0899_OFFST_CRL_LOCK_CLEAR 5 -#define STB0899_WIDTH_CRL_LOCK_CLEAR 1 -#define STB0899_CRL_SWPR_CLEAR (0x01 << 4) -#define STB0899_OFFST_CRL_SWPR_CLEAR 4 -#define STB0899_WIDTH_CRL_SWPR_CLEAR 1 -#define STB0899_CRL_SWP_ENA (0x01 << 3) -#define STB0899_OFFST_CRL_SWP_ENA 3 -#define STB0899_WIDTH_CRL_SWP_ENA 1 -#define STB0899_CRL_DET_SEL (0x01 << 2) -#define STB0899_OFFST_CRL_DET_SEL 2 -#define STB0899_WIDTH_CRL_DET_SEL 1 -#define STB0899_CRL_SENSE (0x01 << 1) -#define STB0899_OFFST_CRL_SENSE 1 -#define STB0899_WIDTH_CRL_SENSE 1 -#define STB0899_CRL_PHSERR_CLEAR (0x01 << 0) -#define STB0899_OFFST_CRL_PHSERR_CLEAR 0 -#define STB0899_WIDTH_CRL_PHSERR_CLEAR 1 - -#define STB0899_OFF0_CRL_PHS_INIT 0xf32c -#define STB0899_BASE_CRL_PHS_INIT 0x00000000 -#define STB0899_CRL_PHS_INIT_31 (0x1 << 30) -#define STB0899_OFFST_CRL_PHS_INIT_31 30 -#define STB0899_WIDTH_CRL_PHS_INIT_31 1 -#define STB0899_CRL_LD_INIT_PHASE (0x1 << 24) -#define STB0899_OFFST_CRL_LD_INIT_PHASE 24 -#define STB0899_WIDTH_CRL_LD_INIT_PHASE 1 -#define STB0899_CRL_INIT_PHASE (0xffffff << 0) -#define STB0899_OFFST_CRL_INIT_PHASE 0 -#define STB0899_WIDTH_CRL_INIT_PHASE 24 - -#define STB0899_OFF0_CRL_FREQ_INIT 0xf330 -#define STB0899_BASE_CRL_FREQ_INIT 0x00000000 -#define STB0899_CRL_FREQ_INIT_31 (0x1 << 30) -#define STB0899_OFFST_CRL_FREQ_INIT_31 30 -#define STB0899_WIDTH_CRL_FREQ_INIT_31 1 -#define STB0899_CRL_LD_FREQ_INIT (0x1 << 24) -#define STB0899_OFFST_CRL_LD_FREQ_INIT 24 -#define STB0899_WIDTH_CRL_LD_FREQ_INIT 1 -#define STB0899_CRL_FREQ_INIT (0xffffff << 0) -#define STB0899_OFFST_CRL_FREQ_INIT 0 -#define STB0899_WIDTH_CRL_FREQ_INIT 24 - -#define STB0899_OFF0_CRL_LOOP_GAIN 0xf334 -#define STB0899_BASE_CRL_LOOP_GAIN 0x00000000 -#define STB0899_KCRL2_RSHFT (0xf << 16) -#define STB0899_OFFST_KCRL2_RSHFT 16 -#define STB0899_WIDTH_KCRL2_RSHFT 4 -#define STB0899_KCRL1 (0xf << 12) -#define STB0899_OFFST_KCRL1 12 -#define STB0899_WIDTH_KCRL1 4 -#define STB0899_KCRL1_RSHFT (0xf << 8) -#define STB0899_OFFST_KCRL1_RSHFT 8 -#define STB0899_WIDTH_KCRL1_RSHFT 4 -#define STB0899_KCRL0 (0xf << 4) -#define STB0899_OFFST_KCRL0 4 -#define STB0899_WIDTH_KCRL0 4 -#define STB0899_KCRL0_RSHFT (0xf << 0) -#define STB0899_OFFST_KCRL0_RSHFT 0 -#define STB0899_WIDTH_KCRL0_RSHFT 4 - -#define STB0899_OFF0_CRL_NOM_FREQ 0xf338 -#define STB0899_BASE_CRL_NOM_FREQ 0x00000000 -#define STB0899_CRL_NOM_FREQ (0x3fffffff << 0) -#define STB0899_OFFST_CRL_NOM_FREQ 0 -#define STB0899_WIDTH_CRL_NOM_FREQ 30 - -#define STB0899_OFF0_CRL_SWP_RATE 0xf33c -#define STB0899_BASE_CRL_SWP_RATE 0x00000000 -#define STB0899_CRL_SWP_RATE (0x3fffffff << 0) -#define STB0899_OFFST_CRL_SWP_RATE 0 -#define STB0899_WIDTH_CRL_SWP_RATE 30 - -#define STB0899_OFF0_CRL_MAX_SWP 0xf340 -#define STB0899_BASE_CRL_MAX_SWP 0x00000000 -#define STB0899_CRL_MAX_SWP (0x3fffffff << 0) -#define STB0899_OFFST_CRL_MAX_SWP 0 -#define STB0899_WIDTH_CRL_MAX_SWP 30 - -#define STB0899_OFF0_CRL_LK_CNTRL 0xf344 -#define STB0899_BASE_CRL_LK_CNTRL 0x00000000 - -#define STB0899_OFF0_DECIM_CNTRL 0xf348 -#define STB0899_BASE_DECIM_CNTRL 0x00000000 -#define STB0899_BAND_LIMIT_B (0x01 << 5) -#define STB0899_OFFST_BAND_LIMIT_B 5 -#define STB0899_WIDTH_BAND_LIMIT_B 1 -#define STB0899_WIN_SEL (0x03 << 3) -#define STB0899_OFFST_WIN_SEL 3 -#define STB0899_WIDTH_WIN_SEL 2 -#define STB0899_DECIM_RATE (0x07 << 0) -#define STB0899_OFFST_DECIM_RATE 0 -#define STB0899_WIDTH_DECIM_RATE 3 - -#define STB0899_OFF0_BTR_CNTRL 0xf34c -#define STB0899_BASE_BTR_CNTRL 0x00000000 -#define STB0899_BTR_FREQ_CORR (0x7ff << 4) -#define STB0899_OFFST_BTR_FREQ_CORR 4 -#define STB0899_WIDTH_BTR_FREQ_CORR 11 -#define STB0899_BTR_CLR_LOCK (0x01 << 3) -#define STB0899_OFFST_BTR_CLR_LOCK 3 -#define STB0899_WIDTH_BTR_CLR_LOCK 1 -#define STB0899_BTR_SENSE (0x01 << 2) -#define STB0899_OFFST_BTR_SENSE 2 -#define STB0899_WIDTH_BTR_SENSE 1 -#define STB0899_BTR_ERR_ENA (0x01 << 1) -#define STB0899_OFFST_BTR_ERR_ENA 1 -#define STB0899_WIDTH_BTR_ERR_ENA 1 -#define STB0899_INTRP_PHS_SENSE (0x01 << 0) -#define STB0899_OFFST_INTRP_PHS_SENSE 0 -#define STB0899_WIDTH_INTRP_PHS_SENSE 1 - -#define STB0899_OFF0_BTR_LOOP_GAIN 0xf350 -#define STB0899_BASE_BTR_LOOP_GAIN 0x00000000 -#define STB0899_KBTR2_RSHFT (0x0f << 16) -#define STB0899_OFFST_KBTR2_RSHFT 16 -#define STB0899_WIDTH_KBTR2_RSHFT 4 -#define STB0899_KBTR1 (0x0f << 12) -#define STB0899_OFFST_KBTR1 12 -#define STB0899_WIDTH_KBTR1 4 -#define STB0899_KBTR1_RSHFT (0x0f << 8) -#define STB0899_OFFST_KBTR1_RSHFT 8 -#define STB0899_WIDTH_KBTR1_RSHFT 4 -#define STB0899_KBTR0 (0x0f << 4) -#define STB0899_OFFST_KBTR0 4 -#define STB0899_WIDTH_KBTR0 4 -#define STB0899_KBTR0_RSHFT (0x0f << 0) -#define STB0899_OFFST_KBTR0_RSHFT 0 -#define STB0899_WIDTH_KBTR0_RSHFT 4 - -#define STB0899_OFF0_BTR_PHS_INIT 0xf354 -#define STB0899_BASE_BTR_PHS_INIT 0x00000000 -#define STB0899_BTR_LD_PHASE_INIT (0x01 << 28) -#define STB0899_OFFST_BTR_LD_PHASE_INIT 28 -#define STB0899_WIDTH_BTR_LD_PHASE_INIT 1 -#define STB0899_BTR_INIT_PHASE (0xfffffff << 0) -#define STB0899_OFFST_BTR_INIT_PHASE 0 -#define STB0899_WIDTH_BTR_INIT_PHASE 28 - -#define STB0899_OFF0_BTR_FREQ_INIT 0xf358 -#define STB0899_BASE_BTR_FREQ_INIT 0x00000000 -#define STB0899_BTR_LD_FREQ_INIT (1 << 28) -#define STB0899_OFFST_BTR_LD_FREQ_INIT 28 -#define STB0899_WIDTH_BTR_LD_FREQ_INIT 1 -#define STB0899_BTR_FREQ_INIT (0xfffffff << 0) -#define STB0899_OFFST_BTR_FREQ_INIT 0 -#define STB0899_WIDTH_BTR_FREQ_INIT 28 - -#define STB0899_OFF0_BTR_NOM_FREQ 0xf35c -#define STB0899_BASE_BTR_NOM_FREQ 0x00000000 -#define STB0899_BTR_NOM_FREQ (0xfffffff << 0) -#define STB0899_OFFST_BTR_NOM_FREQ 0 -#define STB0899_WIDTH_BTR_NOM_FREQ 28 - -#define STB0899_OFF0_BTR_LK_CNTRL 0xf360 -#define STB0899_BASE_BTR_LK_CNTRL 0x00000000 -#define STB0899_BTR_MIN_ENERGY (0x0f << 24) -#define STB0899_OFFST_BTR_MIN_ENERGY 24 -#define STB0899_WIDTH_BTR_MIN_ENERGY 4 -#define STB0899_BTR_LOCK_TH_LO (0xff << 16) -#define STB0899_OFFST_BTR_LOCK_TH_LO 16 -#define STB0899_WIDTH_BTR_LOCK_TH_LO 8 -#define STB0899_BTR_LOCK_TH_HI (0xff << 8) -#define STB0899_OFFST_BTR_LOCK_TH_HI 8 -#define STB0899_WIDTH_BTR_LOCK_TH_HI 8 -#define STB0899_BTR_LOCK_GAIN (0x03 << 6) -#define STB0899_OFFST_BTR_LOCK_GAIN 6 -#define STB0899_WIDTH_BTR_LOCK_GAIN 2 -#define STB0899_BTR_LOCK_LEAK (0x3f << 0) -#define STB0899_OFFST_BTR_LOCK_LEAK 0 -#define STB0899_WIDTH_BTR_LOCK_LEAK 6 - -#define STB0899_OFF0_DECN_CNTRL 0xf364 -#define STB0899_BASE_DECN_CNTRL 0x00000000 - -#define STB0899_OFF0_TP_CNTRL 0xf368 -#define STB0899_BASE_TP_CNTRL 0x00000000 - -#define STB0899_OFF0_TP_BUF_STATUS 0xf36c -#define STB0899_BASE_TP_BUF_STATUS 0x00000000 -#define STB0899_TP_BUFFER_FULL (1 << 0) - -#define STB0899_OFF0_DC_ESTIM 0xf37c -#define STB0899_BASE_DC_ESTIM 0x0000 -#define STB0899_I_DC_ESTIMATE (0xff << 8) -#define STB0899_OFFST_I_DC_ESTIMATE 8 -#define STB0899_WIDTH_I_DC_ESTIMATE 8 -#define STB0899_Q_DC_ESTIMATE (0xff << 0) -#define STB0899_OFFST_Q_DC_ESTIMATE 0 -#define STB0899_WIDTH_Q_DC_ESTIMATE 8 - -#define STB0899_OFF0_FLL_CNTRL 0xf310 -#define STB0899_BASE_FLL_CNTRL 0x00000020 -#define STB0899_CRL_FLL_ACC (0x01 << 4) -#define STB0899_OFFST_CRL_FLL_ACC 4 -#define STB0899_WIDTH_CRL_FLL_ACC 1 -#define STB0899_FLL_AVG_PERIOD (0x0f << 0) -#define STB0899_OFFST_FLL_AVG_PERIOD 0 -#define STB0899_WIDTH_FLL_AVG_PERIOD 4 - -#define STB0899_OFF0_FLL_FREQ_WD 0xf314 -#define STB0899_BASE_FLL_FREQ_WD 0x00000020 -#define STB0899_FLL_FREQ_WD (0xffffffff << 0) -#define STB0899_OFFST_FLL_FREQ_WD 0 -#define STB0899_WIDTH_FLL_FREQ_WD 32 - -#define STB0899_OFF0_ANTI_ALIAS_SEL 0xf358 -#define STB0899_BASE_ANTI_ALIAS_SEL 0x00000020 -#define STB0899_ANTI_ALIAS_SELB (0x03 << 0) -#define STB0899_OFFST_ANTI_ALIAS_SELB 0 -#define STB0899_WIDTH_ANTI_ALIAS_SELB 2 - -#define STB0899_OFF0_RRC_ALPHA 0xf35c -#define STB0899_BASE_RRC_ALPHA 0x00000020 -#define STB0899_RRC_ALPHA (0x03 << 0) -#define STB0899_OFFST_RRC_ALPHA 0 -#define STB0899_WIDTH_RRC_ALPHA 2 - -#define STB0899_OFF0_DC_ADAPT_LSHFT 0xf360 -#define STB0899_BASE_DC_ADAPT_LSHFT 0x00000020 -#define STB0899_DC_ADAPT_LSHFT (0x077 << 0) -#define STB0899_OFFST_DC_ADAPT_LSHFT 0 -#define STB0899_WIDTH_DC_ADAPT_LSHFT 3 - -#define STB0899_OFF0_IMB_OFFSET 0xf364 -#define STB0899_BASE_IMB_OFFSET 0x00000020 -#define STB0899_PHS_IMB_COMP (0xff << 8) -#define STB0899_OFFST_PHS_IMB_COMP 8 -#define STB0899_WIDTH_PHS_IMB_COMP 8 -#define STB0899_AMPL_IMB_COMP (0xff << 0) -#define STB0899_OFFST_AMPL_IMB_COMP 0 -#define STB0899_WIDTH_AMPL_IMB_COMP 8 - -#define STB0899_OFF0_IMB_ESTIMATE 0xf368 -#define STB0899_BASE_IMB_ESTIMATE 0x00000020 -#define STB0899_PHS_IMB_ESTIMATE (0xff << 8) -#define STB0899_OFFST_PHS_IMB_ESTIMATE 8 -#define STB0899_WIDTH_PHS_IMB_ESTIMATE 8 -#define STB0899_AMPL_IMB_ESTIMATE (0xff << 0) -#define STB0899_OFFST_AMPL_IMB_ESTIMATE 0 -#define STB0899_WIDTH_AMPL_IMB_ESTIMATE 8 - -#define STB0899_OFF0_IMB_CNTRL 0xf36c -#define STB0899_BASE_IMB_CNTRL 0x00000020 -#define STB0899_PHS_ADAPT_LSHFT (0x07 << 4) -#define STB0899_OFFST_PHS_ADAPT_LSHFT 4 -#define STB0899_WIDTH_PHS_ADAPT_LSHFT 3 -#define STB0899_AMPL_ADAPT_LSHFT (0x07 << 1) -#define STB0899_OFFST_AMPL_ADAPT_LSHFT 1 -#define STB0899_WIDTH_AMPL_ADAPT_LSHFT 3 -#define STB0899_IMB_COMP (0x01 << 0) -#define STB0899_OFFST_IMB_COMP 0 -#define STB0899_WIDTH_IMB_COMP 1 - -#define STB0899_OFF0_IF_AGC_CNTRL2 0xf374 -#define STB0899_BASE_IF_AGC_CNTRL2 0x00000020 -#define STB0899_IF_AGC_LOCK_TH (0xff << 11) -#define STB0899_OFFST_IF_AGC_LOCK_TH 11 -#define STB0899_WIDTH_IF_AGC_LOCK_TH 8 -#define STB0899_IF_AGC_SD_DIV (0xff << 3) -#define STB0899_OFFST_IF_AGC_SD_DIV 3 -#define STB0899_WIDTH_IF_AGC_SD_DIV 8 -#define STB0899_IF_AGC_DUMP_PER (0x07 << 0) -#define STB0899_OFFST_IF_AGC_DUMP_PER 0 -#define STB0899_WIDTH_IF_AGC_DUMP_PER 3 - -#define STB0899_OFF0_DMD_CNTRL2 0xf378 -#define STB0899_BASE_DMD_CNTRL2 0x00000020 -#define STB0899_SPECTRUM_INVERT (0x01 << 2) -#define STB0899_OFFST_SPECTRUM_INVERT 2 -#define STB0899_WIDTH_SPECTRUM_INVERT 1 -#define STB0899_AGC_MODE (0x01 << 1) -#define STB0899_OFFST_AGC_MODE 1 -#define STB0899_WIDTH_AGC_MODE 1 -#define STB0899_CRL_FREQ_ADJ (0x01 << 0) -#define STB0899_OFFST_CRL_FREQ_ADJ 0 -#define STB0899_WIDTH_CRL_FREQ_ADJ 1 - -#define STB0899_OFF0_TP_BUFFER 0xf300 -#define STB0899_BASE_TP_BUFFER 0x00000040 -#define STB0899_TP_BUFFER_IN (0xffff << 0) -#define STB0899_OFFST_TP_BUFFER_IN 0 -#define STB0899_WIDTH_TP_BUFFER_IN 16 - -#define STB0899_OFF0_TP_BUFFER1 0xf304 -#define STB0899_BASE_TP_BUFFER1 0x00000040 -#define STB0899_OFF0_TP_BUFFER2 0xf308 -#define STB0899_BASE_TP_BUFFER2 0x00000040 -#define STB0899_OFF0_TP_BUFFER3 0xf30c -#define STB0899_BASE_TP_BUFFER3 0x00000040 -#define STB0899_OFF0_TP_BUFFER4 0xf310 -#define STB0899_BASE_TP_BUFFER4 0x00000040 -#define STB0899_OFF0_TP_BUFFER5 0xf314 -#define STB0899_BASE_TP_BUFFER5 0x00000040 -#define STB0899_OFF0_TP_BUFFER6 0xf318 -#define STB0899_BASE_TP_BUFFER6 0x00000040 -#define STB0899_OFF0_TP_BUFFER7 0xf31c -#define STB0899_BASE_TP_BUFFER7 0x00000040 -#define STB0899_OFF0_TP_BUFFER8 0xf320 -#define STB0899_BASE_TP_BUFFER8 0x00000040 -#define STB0899_OFF0_TP_BUFFER9 0xf324 -#define STB0899_BASE_TP_BUFFER9 0x00000040 -#define STB0899_OFF0_TP_BUFFER10 0xf328 -#define STB0899_BASE_TP_BUFFER10 0x00000040 -#define STB0899_OFF0_TP_BUFFER11 0xf32c -#define STB0899_BASE_TP_BUFFER11 0x00000040 -#define STB0899_OFF0_TP_BUFFER12 0xf330 -#define STB0899_BASE_TP_BUFFER12 0x00000040 -#define STB0899_OFF0_TP_BUFFER13 0xf334 -#define STB0899_BASE_TP_BUFFER13 0x00000040 -#define STB0899_OFF0_TP_BUFFER14 0xf338 -#define STB0899_BASE_TP_BUFFER14 0x00000040 -#define STB0899_OFF0_TP_BUFFER15 0xf33c -#define STB0899_BASE_TP_BUFFER15 0x00000040 -#define STB0899_OFF0_TP_BUFFER16 0xf340 -#define STB0899_BASE_TP_BUFFER16 0x00000040 -#define STB0899_OFF0_TP_BUFFER17 0xf344 -#define STB0899_BASE_TP_BUFFER17 0x00000040 -#define STB0899_OFF0_TP_BUFFER18 0xf348 -#define STB0899_BASE_TP_BUFFER18 0x00000040 -#define STB0899_OFF0_TP_BUFFER19 0xf34c -#define STB0899_BASE_TP_BUFFER19 0x00000040 -#define STB0899_OFF0_TP_BUFFER20 0xf350 -#define STB0899_BASE_TP_BUFFER20 0x00000040 -#define STB0899_OFF0_TP_BUFFER21 0xf354 -#define STB0899_BASE_TP_BUFFER21 0x00000040 -#define STB0899_OFF0_TP_BUFFER22 0xf358 -#define STB0899_BASE_TP_BUFFER22 0x00000040 -#define STB0899_OFF0_TP_BUFFER23 0xf35c -#define STB0899_BASE_TP_BUFFER23 0x00000040 -#define STB0899_OFF0_TP_BUFFER24 0xf360 -#define STB0899_BASE_TP_BUFFER24 0x00000040 -#define STB0899_OFF0_TP_BUFFER25 0xf364 -#define STB0899_BASE_TP_BUFFER25 0x00000040 -#define STB0899_OFF0_TP_BUFFER26 0xf368 -#define STB0899_BASE_TP_BUFFER26 0x00000040 -#define STB0899_OFF0_TP_BUFFER27 0xf36c -#define STB0899_BASE_TP_BUFFER27 0x00000040 -#define STB0899_OFF0_TP_BUFFER28 0xf370 -#define STB0899_BASE_TP_BUFFER28 0x00000040 -#define STB0899_OFF0_TP_BUFFER29 0xf374 -#define STB0899_BASE_TP_BUFFER29 0x00000040 -#define STB0899_OFF0_TP_BUFFER30 0xf378 -#define STB0899_BASE_TP_BUFFER30 0x00000040 -#define STB0899_OFF0_TP_BUFFER31 0xf37c -#define STB0899_BASE_TP_BUFFER31 0x00000040 -#define STB0899_OFF0_TP_BUFFER32 0xf300 -#define STB0899_BASE_TP_BUFFER32 0x00000060 -#define STB0899_OFF0_TP_BUFFER33 0xf304 -#define STB0899_BASE_TP_BUFFER33 0x00000060 -#define STB0899_OFF0_TP_BUFFER34 0xf308 -#define STB0899_BASE_TP_BUFFER34 0x00000060 -#define STB0899_OFF0_TP_BUFFER35 0xf30c -#define STB0899_BASE_TP_BUFFER35 0x00000060 -#define STB0899_OFF0_TP_BUFFER36 0xf310 -#define STB0899_BASE_TP_BUFFER36 0x00000060 -#define STB0899_OFF0_TP_BUFFER37 0xf314 -#define STB0899_BASE_TP_BUFFER37 0x00000060 -#define STB0899_OFF0_TP_BUFFER38 0xf318 -#define STB0899_BASE_TP_BUFFER38 0x00000060 -#define STB0899_OFF0_TP_BUFFER39 0xf31c -#define STB0899_BASE_TP_BUFFER39 0x00000060 -#define STB0899_OFF0_TP_BUFFER40 0xf320 -#define STB0899_BASE_TP_BUFFER40 0x00000060 -#define STB0899_OFF0_TP_BUFFER41 0xf324 -#define STB0899_BASE_TP_BUFFER41 0x00000060 -#define STB0899_OFF0_TP_BUFFER42 0xf328 -#define STB0899_BASE_TP_BUFFER42 0x00000060 -#define STB0899_OFF0_TP_BUFFER43 0xf32c -#define STB0899_BASE_TP_BUFFER43 0x00000060 -#define STB0899_OFF0_TP_BUFFER44 0xf330 -#define STB0899_BASE_TP_BUFFER44 0x00000060 -#define STB0899_OFF0_TP_BUFFER45 0xf334 -#define STB0899_BASE_TP_BUFFER45 0x00000060 -#define STB0899_OFF0_TP_BUFFER46 0xf338 -#define STB0899_BASE_TP_BUFFER46 0x00000060 -#define STB0899_OFF0_TP_BUFFER47 0xf33c -#define STB0899_BASE_TP_BUFFER47 0x00000060 -#define STB0899_OFF0_TP_BUFFER48 0xf340 -#define STB0899_BASE_TP_BUFFER48 0x00000060 -#define STB0899_OFF0_TP_BUFFER49 0xf344 -#define STB0899_BASE_TP_BUFFER49 0x00000060 -#define STB0899_OFF0_TP_BUFFER50 0xf348 -#define STB0899_BASE_TP_BUFFER50 0x00000060 -#define STB0899_OFF0_TP_BUFFER51 0xf34c -#define STB0899_BASE_TP_BUFFER51 0x00000060 -#define STB0899_OFF0_TP_BUFFER52 0xf350 -#define STB0899_BASE_TP_BUFFER52 0x00000060 -#define STB0899_OFF0_TP_BUFFER53 0xf354 -#define STB0899_BASE_TP_BUFFER53 0x00000060 -#define STB0899_OFF0_TP_BUFFER54 0xf358 -#define STB0899_BASE_TP_BUFFER54 0x00000060 -#define STB0899_OFF0_TP_BUFFER55 0xf35c -#define STB0899_BASE_TP_BUFFER55 0x00000060 -#define STB0899_OFF0_TP_BUFFER56 0xf360 -#define STB0899_BASE_TP_BUFFER56 0x00000060 -#define STB0899_OFF0_TP_BUFFER57 0xf364 -#define STB0899_BASE_TP_BUFFER57 0x00000060 -#define STB0899_OFF0_TP_BUFFER58 0xf368 -#define STB0899_BASE_TP_BUFFER58 0x00000060 -#define STB0899_OFF0_TP_BUFFER59 0xf36c -#define STB0899_BASE_TP_BUFFER59 0x00000060 -#define STB0899_OFF0_TP_BUFFER60 0xf370 -#define STB0899_BASE_TP_BUFFER60 0x00000060 -#define STB0899_OFF0_TP_BUFFER61 0xf374 -#define STB0899_BASE_TP_BUFFER61 0x00000060 -#define STB0899_OFF0_TP_BUFFER62 0xf378 -#define STB0899_BASE_TP_BUFFER62 0x00000060 -#define STB0899_OFF0_TP_BUFFER63 0xf37c -#define STB0899_BASE_TP_BUFFER63 0x00000060 - -#define STB0899_OFF0_RESET_CNTRL 0xf300 -#define STB0899_BASE_RESET_CNTRL 0x00000400 -#define STB0899_DVBS2_RESET (0x01 << 0) -#define STB0899_OFFST_DVBS2_RESET 0 -#define STB0899_WIDTH_DVBS2_RESET 1 - -#define STB0899_OFF0_ACM_ENABLE 0xf304 -#define STB0899_BASE_ACM_ENABLE 0x00000400 -#define STB0899_ACM_ENABLE 1 - -#define STB0899_OFF0_DESCR_CNTRL 0xf30c -#define STB0899_BASE_DESCR_CNTRL 0x00000400 -#define STB0899_OFFST_DESCR_CNTRL 0 -#define STB0899_WIDTH_DESCR_CNTRL 16 - -#define STB0899_OFF0_UWP_CNTRL1 0xf320 -#define STB0899_BASE_UWP_CNTRL1 0x00000400 -#define STB0899_UWP_TH_SOF (0x7fff << 11) -#define STB0899_OFFST_UWP_TH_SOF 11 -#define STB0899_WIDTH_UWP_TH_SOF 15 -#define STB0899_UWP_ESN0_QUANT (0xff << 3) -#define STB0899_OFFST_UWP_ESN0_QUANT 3 -#define STB0899_WIDTH_UWP_ESN0_QUANT 8 -#define STB0899_UWP_ESN0_AVE (0x03 << 1) -#define STB0899_OFFST_UWP_ESN0_AVE 1 -#define STB0899_WIDTH_UWP_ESN0_AVE 2 -#define STB0899_UWP_START (0x01 << 0) -#define STB0899_OFFST_UWP_START 0 -#define STB0899_WIDTH_UWP_START 1 - -#define STB0899_OFF0_UWP_CNTRL2 0xf324 -#define STB0899_BASE_UWP_CNTRL2 0x00000400 -#define STB0899_UWP_MISS_TH (0xff << 16) -#define STB0899_OFFST_UWP_MISS_TH 16 -#define STB0899_WIDTH_UWP_MISS_TH 8 -#define STB0899_FE_FINE_TRK (0xff << 8) -#define STB0899_OFFST_FE_FINE_TRK 8 -#define STB0899_WIDTH_FE_FINE_TRK 8 -#define STB0899_FE_COARSE_TRK (0xff << 0) -#define STB0899_OFFST_FE_COARSE_TRK 0 -#define STB0899_WIDTH_FE_COARSE_TRK 8 - -#define STB0899_OFF0_UWP_STAT1 0xf328 -#define STB0899_BASE_UWP_STAT1 0x00000400 -#define STB0899_UWP_STATE (0x03ff << 15) -#define STB0899_OFFST_UWP_STATE 15 -#define STB0899_WIDTH_UWP_STATE 10 -#define STB0899_UW_MAX_PEAK (0x7fff << 0) -#define STB0899_OFFST_UW_MAX_PEAK 0 -#define STB0899_WIDTH_UW_MAX_PEAK 15 - -#define STB0899_OFF0_UWP_STAT2 0xf32c -#define STB0899_BASE_UWP_STAT2 0x00000400 -#define STB0899_ESNO_EST (0x07ffff << 7) -#define STB0899_OFFST_ESN0_EST 7 -#define STB0899_WIDTH_ESN0_EST 19 -#define STB0899_UWP_DECODE_MOD (0x7f << 0) -#define STB0899_OFFST_UWP_DECODE_MOD 0 -#define STB0899_WIDTH_UWP_DECODE_MOD 7 - -#define STB0899_OFF0_DMD_CORE_ID 0xf334 -#define STB0899_BASE_DMD_CORE_ID 0x00000400 -#define STB0899_CORE_ID (0xffffffff << 0) -#define STB0899_OFFST_CORE_ID 0 -#define STB0899_WIDTH_CORE_ID 32 - -#define STB0899_OFF0_DMD_VERSION_ID 0xf33c -#define STB0899_BASE_DMD_VERSION_ID 0x00000400 -#define STB0899_VERSION_ID (0xff << 0) -#define STB0899_OFFST_VERSION_ID 0 -#define STB0899_WIDTH_VERSION_ID 8 - -#define STB0899_OFF0_DMD_STAT2 0xf340 -#define STB0899_BASE_DMD_STAT2 0x00000400 -#define STB0899_CSM_LOCK (0x01 << 1) -#define STB0899_OFFST_CSM_LOCK 1 -#define STB0899_WIDTH_CSM_LOCK 1 -#define STB0899_UWP_LOCK (0x01 << 0) -#define STB0899_OFFST_UWP_LOCK 0 -#define STB0899_WIDTH_UWP_LOCK 1 - -#define STB0899_OFF0_FREQ_ADJ_SCALE 0xf344 -#define STB0899_BASE_FREQ_ADJ_SCALE 0x00000400 -#define STB0899_FREQ_ADJ_SCALE (0x0fff << 0) -#define STB0899_OFFST_FREQ_ADJ_SCALE 0 -#define STB0899_WIDTH_FREQ_ADJ_SCALE 12 - -#define STB0899_OFF0_UWP_CNTRL3 0xf34c -#define STB0899_BASE_UWP_CNTRL3 0x00000400 -#define STB0899_UWP_TH_TRACK (0x7fff << 15) -#define STB0899_OFFST_UWP_TH_TRACK 15 -#define STB0899_WIDTH_UWP_TH_TRACK 15 -#define STB0899_UWP_TH_ACQ (0x7fff << 0) -#define STB0899_OFFST_UWP_TH_ACQ 0 -#define STB0899_WIDTH_UWP_TH_ACQ 15 - -#define STB0899_OFF0_SYM_CLK_SEL 0xf350 -#define STB0899_BASE_SYM_CLK_SEL 0x00000400 -#define STB0899_SYM_CLK_SEL (0x03 << 0) -#define STB0899_OFFST_SYM_CLK_SEL 0 -#define STB0899_WIDTH_SYM_CLK_SEL 2 - -#define STB0899_OFF0_SOF_SRCH_TO 0xf354 -#define STB0899_BASE_SOF_SRCH_TO 0x00000400 -#define STB0899_SOF_SEARCH_TIMEOUT (0x3fffff << 0) -#define STB0899_OFFST_SOF_SEARCH_TIMEOUT 0 -#define STB0899_WIDTH_SOF_SEARCH_TIMEOUT 22 - -#define STB0899_OFF0_ACQ_CNTRL1 0xf358 -#define STB0899_BASE_ACQ_CNTRL1 0x00000400 -#define STB0899_FE_FINE_ACQ (0xff << 8) -#define STB0899_OFFST_FE_FINE_ACQ 8 -#define STB0899_WIDTH_FE_FINE_ACQ 8 -#define STB0899_FE_COARSE_ACQ (0xff << 0) -#define STB0899_OFFST_FE_COARSE_ACQ 0 -#define STB0899_WIDTH_FE_COARSE_ACQ 8 - -#define STB0899_OFF0_ACQ_CNTRL2 0xf35c -#define STB0899_BASE_ACQ_CNTRL2 0x00000400 -#define STB0899_ZIGZAG (0x01 << 25) -#define STB0899_OFFST_ZIGZAG 25 -#define STB0899_WIDTH_ZIGZAG 1 -#define STB0899_NUM_STEPS (0xff << 17) -#define STB0899_OFFST_NUM_STEPS 17 -#define STB0899_WIDTH_NUM_STEPS 8 -#define STB0899_FREQ_STEPSIZE (0x1ffff << 0) -#define STB0899_OFFST_FREQ_STEPSIZE 0 -#define STB0899_WIDTH_FREQ_STEPSIZE 17 - -#define STB0899_OFF0_ACQ_CNTRL3 0xf360 -#define STB0899_BASE_ACQ_CNTRL3 0x00000400 -#define STB0899_THRESHOLD_SCL (0x3f << 23) -#define STB0899_OFFST_THRESHOLD_SCL 23 -#define STB0899_WIDTH_THRESHOLD_SCL 6 -#define STB0899_UWP_TH_SRCH (0x7fff << 8) -#define STB0899_OFFST_UWP_TH_SRCH 8 -#define STB0899_WIDTH_UWP_TH_SRCH 15 -#define STB0899_AUTO_REACQUIRE (0x01 << 7) -#define STB0899_OFFST_AUTO_REACQUIRE 7 -#define STB0899_WIDTH_AUTO_REACQUIRE 1 -#define STB0899_TRACK_LOCK_SEL (0x01 << 6) -#define STB0899_OFFST_TRACK_LOCK_SEL 6 -#define STB0899_WIDTH_TRACK_LOCK_SEL 1 -#define STB0899_ACQ_SEARCH_MODE (0x03 << 4) -#define STB0899_OFFST_ACQ_SEARCH_MODE 4 -#define STB0899_WIDTH_ACQ_SEARCH_MODE 2 -#define STB0899_CONFIRM_FRAMES (0x0f << 0) -#define STB0899_OFFST_CONFIRM_FRAMES 0 -#define STB0899_WIDTH_CONFIRM_FRAMES 4 - -#define STB0899_OFF0_FE_SETTLE 0xf364 -#define STB0899_BASE_FE_SETTLE 0x00000400 -#define STB0899_SETTLING_TIME (0x3fffff << 0) -#define STB0899_OFFST_SETTLING_TIME 0 -#define STB0899_WIDTH_SETTLING_TIME 22 - -#define STB0899_OFF0_AC_DWELL 0xf368 -#define STB0899_BASE_AC_DWELL 0x00000400 -#define STB0899_DWELL_TIME (0x3fffff << 0) -#define STB0899_OFFST_DWELL_TIME 0 -#define STB0899_WIDTH_DWELL_TIME 22 - -#define STB0899_OFF0_ACQUIRE_TRIG 0xf36c -#define STB0899_BASE_ACQUIRE_TRIG 0x00000400 -#define STB0899_ACQUIRE (0x01 << 0) -#define STB0899_OFFST_ACQUIRE 0 -#define STB0899_WIDTH_ACQUIRE 1 - -#define STB0899_OFF0_LOCK_LOST 0xf370 -#define STB0899_BASE_LOCK_LOST 0x00000400 -#define STB0899_LOCK_LOST (0x01 << 0) -#define STB0899_OFFST_LOCK_LOST 0 -#define STB0899_WIDTH_LOCK_LOST 1 - -#define STB0899_OFF0_ACQ_STAT1 0xf374 -#define STB0899_BASE_ACQ_STAT1 0x00000400 -#define STB0899_STEP_FREQ (0x1fffff << 11) -#define STB0899_OFFST_STEP_FREQ 11 -#define STB0899_WIDTH_STEP_FREQ 21 -#define STB0899_ACQ_STATE (0x07 << 8) -#define STB0899_OFFST_ACQ_STATE 8 -#define STB0899_WIDTH_ACQ_STATE 3 -#define STB0899_UW_DETECT_COUNT (0xff << 0) -#define STB0899_OFFST_UW_DETECT_COUNT 0 -#define STB0899_WIDTH_UW_DETECT_COUNT 8 - -#define STB0899_OFF0_ACQ_TIMEOUT 0xf378 -#define STB0899_BASE_ACQ_TIMEOUT 0x00000400 -#define STB0899_ACQ_TIMEOUT (0x3fffff << 0) -#define STB0899_OFFST_ACQ_TIMEOUT 0 -#define STB0899_WIDTH_ACQ_TIMEOUT 22 - -#define STB0899_OFF0_ACQ_TIME 0xf37c -#define STB0899_BASE_ACQ_TIME 0x00000400 -#define STB0899_ACQ_TIME_SYM (0xffffff << 0) -#define STB0899_OFFST_ACQ_TIME_SYM 0 -#define STB0899_WIDTH_ACQ_TIME_SYM 24 - -#define STB0899_OFF0_FINAL_AGC_CNTRL 0xf308 -#define STB0899_BASE_FINAL_AGC_CNTRL 0x00000440 -#define STB0899_FINAL_GAIN_INIT (0x3fff << 12) -#define STB0899_OFFST_FINAL_GAIN_INIT 12 -#define STB0899_WIDTH_FINAL_GAIN_INIT 14 -#define STB0899_FINAL_LOOP_GAIN (0x0f << 8) -#define STB0899_OFFST_FINAL_LOOP_GAIN 8 -#define STB0899_WIDTH_FINAL_LOOP_GAIN 4 -#define STB0899_FINAL_LD_GAIN_INIT (0x01 << 7) -#define STB0899_OFFST_FINAL_LD_GAIN_INIT 7 -#define STB0899_WIDTH_FINAL_LD_GAIN_INIT 1 -#define STB0899_FINAL_AGC_REF (0x7f << 0) -#define STB0899_OFFST_FINAL_AGC_REF 0 -#define STB0899_WIDTH_FINAL_AGC_REF 7 - -#define STB0899_OFF0_FINAL_AGC_GAIN 0xf30c -#define STB0899_BASE_FINAL_AGC_GAIN 0x00000440 -#define STB0899_FINAL_AGC_GAIN (0x3fff << 0) -#define STB0899_OFFST_FINAL_AGC_GAIN 0 -#define STB0899_WIDTH_FINAL_AGC_GAIN 14 - -#define STB0899_OFF0_EQUALIZER_INIT 0xf310 -#define STB0899_BASE_EQUALIZER_INIT 0x00000440 -#define STB0899_EQ_SRST (0x01 << 1) -#define STB0899_OFFST_EQ_SRST 1 -#define STB0899_WIDTH_EQ_SRST 1 -#define STB0899_EQ_INIT (0x01 << 0) -#define STB0899_OFFST_EQ_INIT 0 -#define STB0899_WIDTH_EQ_INIT 1 - -#define STB0899_OFF0_EQ_CNTRL 0xf314 -#define STB0899_BASE_EQ_CNTRL 0x00000440 -#define STB0899_EQ_ADAPT_MODE (0x01 << 18) -#define STB0899_OFFST_EQ_ADAPT_MODE 18 -#define STB0899_WIDTH_EQ_ADAPT_MODE 1 -#define STB0899_EQ_DELAY (0x0f << 14) -#define STB0899_OFFST_EQ_DELAY 14 -#define STB0899_WIDTH_EQ_DELAY 4 -#define STB0899_EQ_QUANT_LEVEL (0xff << 6) -#define STB0899_OFFST_EQ_QUANT_LEVEL 6 -#define STB0899_WIDTH_EQ_QUANT_LEVEL 8 -#define STB0899_EQ_DISABLE_UPDATE (0x01 << 5) -#define STB0899_OFFST_EQ_DISABLE_UPDATE 5 -#define STB0899_WIDTH_EQ_DISABLE_UPDATE 1 -#define STB0899_EQ_BYPASS (0x01 << 4) -#define STB0899_OFFST_EQ_BYPASS 4 -#define STB0899_WIDTH_EQ_BYPASS 1 -#define STB0899_EQ_SHIFT (0x0f << 0) -#define STB0899_OFFST_EQ_SHIFT 0 -#define STB0899_WIDTH_EQ_SHIFT 4 - -#define STB0899_OFF0_EQ_I_INIT_COEFF_0 0xf320 -#define STB0899_OFF1_EQ_I_INIT_COEFF_1 0xf324 -#define STB0899_OFF2_EQ_I_INIT_COEFF_2 0xf328 -#define STB0899_OFF3_EQ_I_INIT_COEFF_3 0xf32c -#define STB0899_OFF4_EQ_I_INIT_COEFF_4 0xf330 -#define STB0899_OFF5_EQ_I_INIT_COEFF_5 0xf334 -#define STB0899_OFF6_EQ_I_INIT_COEFF_6 0xf338 -#define STB0899_OFF7_EQ_I_INIT_COEFF_7 0xf33c -#define STB0899_OFF8_EQ_I_INIT_COEFF_8 0xf340 -#define STB0899_OFF9_EQ_I_INIT_COEFF_9 0xf344 -#define STB0899_OFFa_EQ_I_INIT_COEFF_10 0xf348 -#define STB0899_BASE_EQ_I_INIT_COEFF_N 0x00000440 -#define STB0899_EQ_I_INIT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_I_INIT_COEFF_N 0 -#define STB0899_WIDTH_EQ_I_INIT_COEFF_N 12 - -#define STB0899_OFF0_EQ_Q_INIT_COEFF_0 0xf350 -#define STB0899_OFF1_EQ_Q_INIT_COEFF_1 0xf354 -#define STB0899_OFF2_EQ_Q_INIT_COEFF_2 0xf358 -#define STB0899_OFF3_EQ_Q_INIT_COEFF_3 0xf35c -#define STB0899_OFF4_EQ_Q_INIT_COEFF_4 0xf360 -#define STB0899_OFF5_EQ_Q_INIT_COEFF_5 0xf364 -#define STB0899_OFF6_EQ_Q_INIT_COEFF_6 0xf368 -#define STB0899_OFF7_EQ_Q_INIT_COEFF_7 0xf36c -#define STB0899_OFF8_EQ_Q_INIT_COEFF_8 0xf370 -#define STB0899_OFF9_EQ_Q_INIT_COEFF_9 0xf374 -#define STB0899_OFFa_EQ_Q_INIT_COEFF_10 0xf378 -#define STB0899_BASE_EQ_Q_INIT_COEFF_N 0x00000440 -#define STB0899_EQ_Q_INIT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_Q_INIT_COEFF_N 0 -#define STB0899_WIDTH_EQ_Q_INIT_COEFF_N 12 - -#define STB0899_OFF0_EQ_I_OUT_COEFF_0 0xf300 -#define STB0899_OFF1_EQ_I_OUT_COEFF_1 0xf304 -#define STB0899_OFF2_EQ_I_OUT_COEFF_2 0xf308 -#define STB0899_OFF3_EQ_I_OUT_COEFF_3 0xf30c -#define STB0899_OFF4_EQ_I_OUT_COEFF_4 0xf310 -#define STB0899_OFF5_EQ_I_OUT_COEFF_5 0xf314 -#define STB0899_OFF6_EQ_I_OUT_COEFF_6 0xf318 -#define STB0899_OFF7_EQ_I_OUT_COEFF_7 0xf31c -#define STB0899_OFF8_EQ_I_OUT_COEFF_8 0xf320 -#define STB0899_OFF9_EQ_I_OUT_COEFF_9 0xf324 -#define STB0899_OFFa_EQ_I_OUT_COEFF_10 0xf328 -#define STB0899_BASE_EQ_I_OUT_COEFF_N 0x00000460 -#define STB0899_EQ_I_OUT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_I_OUT_COEFF_N 0 -#define STB0899_WIDTH_EQ_I_OUT_COEFF_N 12 - -#define STB0899_OFF0_EQ_Q_OUT_COEFF_0 0xf330 -#define STB0899_OFF1_EQ_Q_OUT_COEFF_1 0xf334 -#define STB0899_OFF2_EQ_Q_OUT_COEFF_2 0xf338 -#define STB0899_OFF3_EQ_Q_OUT_COEFF_3 0xf33c -#define STB0899_OFF4_EQ_Q_OUT_COEFF_4 0xf340 -#define STB0899_OFF5_EQ_Q_OUT_COEFF_5 0xf344 -#define STB0899_OFF6_EQ_Q_OUT_COEFF_6 0xf348 -#define STB0899_OFF7_EQ_Q_OUT_COEFF_7 0xf34c -#define STB0899_OFF8_EQ_Q_OUT_COEFF_8 0xf350 -#define STB0899_OFF9_EQ_Q_OUT_COEFF_9 0xf354 -#define STB0899_OFFa_EQ_Q_OUT_COEFF_10 0xf358 -#define STB0899_BASE_EQ_Q_OUT_COEFF_N 0x00000460 -#define STB0899_EQ_Q_OUT_COEFF_N (0x0fff << 0) -#define STB0899_OFFST_EQ_Q_OUT_COEFF_N 0 -#define STB0899_WIDTH_EQ_Q_OUT_COEFF_N 12 - -/* S2 FEC */ -#define STB0899_OFF0_BLOCK_LNGTH 0xfa04 -#define STB0899_BASE_BLOCK_LNGTH 0x00000000 -#define STB0899_BLOCK_LENGTH (0xff << 0) -#define STB0899_OFFST_BLOCK_LENGTH 0 -#define STB0899_WIDTH_BLOCK_LENGTH 8 - -#define STB0899_OFF0_ROW_STR 0xfa08 -#define STB0899_BASE_ROW_STR 0x00000000 -#define STB0899_ROW_STRIDE (0xff << 0) -#define STB0899_OFFST_ROW_STRIDE 0 -#define STB0899_WIDTH_ROW_STRIDE 8 - -#define STB0899_OFF0_MAX_ITER 0xfa0c -#define STB0899_BASE_MAX_ITER 0x00000000 -#define STB0899_MAX_ITERATIONS (0xff << 0) -#define STB0899_OFFST_MAX_ITERATIONS 0 -#define STB0899_WIDTH_MAX_ITERATIONS 8 - -#define STB0899_OFF0_BN_END_ADDR 0xfa10 -#define STB0899_BASE_BN_END_ADDR 0x00000000 -#define STB0899_BN_END_ADDR (0x0fff << 0) -#define STB0899_OFFST_BN_END_ADDR 0 -#define STB0899_WIDTH_BN_END_ADDR 12 - -#define STB0899_OFF0_CN_END_ADDR 0xfa14 -#define STB0899_BASE_CN_END_ADDR 0x00000000 -#define STB0899_CN_END_ADDR (0x0fff << 0) -#define STB0899_OFFST_CN_END_ADDR 0 -#define STB0899_WIDTH_CN_END_ADDR 12 - -#define STB0899_OFF0_INFO_LENGTH 0xfa1c -#define STB0899_BASE_INFO_LENGTH 0x00000000 -#define STB0899_INFO_LENGTH (0xff << 0) -#define STB0899_OFFST_INFO_LENGTH 0 -#define STB0899_WIDTH_INFO_LENGTH 8 - -#define STB0899_OFF0_BOT_ADDR 0xfa20 -#define STB0899_BASE_BOT_ADDR 0x00000000 -#define STB0899_BOTTOM_BASE_ADDR (0x03ff << 0) -#define STB0899_OFFST_BOTTOM_BASE_ADDR 0 -#define STB0899_WIDTH_BOTTOM_BASE_ADDR 10 - -#define STB0899_OFF0_BCH_BLK_LN 0xfa24 -#define STB0899_BASE_BCH_BLK_LN 0x00000000 -#define STB0899_BCH_BLOCK_LENGTH (0xffff << 0) -#define STB0899_OFFST_BCH_BLOCK_LENGTH 0 -#define STB0899_WIDTH_BCH_BLOCK_LENGTH 16 - -#define STB0899_OFF0_BCH_T 0xfa28 -#define STB0899_BASE_BCH_T 0x00000000 -#define STB0899_BCH_T (0x0f << 0) -#define STB0899_OFFST_BCH_T 0 -#define STB0899_WIDTH_BCH_T 4 - -#define STB0899_OFF0_CNFG_MODE 0xfa00 -#define STB0899_BASE_CNFG_MODE 0x00000800 -#define STB0899_MODCOD (0x1f << 2) -#define STB0899_OFFST_MODCOD 2 -#define STB0899_WIDTH_MODCOD 5 -#define STB0899_MODCOD_SEL (0x01 << 1) -#define STB0899_OFFST_MODCOD_SEL 1 -#define STB0899_WIDTH_MODCOD_SEL 1 -#define STB0899_CONFIG_MODE (0x01 << 0) -#define STB0899_OFFST_CONFIG_MODE 0 -#define STB0899_WIDTH_CONFIG_MODE 1 - -#define STB0899_OFF0_LDPC_STAT 0xfa04 -#define STB0899_BASE_LDPC_STAT 0x00000800 -#define STB0899_ITERATION (0xff << 3) -#define STB0899_OFFST_ITERATION 3 -#define STB0899_WIDTH_ITERATION 8 -#define STB0899_LDPC_DEC_STATE (0x07 << 0) -#define STB0899_OFFST_LDPC_DEC_STATE 0 -#define STB0899_WIDTH_LDPC_DEC_STATE 3 - -#define STB0899_OFF0_ITER_SCALE 0xfa08 -#define STB0899_BASE_ITER_SCALE 0x00000800 -#define STB0899_ITERATION_SCALE (0xff << 0) -#define STB0899_OFFST_ITERATION_SCALE 0 -#define STB0899_WIDTH_ITERATION_SCALE 8 - -#define STB0899_OFF0_INPUT_MODE 0xfa0c -#define STB0899_BASE_INPUT_MODE 0x00000800 -#define STB0899_SD_BLOCK1_STREAM0 (0x01 << 0) -#define STB0899_OFFST_SD_BLOCK1_STREAM0 0 -#define STB0899_WIDTH_SD_BLOCK1_STREAM0 1 - -#define STB0899_OFF0_LDPCDECRST 0xfa10 -#define STB0899_BASE_LDPCDECRST 0x00000800 -#define STB0899_LDPC_DEC_RST (0x01 << 0) -#define STB0899_OFFST_LDPC_DEC_RST 0 -#define STB0899_WIDTH_LDPC_DEC_RST 1 - -#define STB0899_OFF0_CLK_PER_BYTE_RW 0xfa14 -#define STB0899_BASE_CLK_PER_BYTE_RW 0x00000800 -#define STB0899_CLKS_PER_BYTE (0x0f << 0) -#define STB0899_OFFST_CLKS_PER_BYTE 0 -#define STB0899_WIDTH_CLKS_PER_BYTE 5 - -#define STB0899_OFF0_BCH_ERRORS 0xfa18 -#define STB0899_BASE_BCH_ERRORS 0x00000800 -#define STB0899_BCH_ERRORS (0x0f << 0) -#define STB0899_OFFST_BCH_ERRORS 0 -#define STB0899_WIDTH_BCH_ERRORS 4 - -#define STB0899_OFF0_LDPC_ERRORS 0xfa1c -#define STB0899_BASE_LDPC_ERRORS 0x00000800 -#define STB0899_LDPC_ERRORS (0xffff << 0) -#define STB0899_OFFST_LDPC_ERRORS 0 -#define STB0899_WIDTH_LDPC_ERRORS 16 - -#define STB0899_OFF0_BCH_MODE 0xfa20 -#define STB0899_BASE_BCH_MODE 0x00000800 -#define STB0899_BCH_CORRECT_N (0x01 << 1) -#define STB0899_OFFST_BCH_CORRECT_N 1 -#define STB0899_WIDTH_BCH_CORRECT_N 1 -#define STB0899_FULL_BYPASS (0x01 << 0) -#define STB0899_OFFST_FULL_BYPASS 0 -#define STB0899_WIDTH_FULL_BYPASS 1 - -#define STB0899_OFF0_ERR_ACC_PER 0xfa24 -#define STB0899_BASE_ERR_ACC_PER 0x00000800 -#define STB0899_BCH_ERR_ACC_PERIOD (0x0f << 0) -#define STB0899_OFFST_BCH_ERR_ACC_PERIOD 0 -#define STB0899_WIDTH_BCH_ERR_ACC_PERIOD 4 - -#define STB0899_OFF0_BCH_ERR_ACC 0xfa28 -#define STB0899_BASE_BCH_ERR_ACC 0x00000800 -#define STB0899_BCH_ERR_ACCUM (0xff << 0) -#define STB0899_OFFST_BCH_ERR_ACCUM 0 -#define STB0899_WIDTH_BCH_ERR_ACCUM 8 - -#define STB0899_OFF0_FEC_CORE_ID_REG 0xfa2c -#define STB0899_BASE_FEC_CORE_ID_REG 0x00000800 -#define STB0899_FEC_CORE_ID (0xffffffff << 0) -#define STB0899_OFFST_FEC_CORE_ID 0 -#define STB0899_WIDTH_FEC_CORE_ID 32 - -#define STB0899_OFF0_FEC_VER_ID_REG 0xfa34 -#define STB0899_BASE_FEC_VER_ID_REG 0x00000800 -#define STB0899_FEC_VER_ID (0xff << 0) -#define STB0899_OFFST_FEC_VER_ID 0 -#define STB0899_WIDTH_FEC_VER_ID 8 - -#define STB0899_OFF0_FEC_TP_SEL 0xfa38 -#define STB0899_BASE_FEC_TP_SEL 0x00000800 - -#define STB0899_OFF0_CSM_CNTRL1 0xf310 -#define STB0899_BASE_CSM_CNTRL1 0x00000400 -#define STB0899_CSM_FORCE_FREQLOCK (0x01 << 19) -#define STB0899_OFFST_CSM_FORCE_FREQLOCK 19 -#define STB0899_WIDTH_CSM_FORCE_FREQLOCK 1 -#define STB0899_CSM_FREQ_LOCKSTATE (0x01 << 18) -#define STB0899_OFFST_CSM_FREQ_LOCKSTATE 18 -#define STB0899_WIDTH_CSM_FREQ_LOCKSTATE 1 -#define STB0899_CSM_AUTO_PARAM (0x01 << 17) -#define STB0899_OFFST_CSM_AUTO_PARAM 17 -#define STB0899_WIDTH_CSM_AUTO_PARAM 1 -#define STB0899_FE_LOOP_SHIFT (0x07 << 14) -#define STB0899_OFFST_FE_LOOP_SHIFT 14 -#define STB0899_WIDTH_FE_LOOP_SHIFT 3 -#define STB0899_CSM_AGC_SHIFT (0x07 << 11) -#define STB0899_OFFST_CSM_AGC_SHIFT 11 -#define STB0899_WIDTH_CSM_AGC_SHIFT 3 -#define STB0899_CSM_AGC_GAIN (0x1ff << 2) -#define STB0899_OFFST_CSM_AGC_GAIN 2 -#define STB0899_WIDTH_CSM_AGC_GAIN 9 -#define STB0899_CSM_TWO_PASS (0x01 << 1) -#define STB0899_OFFST_CSM_TWO_PASS 1 -#define STB0899_WIDTH_CSM_TWO_PASS 1 -#define STB0899_CSM_DVT_TABLE (0x01 << 0) -#define STB0899_OFFST_CSM_DVT_TABLE 0 -#define STB0899_WIDTH_CSM_DVT_TABLE 1 - -#define STB0899_OFF0_CSM_CNTRL2 0xf314 -#define STB0899_BASE_CSM_CNTRL2 0x00000400 -#define STB0899_CSM_GAMMA_RHO_ACQ (0x1ff << 9) -#define STB0899_OFFST_CSM_GAMMA_RHOACQ 9 -#define STB0899_WIDTH_CSM_GAMMA_RHOACQ 9 -#define STB0899_CSM_GAMMA_ACQ (0x1ff << 0) -#define STB0899_OFFST_CSM_GAMMA_ACQ 0 -#define STB0899_WIDTH_CSM_GAMMA_ACQ 9 - -#define STB0899_OFF0_CSM_CNTRL3 0xf318 -#define STB0899_BASE_CSM_CNTRL3 0x00000400 -#define STB0899_CSM_GAMMA_RHO_TRACK (0x1ff << 9) -#define STB0899_OFFST_CSM_GAMMA_RHOTRACK 9 -#define STB0899_WIDTH_CSM_GAMMA_RHOTRACK 9 -#define STB0899_CSM_GAMMA_TRACK (0x1ff << 0) -#define STB0899_OFFST_CSM_GAMMA_TRACK 0 -#define STB0899_WIDTH_CSM_GAMMA_TRACK 9 - -#define STB0899_OFF0_CSM_CNTRL4 0xf31c -#define STB0899_BASE_CSM_CNTRL4 0x00000400 -#define STB0899_CSM_PHASEDIFF_THRESH (0x0f << 8) -#define STB0899_OFFST_CSM_PHASEDIFF_THRESH 8 -#define STB0899_WIDTH_CSM_PHASEDIFF_THRESH 4 -#define STB0899_CSM_LOCKCOUNT_THRESH (0xff << 0) -#define STB0899_OFFST_CSM_LOCKCOUNT_THRESH 0 -#define STB0899_WIDTH_CSM_LOCKCOUNT_THRESH 8 - -/* Check on chapter 8 page 42 */ -#define STB0899_ERRCTRL1 0xf574 -#define STB0899_ERRCTRL2 0xf575 -#define STB0899_ERRCTRL3 0xf576 -#define STB0899_ERR_SRC_S1 (0x1f << 3) -#define STB0899_OFFST_ERR_SRC_S1 3 -#define STB0899_WIDTH_ERR_SRC_S1 5 -#define STB0899_ERR_SRC_S2 (0x0f << 0) -#define STB0899_OFFST_ERR_SRC_S2 0 -#define STB0899_WIDTH_ERR_SRC_S2 4 -#define STB0899_NOE (0x07 << 0) -#define STB0899_OFFST_NOE 0 -#define STB0899_WIDTH_NOE 3 - -#define STB0899_ECNT1M 0xf524 -#define STB0899_ECNT1L 0xf525 -#define STB0899_ECNT2M 0xf526 -#define STB0899_ECNT2L 0xf527 -#define STB0899_ECNT3M 0xf528 -#define STB0899_ECNT3L 0xf529 - -#define STB0899_DMONMSK1 0xf57b -#define STB0899_DMONMSK1_WAIT_1STEP (1 << 7) -#define STB0899_DMONMSK1_FREE_14 (1 << 6) -#define STB0899_DMONMSK1_AVRGVIT_CALC (1 << 5) -#define STB0899_DMONMSK1_FREE_12 (1 << 4) -#define STB0899_DMONMSK1_FREE_11 (1 << 3) -#define STB0899_DMONMSK1_B0DIV_CALC (1 << 2) -#define STB0899_DMONMSK1_KDIVB1_CALC (1 << 1) -#define STB0899_DMONMSK1_KDIVB2_CALC (1 << 0) - -#define STB0899_DMONMSK0 0xf57c -#define STB0899_DMONMSK0_SMOTTH_CALC (1 << 7) -#define STB0899_DMONMSK0_FREE_6 (1 << 6) -#define STB0899_DMONMSK0_SIGPOWER_CALC (1 << 5) -#define STB0899_DMONMSK0_QSEUIL_CALC (1 << 4) -#define STB0899_DMONMSK0_FREE_3 (1 << 3) -#define STB0899_DMONMSK0_FREE_2 (1 << 2) -#define STB0899_DMONMSK0_KVDIVB1_CALC (1 << 1) -#define STB0899_DMONMSK0_KVDIVB2_CALC (1 << 0) - -#define STB0899_TSULC 0xf549 -#define STB0899_ULNOSYNCBYTES (0x01 << 7) -#define STB0899_OFFST_ULNOSYNCBYTES 7 -#define STB0899_WIDTH_ULNOSYNCBYTES 1 -#define STB0899_ULPARITY_ON (0x01 << 6) -#define STB0899_OFFST_ULPARITY_ON 6 -#define STB0899_WIDTH_ULPARITY_ON 1 -#define STB0899_ULSYNCOUTRS (0x01 << 5) -#define STB0899_OFFST_ULSYNCOUTRS 5 -#define STB0899_WIDTH_ULSYNCOUTRS 1 -#define STB0899_ULDSS_PACKETS (0x01 << 0) -#define STB0899_OFFST_ULDSS_PACKETS 0 -#define STB0899_WIDTH_ULDSS_PACKETS 1 - -#define STB0899_TSLPL 0xf54b -#define STB0899_LLDVBS2_MODE (0x01 << 4) -#define STB0899_OFFST_LLDVBS2_MODE 4 -#define STB0899_WIDTH_LLDVBS2_MODE 1 -#define STB0899_LLISSYI_ON (0x01 << 3) -#define STB0899_OFFST_LLISSYI_ON 3 -#define STB0899_WIDTH_LLISSYI_ON 1 -#define STB0899_LLNPD_ON (0x01 << 2) -#define STB0899_OFFST_LLNPD_ON 2 -#define STB0899_WIDTH_LLNPD_ON 1 -#define STB0899_LLCRC8_ON (0x01 << 1) -#define STB0899_OFFST_LLCRC8_ON 1 -#define STB0899_WIDTH_LLCRC8_ON 1 - -#define STB0899_TSCFGH 0xf54c -#define STB0899_OUTRS_PS (0x01 << 6) -#define STB0899_OFFST_OUTRS_PS 6 -#define STB0899_WIDTH_OUTRS_PS 1 -#define STB0899_SYNCBYTE (0x01 << 5) -#define STB0899_OFFST_SYNCBYTE 5 -#define STB0899_WIDTH_SYNCBYTE 1 -#define STB0899_PFBIT (0x01 << 4) -#define STB0899_OFFST_PFBIT 4 -#define STB0899_WIDTH_PFBIT 1 -#define STB0899_ERR_BIT (0x01 << 3) -#define STB0899_OFFST_ERR_BIT 3 -#define STB0899_WIDTH_ERR_BIT 1 -#define STB0899_MPEG (0x01 << 2) -#define STB0899_OFFST_MPEG 2 -#define STB0899_WIDTH_MPEG 1 -#define STB0899_CLK_POL (0x01 << 1) -#define STB0899_OFFST_CLK_POL 1 -#define STB0899_WIDTH_CLK_POL 1 -#define STB0899_FORCE0 (0x01 << 0) -#define STB0899_OFFST_FORCE0 0 -#define STB0899_WIDTH_FORCE0 1 - -#define STB0899_TSCFGM 0xf54d -#define STB0899_LLPRIORITY (0x01 << 3) -#define STB0899_OFFST_LLPRIORIY 3 -#define STB0899_WIDTH_LLPRIORITY 1 -#define STB0899_EN188 (0x01 << 2) -#define STB0899_OFFST_EN188 2 -#define STB0899_WIDTH_EN188 1 - -#define STB0899_TSCFGL 0xf54e -#define STB0899_DEL_ERRPCK (0x01 << 7) -#define STB0899_OFFST_DEL_ERRPCK 7 -#define STB0899_WIDTH_DEL_ERRPCK 1 -#define STB0899_ERRFLAGSTD (0x01 << 5) -#define STB0899_OFFST_ERRFLAGSTD 5 -#define STB0899_WIDTH_ERRFLAGSTD 1 -#define STB0899_MPEGERR (0x01 << 4) -#define STB0899_OFFST_MPEGERR 4 -#define STB0899_WIDTH_MPEGERR 1 -#define STB0899_BCH_CHK (0x01 << 3) -#define STB0899_OFFST_BCH_CHK 5 -#define STB0899_WIDTH_BCH_CHK 1 -#define STB0899_CRC8CHK (0x01 << 2) -#define STB0899_OFFST_CRC8CHK 2 -#define STB0899_WIDTH_CRC8CHK 1 -#define STB0899_SPEC_INFO (0x01 << 1) -#define STB0899_OFFST_SPEC_INFO 1 -#define STB0899_WIDTH_SPEC_INFO 1 -#define STB0899_LOW_PRIO_CLK (0x01 << 0) -#define STB0899_OFFST_LOW_PRIO_CLK 0 -#define STB0899_WIDTH_LOW_PRIO_CLK 1 -#define STB0899_ERROR_NORM (0x00 << 0) -#define STB0899_OFFST_ERROR_NORM 0 -#define STB0899_WIDTH_ERROR_NORM 0 - -#define STB0899_TSOUT 0xf54f -#define STB0899_RSSYNCDEL 0xf550 -#define STB0899_TSINHDELH 0xf551 -#define STB0899_TSINHDELM 0xf552 -#define STB0899_TSINHDELL 0xf553 -#define STB0899_TSLLSTKM 0xf55a -#define STB0899_TSLLSTKL 0xf55b -#define STB0899_TSULSTKM 0xf55c -#define STB0899_TSULSTKL 0xf55d -#define STB0899_TSSTATUS 0xf561 - -#define STB0899_PDELCTRL 0xf600 -#define STB0899_INVERT_RES (0x01 << 7) -#define STB0899_OFFST_INVERT_RES 7 -#define STB0899_WIDTH_INVERT_RES 1 -#define STB0899_FORCE_ACCEPTED (0x01 << 6) -#define STB0899_OFFST_FORCE_ACCEPTED 6 -#define STB0899_WIDTH_FORCE_ACCEPTED 1 -#define STB0899_FILTER_EN (0x01 << 5) -#define STB0899_OFFST_FILTER_EN 5 -#define STB0899_WIDTH_FILTER_EN 1 -#define STB0899_LOCKFALL_THRESH (0x01 << 4) -#define STB0899_OFFST_LOCKFALL_THRESH 4 -#define STB0899_WIDTH_LOCKFALL_THRESH 1 -#define STB0899_HYST_EN (0x01 << 3) -#define STB0899_OFFST_HYST_EN 3 -#define STB0899_WIDTH_HYST_EN 1 -#define STB0899_HYST_SWRST (0x01 << 2) -#define STB0899_OFFST_HYST_SWRST 2 -#define STB0899_WIDTH_HYST_SWRST 1 -#define STB0899_ALGO_EN (0x01 << 1) -#define STB0899_OFFST_ALGO_EN 1 -#define STB0899_WIDTH_ALGO_EN 1 -#define STB0899_ALGO_SWRST (0x01 << 0) -#define STB0899_OFFST_ALGO_SWRST 0 -#define STB0899_WIDTH_ALGO_SWRST 1 - -#define STB0899_PDELCTRL2 0xf601 -#define STB0899_BBHCTRL1 0xf602 -#define STB0899_BBHCTRL2 0xf603 -#define STB0899_HYSTTHRESH 0xf604 - -#define STB0899_MATCSTM 0xf605 -#define STB0899_MATCSTL 0xf606 -#define STB0899_UPLCSTM 0xf607 -#define STB0899_UPLCSTL 0xf608 -#define STB0899_DFLCSTM 0xf609 -#define STB0899_DFLCSTL 0xf60a -#define STB0899_SYNCCST 0xf60b -#define STB0899_SYNCDCSTM 0xf60c -#define STB0899_SYNCDCSTL 0xf60d -#define STB0899_ISI_ENTRY 0xf60e -#define STB0899_ISI_BIT_EN 0xf60f -#define STB0899_MATSTRM 0xf610 -#define STB0899_MATSTRL 0xf611 -#define STB0899_UPLSTRM 0xf612 -#define STB0899_UPLSTRL 0xf613 -#define STB0899_DFLSTRM 0xf614 -#define STB0899_DFLSTRL 0xf615 -#define STB0899_SYNCSTR 0xf616 -#define STB0899_SYNCDSTRM 0xf617 -#define STB0899_SYNCDSTRL 0xf618 - -#define STB0899_CFGPDELSTATUS1 0xf619 -#define STB0899_BADDFL (0x01 << 6) -#define STB0899_OFFST_BADDFL 6 -#define STB0899_WIDTH_BADDFL 1 -#define STB0899_CONTINUOUS_STREAM (0x01 << 5) -#define STB0899_OFFST_CONTINUOUS_STREAM 5 -#define STB0899_WIDTH_CONTINUOUS_STREAM 1 -#define STB0899_ACCEPTED_STREAM (0x01 << 4) -#define STB0899_OFFST_ACCEPTED_STREAM 4 -#define STB0899_WIDTH_ACCEPTED_STREAM 1 -#define STB0899_BCH_ERRFLAG (0x01 << 3) -#define STB0899_OFFST_BCH_ERRFLAG 3 -#define STB0899_WIDTH_BCH_ERRFLAG 1 -#define STB0899_CRCRES (0x01 << 2) -#define STB0899_OFFST_CRCRES 2 -#define STB0899_WIDTH_CRCRES 1 -#define STB0899_CFGPDELSTATUS_LOCK (0x01 << 1) -#define STB0899_OFFST_CFGPDELSTATUS_LOCK 1 -#define STB0899_WIDTH_CFGPDELSTATUS_LOCK 1 -#define STB0899_1STLOCK (0x01 << 0) -#define STB0899_OFFST_1STLOCK 0 -#define STB0899_WIDTH_1STLOCK 1 - -#define STB0899_CFGPDELSTATUS2 0xf61a -#define STB0899_BBFERRORM 0xf61b -#define STB0899_BBFERRORL 0xf61c -#define STB0899_UPKTERRORM 0xf61d -#define STB0899_UPKTERRORL 0xf61e - -#define STB0899_TSTCK 0xff10 - -#define STB0899_TSTRES 0xff11 -#define STB0899_FRESLDPC (0x01 << 7) -#define STB0899_OFFST_FRESLDPC 7 -#define STB0899_WIDTH_FRESLDPC 1 -#define STB0899_FRESRS (0x01 << 6) -#define STB0899_OFFST_FRESRS 6 -#define STB0899_WIDTH_FRESRS 1 -#define STB0899_FRESVIT (0x01 << 5) -#define STB0899_OFFST_FRESVIT 5 -#define STB0899_WIDTH_FRESVIT 1 -#define STB0899_FRESMAS1_2 (0x01 << 4) -#define STB0899_OFFST_FRESMAS1_2 4 -#define STB0899_WIDTH_FRESMAS1_2 1 -#define STB0899_FRESACS (0x01 << 3) -#define STB0899_OFFST_FRESACS 3 -#define STB0899_WIDTH_FRESACS 1 -#define STB0899_FRESSYM (0x01 << 2) -#define STB0899_OFFST_FRESSYM 2 -#define STB0899_WIDTH_FRESSYM 1 -#define STB0899_FRESMAS (0x01 << 1) -#define STB0899_OFFST_FRESMAS 1 -#define STB0899_WIDTH_FRESMAS 1 -#define STB0899_FRESINT (0x01 << 0) -#define STB0899_OFFST_FRESINIT 0 -#define STB0899_WIDTH_FRESINIT 1 - -#define STB0899_TSTOUT 0xff12 -#define STB0899_EN_SIGNATURE (0x01 << 7) -#define STB0899_OFFST_EN_SIGNATURE 7 -#define STB0899_WIDTH_EN_SIGNATURE 1 -#define STB0899_BCLK_CLK (0x01 << 6) -#define STB0899_OFFST_BCLK_CLK 6 -#define STB0899_WIDTH_BCLK_CLK 1 -#define STB0899_SGNL_OUT (0x01 << 5) -#define STB0899_OFFST_SGNL_OUT 5 -#define STB0899_WIDTH_SGNL_OUT 1 -#define STB0899_TS (0x01 << 4) -#define STB0899_OFFST_TS 4 -#define STB0899_WIDTH_TS 1 -#define STB0899_CTEST (0x01 << 0) -#define STB0899_OFFST_CTEST 0 -#define STB0899_WIDTH_CTEST 1 - -#define STB0899_TSTIN 0xff13 -#define STB0899_TEST_IN (0x01 << 7) -#define STB0899_OFFST_TEST_IN 7 -#define STB0899_WIDTH_TEST_IN 1 -#define STB0899_EN_ADC (0x01 << 6) -#define STB0899_OFFST_EN_ADC 6 -#define STB0899_WIDTH_ENADC 1 -#define STB0899_SGN_ADC (0x01 << 5) -#define STB0899_OFFST_SGN_ADC 5 -#define STB0899_WIDTH_SGN_ADC 1 -#define STB0899_BCLK_IN (0x01 << 4) -#define STB0899_OFFST_BCLK_IN 4 -#define STB0899_WIDTH_BCLK_IN 1 -#define STB0899_JETONIN_MODE (0x01 << 3) -#define STB0899_OFFST_JETONIN_MODE 3 -#define STB0899_WIDTH_JETONIN_MODE 1 -#define STB0899_BCLK_VALUE (0x01 << 2) -#define STB0899_OFFST_BCLK_VALUE 2 -#define STB0899_WIDTH_BCLK_VALUE 1 -#define STB0899_SGNRST_T12 (0x01 << 1) -#define STB0899_OFFST_SGNRST_T12 1 -#define STB0899_WIDTH_SGNRST_T12 1 -#define STB0899_LOWSP_ENAX (0x01 << 0) -#define STB0899_OFFST_LOWSP_ENAX 0 -#define STB0899_WIDTH_LOWSP_ENAX 1 - -#define STB0899_TSTSYS 0xff14 -#define STB0899_TSTCHIP 0xff15 -#define STB0899_TSTFREE 0xff16 -#define STB0899_TSTI2C 0xff17 -#define STB0899_BITSPEEDM 0xff1c -#define STB0899_BITSPEEDL 0xff1d -#define STB0899_TBUSBIT 0xff1e -#define STB0899_TSTDIS 0xff24 -#define STB0899_TSTDISRX 0xff25 -#define STB0899_TSTJETON 0xff28 -#define STB0899_TSTDCADJ 0xff40 -#define STB0899_TSTAGC1 0xff41 -#define STB0899_TSTAGC1N 0xff42 -#define STB0899_TSTPOLYPH 0xff48 -#define STB0899_TSTR 0xff49 -#define STB0899_TSTAGC2 0xff4a -#define STB0899_TSTCTL1 0xff4b -#define STB0899_TSTCTL2 0xff4c -#define STB0899_TSTCTL3 0xff4d -#define STB0899_TSTDEMAP 0xff50 -#define STB0899_TSTDEMAP2 0xff51 -#define STB0899_TSTDEMMON 0xff52 -#define STB0899_TSTRATE 0xff53 -#define STB0899_TSTSELOUT 0xff54 -#define STB0899_TSYNC 0xff55 -#define STB0899_TSTERR 0xff56 -#define STB0899_TSTRAM1 0xff58 -#define STB0899_TSTVSELOUT 0xff59 -#define STB0899_TSTFORCEIN 0xff5a -#define STB0899_TSTRS1 0xff5c -#define STB0899_TSTRS2 0xff5d -#define STB0899_TSTRS3 0xff53 - -#define STB0899_INTBUFSTATUS 0xf200 -#define STB0899_INTBUFCTRL 0xf201 -#define STB0899_PCKLENUL 0xf55e -#define STB0899_PCKLENLL 0xf55f -#define STB0899_RSPCKLEN 0xf560 - -/* 2 registers */ -#define STB0899_SYNCDCST 0xf60c - -/* DiSEqC */ -#define STB0899_DISCNTRL1 0xf0a0 -#define STB0899_TIMOFF (0x01 << 7) -#define STB0899_OFFST_TIMOFF 7 -#define STB0899_WIDTH_TIMOFF 1 -#define STB0899_DISEQCRESET (0x01 << 6) -#define STB0899_OFFST_DISEQCRESET 6 -#define STB0899_WIDTH_DISEQCRESET 1 -#define STB0899_TIMCMD (0x03 << 4) -#define STB0899_OFFST_TIMCMD 4 -#define STB0899_WIDTH_TIMCMD 2 -#define STB0899_DISPRECHARGE (0x01 << 2) -#define STB0899_OFFST_DISPRECHARGE 2 -#define STB0899_WIDTH_DISPRECHARGE 1 -#define STB0899_DISEQCMODE (0x03 << 0) -#define STB0899_OFFST_DISEQCMODE 0 -#define STB0899_WIDTH_DISEQCMODE 2 - -#define STB0899_DISCNTRL2 0xf0a1 -#define STB0899_RECEIVER_ON (0x01 << 7) -#define STB0899_OFFST_RECEIVER_ON 7 -#define STB0899_WIDTH_RECEIVER_ON 1 -#define STB0899_IGNO_SHORT_22K (0x01 << 6) -#define STB0899_OFFST_IGNO_SHORT_22K 6 -#define STB0899_WIDTH_IGNO_SHORT_22K 1 -#define STB0899_ONECHIP_TRX (0x01 << 5) -#define STB0899_OFFST_ONECHIP_TRX 5 -#define STB0899_WIDTH_ONECHIP_TRX 1 -#define STB0899_EXT_ENVELOP (0x01 << 4) -#define STB0899_OFFST_EXT_ENVELOP 4 -#define STB0899_WIDTH_EXT_ENVELOP 1 -#define STB0899_PIN_SELECT (0x03 << 2) -#define STB0899_OFFST_PIN_SELCT 2 -#define STB0899_WIDTH_PIN_SELCT 2 -#define STB0899_IRQ_RXEND (0x01 << 1) -#define STB0899_OFFST_IRQ_RXEND 1 -#define STB0899_WIDTH_IRQ_RXEND 1 -#define STB0899_IRQ_4NBYTES (0x01 << 0) -#define STB0899_OFFST_IRQ_4NBYTES 0 -#define STB0899_WIDTH_IRQ_4NBYTES 1 - -#define STB0899_DISRX_ST0 0xf0a4 -#define STB0899_RXEND (0x01 << 7) -#define STB0899_OFFST_RXEND 7 -#define STB0899_WIDTH_RXEND 1 -#define STB0899_RXACTIVE (0x01 << 6) -#define STB0899_OFFST_RXACTIVE 6 -#define STB0899_WIDTH_RXACTIVE 1 -#define STB0899_SHORT22K (0x01 << 5) -#define STB0899_OFFST_SHORT22K 5 -#define STB0899_WIDTH_SHORT22K 1 -#define STB0899_CONTTONE (0x01 << 4) -#define STB0899_OFFST_CONTTONE 4 -#define STB0899_WIDTH_CONTONE 1 -#define STB0899_4BFIFOREDY (0x01 << 3) -#define STB0899_OFFST_4BFIFOREDY 3 -#define STB0899_WIDTH_4BFIFOREDY 1 -#define STB0899_FIFOEMPTY (0x01 << 2) -#define STB0899_OFFST_FIFOEMPTY 2 -#define STB0899_WIDTH_FIFOEMPTY 1 -#define STB0899_ABORTTRX (0x01 << 0) -#define STB0899_OFFST_ABORTTRX 0 -#define STB0899_WIDTH_ABORTTRX 1 - -#define STB0899_DISRX_ST1 0xf0a5 -#define STB0899_RXFAIL (0x01 << 7) -#define STB0899_OFFST_RXFAIL 7 -#define STB0899_WIDTH_RXFAIL 1 -#define STB0899_FIFOPFAIL (0x01 << 6) -#define STB0899_OFFST_FIFOPFAIL 6 -#define STB0899_WIDTH_FIFOPFAIL 1 -#define STB0899_RXNONBYTES (0x01 << 5) -#define STB0899_OFFST_RXNONBYTES 5 -#define STB0899_WIDTH_RXNONBYTES 1 -#define STB0899_FIFOOVF (0x01 << 4) -#define STB0899_OFFST_FIFOOVF 4 -#define STB0899_WIDTH_FIFOOVF 1 -#define STB0899_FIFOBYTENBR (0x0f << 0) -#define STB0899_OFFST_FIFOBYTENBR 0 -#define STB0899_WIDTH_FIFOBYTENBR 4 - -#define STB0899_DISPARITY 0xf0a6 - -#define STB0899_DISFIFO 0xf0a7 - -#define STB0899_DISSTATUS 0xf0a8 -#define STB0899_FIFOFULL (0x01 << 6) -#define STB0899_OFFST_FIFOFULL 6 -#define STB0899_WIDTH_FIFOFULL 1 -#define STB0899_TXIDLE (0x01 << 5) -#define STB0899_OFFST_TXIDLE 5 -#define STB0899_WIDTH_TXIDLE 1 -#define STB0899_GAPBURST (0x01 << 4) -#define STB0899_OFFST_GAPBURST 4 -#define STB0899_WIDTH_GAPBURST 1 -#define STB0899_TXFIFOBYTES (0x0f << 0) -#define STB0899_OFFST_TXFIFOBYTES 0 -#define STB0899_WIDTH_TXFIFOBYTES 4 -#define STB0899_DISF22 0xf0a9 - -#define STB0899_DISF22RX 0xf0aa - -/* General Purpose */ -#define STB0899_SYSREG 0xf101 -#define STB0899_ACRPRESC 0xf110 -#define STB0899_OFFST_RSVD2 7 -#define STB0899_WIDTH_RSVD2 1 -#define STB0899_OFFST_ACRPRESC 4 -#define STB0899_WIDTH_ACRPRESC 3 -#define STB0899_OFFST_RSVD1 3 -#define STB0899_WIDTH_RSVD1 1 -#define STB0899_OFFST_ACRPRESC2 0 -#define STB0899_WIDTH_ACRPRESC2 3 - -#define STB0899_ACRDIV1 0xf111 -#define STB0899_ACRDIV2 0xf112 -#define STB0899_DACR1 0xf113 -#define STB0899_DACR2 0xf114 -#define STB0899_OUTCFG 0xf11c -#define STB0899_MODECFG 0xf11d -#define STB0899_NCOARSE 0xf1b3 - -#define STB0899_SYNTCTRL 0xf1b6 -#define STB0899_STANDBY (0x01 << 7) -#define STB0899_OFFST_STANDBY 7 -#define STB0899_WIDTH_STANDBY 1 -#define STB0899_BYPASSPLL (0x01 << 6) -#define STB0899_OFFST_BYPASSPLL 6 -#define STB0899_WIDTH_BYPASSPLL 1 -#define STB0899_SEL1XRATIO (0x01 << 5) -#define STB0899_OFFST_SEL1XRATIO 5 -#define STB0899_WIDTH_SEL1XRATIO 1 -#define STB0899_SELOSCI (0x01 << 1) -#define STB0899_OFFST_SELOSCI 1 -#define STB0899_WIDTH_SELOSCI 1 - -#define STB0899_FILTCTRL 0xf1b7 -#define STB0899_SYSCTRL 0xf1b8 - -#define STB0899_STOPCLK1 0xf1c2 -#define STB0899_STOP_CKINTBUF108 (0x01 << 7) -#define STB0899_OFFST_STOP_CKINTBUF108 7 -#define STB0899_WIDTH_STOP_CKINTBUF108 1 -#define STB0899_STOP_CKINTBUF216 (0x01 << 6) -#define STB0899_OFFST_STOP_CKINTBUF216 6 -#define STB0899_WIDTH_STOP_CKINTBUF216 1 -#define STB0899_STOP_CHK8PSK (0x01 << 5) -#define STB0899_OFFST_STOP_CHK8PSK 5 -#define STB0899_WIDTH_STOP_CHK8PSK 1 -#define STB0899_STOP_CKFEC108 (0x01 << 4) -#define STB0899_OFFST_STOP_CKFEC108 4 -#define STB0899_WIDTH_STOP_CKFEC108 1 -#define STB0899_STOP_CKFEC216 (0x01 << 3) -#define STB0899_OFFST_STOP_CKFEC216 3 -#define STB0899_WIDTH_STOP_CKFEC216 1 -#define STB0899_STOP_CKCORE216 (0x01 << 2) -#define STB0899_OFFST_STOP_CKCORE216 2 -#define STB0899_WIDTH_STOP_CKCORE216 1 -#define STB0899_STOP_CKADCI108 (0x01 << 1) -#define STB0899_OFFST_STOP_CKADCI108 1 -#define STB0899_WIDTH_STOP_CKADCI108 1 -#define STB0899_STOP_INVCKADCI108 (0x01 << 0) -#define STB0899_OFFST_STOP_INVCKADCI108 0 -#define STB0899_WIDTH_STOP_INVCKADCI108 1 - -#define STB0899_STOPCLK2 0xf1c3 -#define STB0899_STOP_CKS2DMD108 (0x01 << 2) -#define STB0899_OFFST_STOP_CKS2DMD108 2 -#define STB0899_WIDTH_STOP_CKS2DMD108 1 -#define STB0899_STOP_CKPKDLIN108 (0x01 << 1) -#define STB0899_OFFST_STOP_CKPKDLIN108 1 -#define STB0899_WIDTH_STOP_CKPKDLIN108 1 -#define STB0899_STOP_CKPKDLIN216 (0x01 << 0) -#define STB0899_OFFST_STOP_CKPKDLIN216 0 -#define STB0899_WIDTH_STOP_CKPKDLIN216 1 - -#define STB0899_TSTTNR1 0xf1e0 -#define STB0899_BYPASS_ADC (0x01 << 7) -#define STB0899_OFFST_BYPASS_ADC 7 -#define STB0899_WIDTH_BYPASS_ADC 1 -#define STB0899_INVADCICKOUT (0x01 << 6) -#define STB0899_OFFST_INVADCICKOUT 6 -#define STB0899_WIDTH_INVADCICKOUT 1 -#define STB0899_ADCTEST_VOLTAGE (0x03 << 4) -#define STB0899_OFFST_ADCTEST_VOLTAGE 4 -#define STB0899_WIDTH_ADCTEST_VOLTAGE 1 -#define STB0899_ADC_RESET (0x01 << 3) -#define STB0899_OFFST_ADC_RESET 3 -#define STB0899_WIDTH_ADC_RESET 1 -#define STB0899_TSTTNR1_2 (0x01 << 2) -#define STB0899_OFFST_TSTTNR1_2 2 -#define STB0899_WIDTH_TSTTNR1_2 1 -#define STB0899_ADCPON (0x01 << 1) -#define STB0899_OFFST_ADCPON 1 -#define STB0899_WIDTH_ADCPON 1 -#define STB0899_ADCIN_MODE (0x01 << 0) -#define STB0899_OFFST_ADCIN_MODE 0 -#define STB0899_WIDTH_ADCIN_MODE 1 - -#define STB0899_TSTTNR2 0xf1e1 -#define STB0899_TSTTNR2_7 (0x01 << 7) -#define STB0899_OFFST_TSTTNR2_7 7 -#define STB0899_WIDTH_TSTTNR2_7 1 -#define STB0899_NOT_DISRX_WIRED (0x01 << 6) -#define STB0899_OFFST_NOT_DISRX_WIRED 6 -#define STB0899_WIDTH_NOT_DISRX_WIRED 1 -#define STB0899_DISEQC_DCURRENT (0x01 << 5) -#define STB0899_OFFST_DISEQC_DCURRENT 5 -#define STB0899_WIDTH_DISEQC_DCURRENT 1 -#define STB0899_DISEQC_ZCURRENT (0x01 << 4) -#define STB0899_OFFST_DISEQC_ZCURRENT 4 -#define STB0899_WIDTH_DISEQC_ZCURRENT 1 -#define STB0899_DISEQC_SINC_SOURCE (0x03 << 2) -#define STB0899_OFFST_DISEQC_SINC_SOURCE 2 -#define STB0899_WIDTH_DISEQC_SINC_SOURCE 2 -#define STB0899_SELIQSRC (0x03 << 0) -#define STB0899_OFFST_SELIQSRC 0 -#define STB0899_WIDTH_SELIQSRC 2 - -#define STB0899_TSTTNR3 0xf1e2 - -#define STB0899_I2CCFG 0xf129 -#define STB0899_I2CCFGRSVD (0x0f << 4) -#define STB0899_OFFST_I2CCFGRSVD 4 -#define STB0899_WIDTH_I2CCFGRSVD 4 -#define STB0899_I2CFASTMODE (0x01 << 3) -#define STB0899_OFFST_I2CFASTMODE 3 -#define STB0899_WIDTH_I2CFASTMODE 1 -#define STB0899_STATUSWR (0x01 << 2) -#define STB0899_OFFST_STATUSWR 2 -#define STB0899_WIDTH_STATUSWR 1 -#define STB0899_I2CADDRINC (0x03 << 0) -#define STB0899_OFFST_I2CADDRINC 0 -#define STB0899_WIDTH_I2CADDRINC 2 - -#define STB0899_I2CRPT 0xf12a -#define STB0899_I2CTON (0x01 << 7) -#define STB0899_OFFST_I2CTON 7 -#define STB0899_WIDTH_I2CTON 1 -#define STB0899_ENARPTLEVEL (0x01 << 6) -#define STB0899_OFFST_ENARPTLEVEL 6 -#define STB0899_WIDTH_ENARPTLEVEL 2 -#define STB0899_SCLTDELAY (0x01 << 3) -#define STB0899_OFFST_SCLTDELAY 3 -#define STB0899_WIDTH_SCLTDELAY 1 -#define STB0899_STOPENA (0x01 << 2) -#define STB0899_OFFST_STOPENA 2 -#define STB0899_WIDTH_STOPENA 1 -#define STB0899_STOPSDAT2SDA (0x01 << 1) -#define STB0899_OFFST_STOPSDAT2SDA 1 -#define STB0899_WIDTH_STOPSDAT2SDA 1 - -#define STB0899_IOPVALUE8 0xf136 -#define STB0899_IOPVALUE7 0xf137 -#define STB0899_IOPVALUE6 0xf138 -#define STB0899_IOPVALUE5 0xf139 -#define STB0899_IOPVALUE4 0xf13a -#define STB0899_IOPVALUE3 0xf13b -#define STB0899_IOPVALUE2 0xf13c -#define STB0899_IOPVALUE1 0xf13d -#define STB0899_IOPVALUE0 0xf13e - -#define STB0899_GPIO00CFG 0xf140 - -#define STB0899_GPIO01CFG 0xf141 -#define STB0899_GPIO02CFG 0xf142 -#define STB0899_GPIO03CFG 0xf143 -#define STB0899_GPIO04CFG 0xf144 -#define STB0899_GPIO05CFG 0xf145 -#define STB0899_GPIO06CFG 0xf146 -#define STB0899_GPIO07CFG 0xf147 -#define STB0899_GPIO08CFG 0xf148 -#define STB0899_GPIO09CFG 0xf149 -#define STB0899_GPIO10CFG 0xf14a -#define STB0899_GPIO11CFG 0xf14b -#define STB0899_GPIO12CFG 0xf14c -#define STB0899_GPIO13CFG 0xf14d -#define STB0899_GPIO14CFG 0xf14e -#define STB0899_GPIO15CFG 0xf14f -#define STB0899_GPIO16CFG 0xf150 -#define STB0899_GPIO17CFG 0xf151 -#define STB0899_GPIO18CFG 0xf152 -#define STB0899_GPIO19CFG 0xf153 -#define STB0899_GPIO20CFG 0xf154 - -#define STB0899_SDATCFG 0xf155 -#define STB0899_SCLTCFG 0xf156 -#define STB0899_AGCRFCFG 0xf157 -#define STB0899_GPIO22 0xf158 /* AGCBB2CFG */ -#define STB0899_GPIO21 0xf159 /* AGCBB1CFG */ -#define STB0899_DIRCLKCFG 0xf15a -#define STB0899_CLKOUT27CFG 0xf15b -#define STB0899_STDBYCFG 0xf15c -#define STB0899_CS0CFG 0xf15d -#define STB0899_CS1CFG 0xf15e -#define STB0899_DISEQCOCFG 0xf15f - -#define STB0899_GPIO32CFG 0xf160 -#define STB0899_GPIO33CFG 0xf161 -#define STB0899_GPIO34CFG 0xf162 -#define STB0899_GPIO35CFG 0xf163 -#define STB0899_GPIO36CFG 0xf164 -#define STB0899_GPIO37CFG 0xf165 -#define STB0899_GPIO38CFG 0xf166 -#define STB0899_GPIO39CFG 0xf167 - -#define STB0899_IRQSTATUS_3 0xf120 -#define STB0899_IRQSTATUS_2 0xf121 -#define STB0899_IRQSTATUS_1 0xf122 -#define STB0899_IRQSTATUS_0 0xf123 - -#define STB0899_IRQMSK_3 0xf124 -#define STB0899_IRQMSK_2 0xf125 -#define STB0899_IRQMSK_1 0xf126 -#define STB0899_IRQMSK_0 0xf127 - -#define STB0899_IRQCFG 0xf128 - -#define STB0899_GHOSTREG 0xf000 - -#define STB0899_S2DEMOD 0xf3fc -#define STB0899_S2FEC 0xfafc - - -#endif diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c deleted file mode 100644 index 0e2cb0df144..00000000000 --- a/drivers/media/dvb/frontends/stb6000.c +++ /dev/null @@ -1,255 +0,0 @@ - /* - Driver for ST STB6000 DVBS Silicon tuner - - Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#include <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "stb6000.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "stb6000: " args); \ - } while (0) - -struct stb6000_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u32 frequency; -}; - -static int stb6000_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int stb6000_sleep(struct dvb_frontend *fe) -{ - struct stb6000_priv *priv = fe->tuner_priv; - int ret; - u8 buf[] = { 10, 0 }; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int stb6000_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct stb6000_priv *priv = fe->tuner_priv; - unsigned int n, m; - int ret; - u32 freq_mhz; - int bandwidth; - u8 buf[12]; - struct i2c_msg msg = { - .addr = priv->i2c_address, - .flags = 0, - .buf = buf, - .len = 12 - }; - - dprintk("%s:\n", __func__); - - freq_mhz = params->frequency / 1000; - bandwidth = params->u.qpsk.symbol_rate / 1000000; - - if (bandwidth > 31) - bandwidth = 31; - - if ((freq_mhz > 949) && (freq_mhz < 2151)) { - buf[0] = 0x01; - buf[1] = 0xac; - if (freq_mhz < 1950) - buf[1] = 0xaa; - if (freq_mhz < 1800) - buf[1] = 0xa8; - if (freq_mhz < 1650) - buf[1] = 0xa6; - if (freq_mhz < 1530) - buf[1] = 0xa5; - if (freq_mhz < 1470) - buf[1] = 0xa4; - if (freq_mhz < 1370) - buf[1] = 0xa2; - if (freq_mhz < 1300) - buf[1] = 0xa1; - if (freq_mhz < 1200) - buf[1] = 0xa0; - if (freq_mhz < 1075) - buf[1] = 0xbc; - if (freq_mhz < 1000) - buf[1] = 0xba; - if (freq_mhz < 1075) { - n = freq_mhz / 8; /* vco=lo*4 */ - m = 2; - } else { - n = freq_mhz / 16; /* vco=lo*2 */ - m = 1; - } - buf[2] = n >> 1; - buf[3] = (unsigned char)(((n & 1) << 7) | - (m * freq_mhz - n * 16) | 0x60); - buf[4] = 0x04; - buf[5] = 0x0e; - - buf[6] = (unsigned char)(bandwidth); - - buf[7] = 0xd8; - buf[8] = 0xd0; - buf[9] = 0x50; - buf[10] = 0xeb; - buf[11] = 0x4f; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - udelay(10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - buf[0] = 0x07; - buf[1] = 0xdf; - buf[2] = 0xd0; - buf[3] = 0x50; - buf[4] = 0xfb; - msg.len = 5; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - ret = i2c_transfer(priv->i2c, &msg, 1); - if (ret != 1) - dprintk("%s: i2c error\n", __func__); - - udelay(10); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - priv->frequency = freq_mhz * 1000; - - return (ret == 1) ? 0 : ret; - } - return -1; -} - -static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct stb6000_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops stb6000_tuner_ops = { - .info = { - .name = "ST STB6000", - .frequency_min = 950000, - .frequency_max = 2150000 - }, - .release = stb6000_release, - .sleep = stb6000_sleep, - .set_params = stb6000_set_params, - .get_frequency = stb6000_get_frequency, -}; - -struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c) -{ - struct stb6000_priv *priv = NULL; - u8 b0[] = { 0 }; - u8 b1[] = { 0, 0 }; - struct i2c_msg msg[2] = { - { - .addr = addr, - .flags = 0, - .buf = b0, - .len = 0 - }, { - .addr = addr, - .flags = I2C_M_RD, - .buf = b1, - .len = 2 - } - }; - int ret; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - /* is some i2c device here ? */ - ret = i2c_transfer(i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - - priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - - memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops, - sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - - return fe; -} -EXPORT_SYMBOL(stb6000_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("DVB STB6000 driver"); -MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb/frontends/stb6000.h deleted file mode 100644 index 7be479c22d5..00000000000 --- a/drivers/media/dvb/frontends/stb6000.h +++ /dev/null @@ -1,51 +0,0 @@ - /* - Driver for ST stb6000 DVBS Silicon tuner - - Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#ifndef __DVB_STB6000_H__ -#define __DVB_STB6000_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -/** - * Attach a stb6000 tuner to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param addr i2c address of the tuner. - * @param i2c i2c adapter to use. - * @return FE pointer on success, NULL on failure. - */ -#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \ - && defined(MODULE)) -extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, - int addr, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_STB6000 */ - -#endif /* __DVB_STB6000_H__ */ diff --git a/drivers/media/dvb/frontends/stb6100.c b/drivers/media/dvb/frontends/stb6100.c deleted file mode 100644 index ff39275ab49..00000000000 --- a/drivers/media/dvb/frontends/stb6100.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - STB6100 Silicon Tuner - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> - -#include "dvb_frontend.h" -#include "stb6100.h" - -static unsigned int verbose; -module_param(verbose, int, 0644); - - -#define FE_ERROR 0 -#define FE_NOTICE 1 -#define FE_INFO 2 -#define FE_DEBUG 3 - -#define dprintk(x, y, z, format, arg...) do { \ - if (z) { \ - if ((x > FE_ERROR) && (x > y)) \ - printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \ - else if ((x > FE_NOTICE) && (x > y)) \ - printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \ - else if ((x > FE_INFO) && (x > y)) \ - printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \ - else if ((x > FE_DEBUG) && (x > y)) \ - printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \ - } else { \ - if (x > y) \ - printk(format, ##arg); \ - } \ -} while(0) - -struct stb6100_lkup { - u32 val_low; - u32 val_high; - u8 reg; -}; - -static int stb6100_release(struct dvb_frontend *fe); - -static const struct stb6100_lkup lkup[] = { - { 0, 950000, 0x0a }, - { 950000, 1000000, 0x0a }, - { 1000000, 1075000, 0x0c }, - { 1075000, 1200000, 0x00 }, - { 1200000, 1300000, 0x01 }, - { 1300000, 1370000, 0x02 }, - { 1370000, 1470000, 0x04 }, - { 1470000, 1530000, 0x05 }, - { 1530000, 1650000, 0x06 }, - { 1650000, 1800000, 0x08 }, - { 1800000, 1950000, 0x0a }, - { 1950000, 2150000, 0x0c }, - { 2150000, 9999999, 0x0c }, - { 0, 0, 0x00 } -}; - -/* Register names for easy debugging. */ -static const char *stb6100_regnames[] = { - [STB6100_LD] = "LD", - [STB6100_VCO] = "VCO", - [STB6100_NI] = "NI", - [STB6100_NF_LSB] = "NF", - [STB6100_K] = "K", - [STB6100_G] = "G", - [STB6100_F] = "F", - [STB6100_DLB] = "DLB", - [STB6100_TEST1] = "TEST1", - [STB6100_FCCK] = "FCCK", - [STB6100_LPEN] = "LPEN", - [STB6100_TEST3] = "TEST3", -}; - -/* Template for normalisation, i.e. setting unused or undocumented - * bits as required according to the documentation. - */ -struct stb6100_regmask { - u8 mask; - u8 set; -}; - -static const struct stb6100_regmask stb6100_template[] = { - [STB6100_LD] = { 0xff, 0x00 }, - [STB6100_VCO] = { 0xff, 0x00 }, - [STB6100_NI] = { 0xff, 0x00 }, - [STB6100_NF_LSB] = { 0xff, 0x00 }, - [STB6100_K] = { 0xc7, 0x38 }, - [STB6100_G] = { 0xef, 0x10 }, - [STB6100_F] = { 0x1f, 0xc0 }, - [STB6100_DLB] = { 0x38, 0xc4 }, - [STB6100_TEST1] = { 0x00, 0x8f }, - [STB6100_FCCK] = { 0x40, 0x0d }, - [STB6100_LPEN] = { 0xf0, 0x0b }, - [STB6100_TEST3] = { 0x00, 0xde }, -}; - -static void stb6100_normalise_regs(u8 regs[]) -{ - int i; - - for (i = 0; i < STB6100_NUMREGS; i++) - regs[i] = (regs[i] & stb6100_template[i].mask) | stb6100_template[i].set; -} - -static int stb6100_read_regs(struct stb6100_state *state, u8 regs[]) -{ - int rc; - struct i2c_msg msg = { - .addr = state->config->tuner_address, - .flags = I2C_M_RD, - .buf = regs, - .len = STB6100_NUMREGS - }; - - rc = i2c_transfer(state->i2c, &msg, 1); - if (unlikely(rc != 1)) { - dprintk(verbose, FE_ERROR, 1, "Read (0x%x) err, rc=[%d]", - state->config->tuner_address, rc); - - return -EREMOTEIO; - } - if (unlikely(verbose > FE_DEBUG)) { - int i; - - dprintk(verbose, FE_DEBUG, 1, " Read from 0x%02x", state->config->tuner_address); - for (i = 0; i < STB6100_NUMREGS; i++) - dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[i], regs[i]); - } - return 0; -} - -static int stb6100_read_reg(struct stb6100_state *state, u8 reg) -{ - u8 regs[STB6100_NUMREGS]; - int rc; - - if (unlikely(reg >= STB6100_NUMREGS)) { - dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); - return -EINVAL; - } - if ((rc = stb6100_read_regs(state, regs)) < 0) - return rc; - return (unsigned int)regs[reg]; -} - -static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int start, int len) -{ - int rc; - u8 cmdbuf[len + 1]; - struct i2c_msg msg = { - .addr = state->config->tuner_address, - .flags = 0, - .buf = cmdbuf, - .len = len + 1 - }; - - if (unlikely(start < 1 || start + len > STB6100_NUMREGS)) { - dprintk(verbose, FE_ERROR, 1, "Invalid register range %d:%d", - start, len); - return -EINVAL; - } - memcpy(&cmdbuf[1], buf, len); - cmdbuf[0] = start; - - if (unlikely(verbose > FE_DEBUG)) { - int i; - - dprintk(verbose, FE_DEBUG, 1, " Write @ 0x%02x: [%d:%d]", state->config->tuner_address, start, len); - for (i = 0; i < len; i++) - dprintk(verbose, FE_DEBUG, 1, " %s: 0x%02x", stb6100_regnames[start + i], buf[i]); - } - rc = i2c_transfer(state->i2c, &msg, 1); - if (unlikely(rc != 1)) { - dprintk(verbose, FE_ERROR, 1, "(0x%x) write err [%d:%d], rc=[%d]", - (unsigned int)state->config->tuner_address, start, len, rc); - return -EREMOTEIO; - } - return 0; -} - -static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data) -{ - if (unlikely(reg >= STB6100_NUMREGS)) { - dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg); - return -EREMOTEIO; - } - data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set; - return stb6100_write_reg_range(state, &data, reg, 1); -} - -static int stb6100_write_regs(struct stb6100_state *state, u8 regs[]) -{ - stb6100_normalise_regs(regs); - return stb6100_write_reg_range(state, ®s[1], 1, STB6100_NUMREGS - 1); -} - -static int stb6100_get_status(struct dvb_frontend *fe, u32 *status) -{ - int rc; - struct stb6100_state *state = fe->tuner_priv; - - if ((rc = stb6100_read_reg(state, STB6100_LD)) < 0) - return rc; - - return (rc & STB6100_LD_LOCK) ? TUNER_STATUS_LOCKED : 0; -} - -static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - int rc; - u8 f; - struct stb6100_state *state = fe->tuner_priv; - - if ((rc = stb6100_read_reg(state, STB6100_F)) < 0) - return rc; - f = rc & STB6100_F_F; - - state->status.bandwidth = (f + 5) * 2000; /* x2 for ZIF */ - - *bandwidth = state->bandwidth = state->status.bandwidth * 1000; - dprintk(verbose, FE_DEBUG, 1, "bandwidth = %u Hz", state->bandwidth); - return 0; -} - -static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) -{ - u32 tmp; - int rc; - struct stb6100_state *state = fe->tuner_priv; - - dprintk(verbose, FE_DEBUG, 1, "set bandwidth to %u Hz", bandwidth); - - bandwidth /= 2; /* ZIF */ - - if (bandwidth >= 36000000) /* F[4:0] BW/2 max =31+5=36 mhz for F=31 */ - tmp = 31; - else if (bandwidth <= 5000000) /* bw/2 min = 5Mhz for F=0 */ - tmp = 0; - else /* if 5 < bw/2 < 36 */ - tmp = (bandwidth + 500000) / 1000000 - 5; - - /* Turn on LPF bandwidth setting clock control, - * set bandwidth, wait 10ms, turn off. - */ - if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d | STB6100_FCCK_FCCK)) < 0) - return rc; - if ((rc = stb6100_write_reg(state, STB6100_F, 0xc0 | tmp)) < 0) - return rc; - msleep(1); - if ((rc = stb6100_write_reg(state, STB6100_FCCK, 0x0d)) < 0) - return rc; - - return 0; -} - -static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - int rc; - u32 nint, nfrac, fvco; - int psd2, odiv; - struct stb6100_state *state = fe->tuner_priv; - u8 regs[STB6100_NUMREGS]; - - if ((rc = stb6100_read_regs(state, regs)) < 0) - return rc; - - odiv = (regs[STB6100_VCO] & STB6100_VCO_ODIV) >> STB6100_VCO_ODIV_SHIFT; - psd2 = (regs[STB6100_K] & STB6100_K_PSD2) >> STB6100_K_PSD2_SHIFT; - nint = regs[STB6100_NI]; - nfrac = ((regs[STB6100_K] & STB6100_K_NF_MSB) << 8) | regs[STB6100_NF_LSB]; - fvco = (nfrac * state->reference >> (9 - psd2)) + (nint * state->reference << psd2); - *frequency = state->frequency = fvco >> (odiv + 1); - - dprintk(verbose, FE_DEBUG, 1, - "frequency = %u kHz, odiv = %u, psd2 = %u, fxtal = %u kHz, fvco = %u kHz, N(I) = %u, N(F) = %u", - state->frequency, odiv, psd2, state->reference, fvco, nint, nfrac); - return 0; -} - - -static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - int rc; - const struct stb6100_lkup *ptr; - struct stb6100_state *state = fe->tuner_priv; - struct dvb_frontend_parameters p; - - u32 srate = 0, fvco, nint, nfrac; - u8 regs[STB6100_NUMREGS]; - u8 g, psd2, odiv; - - if ((rc = stb6100_read_regs(state, regs)) < 0) - return rc; - - if (fe->ops.get_frontend) { - dprintk(verbose, FE_DEBUG, 1, "Get frontend parameters"); - fe->ops.get_frontend(fe, &p); - } - srate = p.u.qpsk.symbol_rate; - - regs[STB6100_DLB] = 0xdc; - /* Disable LPEN */ - regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL Loop disabled */ - - if ((rc = stb6100_write_regs(state, regs)) < 0) - return rc; - - /* Baseband gain. */ - if (srate >= 15000000) - g = 9; // +4 dB - else if (srate >= 5000000) - g = 11; // +8 dB - else - g = 14; // +14 dB - - regs[STB6100_G] = (regs[STB6100_G] & ~STB6100_G_G) | g; - regs[STB6100_G] &= ~STB6100_G_GCT; /* mask GCT */ - regs[STB6100_G] |= (1 << 5); /* 2Vp-p Mode */ - - /* VCO divide ratio (LO divide ratio, VCO prescaler enable). */ - if (frequency <= 1075000) - odiv = 1; - else - odiv = 0; - regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_ODIV) | (odiv << STB6100_VCO_ODIV_SHIFT); - - if ((frequency > 1075000) && (frequency <= 1325000)) - psd2 = 0; - else - psd2 = 1; - regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_PSD2) | (psd2 << STB6100_K_PSD2_SHIFT); - - /* OSM */ - for (ptr = lkup; - (ptr->val_high != 0) && !CHKRANGE(frequency, ptr->val_low, ptr->val_high); - ptr++); - if (ptr->val_high == 0) { - printk(KERN_ERR "%s: frequency out of range: %u kHz\n", __func__, frequency); - return -EINVAL; - } - regs[STB6100_VCO] = (regs[STB6100_VCO] & ~STB6100_VCO_OSM) | ptr->reg; - - /* F(VCO) = F(LO) * (ODIV == 0 ? 2 : 4) */ - fvco = frequency << (1 + odiv); - /* N(I) = floor(f(VCO) / (f(XTAL) * (PSD2 ? 2 : 1))) */ - nint = fvco / (state->reference << psd2); - /* N(F) = round(f(VCO) / f(XTAL) * (PSD2 ? 2 : 1) - N(I)) * 2 ^ 9 */ - nfrac = (((fvco - (nint * state->reference << psd2)) << (9 - psd2)) + state->reference / 2) / state->reference; - dprintk(verbose, FE_DEBUG, 1, - "frequency = %u, srate = %u, g = %u, odiv = %u, psd2 = %u, fxtal = %u, osm = %u, fvco = %u, N(I) = %u, N(F) = %u", - frequency, srate, (unsigned int)g, (unsigned int)odiv, - (unsigned int)psd2, state->reference, - ptr->reg, fvco, nint, nfrac); - regs[STB6100_NI] = nint; - regs[STB6100_NF_LSB] = nfrac; - regs[STB6100_K] = (regs[STB6100_K] & ~STB6100_K_NF_MSB) | ((nfrac >> 8) & STB6100_K_NF_MSB); - regs[STB6100_VCO] |= STB6100_VCO_OSCH; /* VCO search enabled */ - regs[STB6100_VCO] |= STB6100_VCO_OCK; /* VCO search clock off */ - regs[STB6100_FCCK] |= STB6100_FCCK_FCCK; /* LPF BW setting clock enabled */ - regs[STB6100_LPEN] &= ~STB6100_LPEN_LPEN; /* PLL loop disabled */ - /* Power up. */ - regs[STB6100_LPEN] |= STB6100_LPEN_SYNP | STB6100_LPEN_OSCP | STB6100_LPEN_BEN; - - msleep(2); - if ((rc = stb6100_write_regs(state, regs)) < 0) - return rc; - - msleep(2); - regs[STB6100_LPEN] |= STB6100_LPEN_LPEN; /* PLL loop enabled */ - if ((rc = stb6100_write_reg(state, STB6100_LPEN, regs[STB6100_LPEN])) < 0) - return rc; - - regs[STB6100_VCO] &= ~STB6100_VCO_OCK; /* VCO fast search */ - if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0) - return rc; - - msleep(10); /* wait for LO to lock */ - regs[STB6100_VCO] &= ~STB6100_VCO_OSCH; /* vco search disabled */ - regs[STB6100_VCO] |= STB6100_VCO_OCK; /* search clock off */ - if ((rc = stb6100_write_reg(state, STB6100_VCO, regs[STB6100_VCO])) < 0) - return rc; - regs[STB6100_FCCK] &= ~STB6100_FCCK_FCCK; /* LPF BW clock disabled */ - stb6100_normalise_regs(regs); - if ((rc = stb6100_write_reg_range(state, ®s[1], 1, STB6100_NUMREGS - 3)) < 0) - return rc; - - msleep(100); - - return 0; -} - -static int stb6100_sleep(struct dvb_frontend *fe) -{ - /* TODO: power down */ - return 0; -} - -static int stb6100_init(struct dvb_frontend *fe) -{ - struct stb6100_state *state = fe->tuner_priv; - struct tuner_state *status = &state->status; - - status->tunerstep = 125000; - status->ifreq = 0; - status->refclock = 27000000; /* Hz */ - status->iqsense = 1; - status->bandwidth = 36000; /* kHz */ - state->bandwidth = status->bandwidth * 1000; /* MHz */ - state->reference = status->refclock / 1000; /* kHz */ - - /* Set default bandwidth. */ - return stb6100_set_bandwidth(fe, status->bandwidth); -} - -static int stb6100_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) -{ - switch (param) { - case DVBFE_TUNER_FREQUENCY: - stb6100_get_frequency(fe, &state->frequency); - break; - case DVBFE_TUNER_TUNERSTEP: - break; - case DVBFE_TUNER_IFFREQ: - break; - case DVBFE_TUNER_BANDWIDTH: - stb6100_get_bandwidth(fe, &state->bandwidth); - break; - case DVBFE_TUNER_REFCLOCK: - break; - default: - break; - } - - return 0; -} - -static int stb6100_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *state) -{ - struct stb6100_state *tstate = fe->tuner_priv; - - switch (param) { - case DVBFE_TUNER_FREQUENCY: - stb6100_set_frequency(fe, state->frequency); - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_TUNERSTEP: - break; - case DVBFE_TUNER_IFFREQ: - break; - case DVBFE_TUNER_BANDWIDTH: - stb6100_set_bandwidth(fe, state->bandwidth); - tstate->bandwidth = state->bandwidth; - break; - case DVBFE_TUNER_REFCLOCK: - break; - default: - break; - } - - return 0; -} - -static struct dvb_tuner_ops stb6100_ops = { - .info = { - .name = "STB6100 Silicon Tuner", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0, - }, - - .init = stb6100_init, - .sleep = stb6100_sleep, - .get_status = stb6100_get_status, - .get_state = stb6100_get_state, - .set_state = stb6100_set_state, - .release = stb6100_release -}; - -struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, - struct i2c_adapter *i2c) -{ - struct stb6100_state *state = NULL; - - state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL); - if (state == NULL) - goto error; - - state->config = config; - state->i2c = i2c; - state->frontend = fe; - state->reference = config->refclock / 1000; /* kHz */ - fe->tuner_priv = state; - fe->ops.tuner_ops = stb6100_ops; - - printk("%s: Attaching STB6100 \n", __func__); - return fe; - -error: - kfree(state); - return NULL; -} - -static int stb6100_release(struct dvb_frontend *fe) -{ - struct stb6100_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - - return 0; -} - -EXPORT_SYMBOL(stb6100_attach); -MODULE_PARM_DESC(verbose, "Set Verbosity level"); - -MODULE_AUTHOR("Manu Abraham"); -MODULE_DESCRIPTION("STB6100 Silicon tuner"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/stb6100.h b/drivers/media/dvb/frontends/stb6100.h deleted file mode 100644 index 395d056599a..00000000000 --- a/drivers/media/dvb/frontends/stb6100.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - STB6100 Silicon Tuner - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __STB_6100_REG_H -#define __STB_6100_REG_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -#define STB6100_LD 0x00 -#define STB6100_LD_LOCK (1 << 0) - -#define STB6100_VCO 0x01 -#define STB6100_VCO_OSCH (0x01 << 7) -#define STB6100_VCO_OSCH_SHIFT 7 -#define STB6100_VCO_OCK (0x03 << 5) -#define STB6100_VCO_OCK_SHIFT 5 -#define STB6100_VCO_ODIV (0x01 << 4) -#define STB6100_VCO_ODIV_SHIFT 4 -#define STB6100_VCO_OSM (0x0f << 0) - -#define STB6100_NI 0x02 -#define STB6100_NF_LSB 0x03 - -#define STB6100_K 0x04 -#define STB6100_K_PSD2 (0x01 << 2) -#define STB6100_K_PSD2_SHIFT 2 -#define STB6100_K_NF_MSB (0x03 << 0) - -#define STB6100_G 0x05 -#define STB6100_G_G (0x0f << 0) -#define STB6100_G_GCT (0x07 << 5) - -#define STB6100_F 0x06 -#define STB6100_F_F (0x1f << 0) - -#define STB6100_DLB 0x07 - -#define STB6100_TEST1 0x08 - -#define STB6100_FCCK 0x09 -#define STB6100_FCCK_FCCK (0x01 << 6) - -#define STB6100_LPEN 0x0a -#define STB6100_LPEN_LPEN (0x01 << 4) -#define STB6100_LPEN_SYNP (0x01 << 5) -#define STB6100_LPEN_OSCP (0x01 << 6) -#define STB6100_LPEN_BEN (0x01 << 7) - -#define STB6100_TEST3 0x0b - -#define STB6100_NUMREGS 0x0c - - -#define INRANGE(val, x, y) (((x <= val) && (val <= y)) || \ - ((y <= val) && (val <= x)) ? 1 : 0) - -#define CHKRANGE(val, x, y) (((val >= x) && (val < y)) ? 1 : 0) - -struct stb6100_config { - u8 tuner_address; - u32 refclock; -}; - -struct stb6100_state { - struct i2c_adapter *i2c; - - const struct stb6100_config *config; - struct dvb_tuner_ops ops; - struct dvb_frontend *frontend; - struct tuner_state status; - - u32 frequency; - u32 srate; - u32 bandwidth; - u32 reference; -}; - -#if defined(CONFIG_DVB_STB6100) || (defined(CONFIG_DVB_STB6100_MODULE) && defined(MODULE)) - -extern struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, - struct i2c_adapter *i2c); - -#else - -static inline struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, - struct stb6100_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); - return NULL; -} - -#endif //CONFIG_DVB_STB6100 - -#endif diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h deleted file mode 100644 index d3133405dc0..00000000000 --- a/drivers/media/dvb/frontends/stb6100_cfg.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - STB6100 Silicon Tuner - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - Copyright (C) ST Microelectronics - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *frequency = t_state.frequency; - printk("%s: Frequency=%d\n", __func__, t_state.frequency); - } - return 0; -} - -static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - t_state.frequency = frequency; - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - } - printk("%s: Frequency=%d\n", __func__, t_state.frequency); - return 0; -} - -static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *bandwidth = t_state.bandwidth; - } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); - return 0; -} - -static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - t_state.bandwidth = bandwidth; - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); - return 0; -} diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c deleted file mode 100644 index ff1194de34c..00000000000 --- a/drivers/media/dvb/frontends/stv0288.c +++ /dev/null @@ -1,618 +0,0 @@ -/* - Driver for ST STV0288 demodulator - Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de - for Reel Multimedia - Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com> - Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> - Removed stb6000 specific tuner code and revised some - procedures. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "stv0288.h" - -struct stv0288_state { - struct i2c_adapter *i2c; - const struct stv0288_config *config; - struct dvb_frontend frontend; - - u8 initialised:1; - u32 tuner_frequency; - u32 symbol_rate; - fe_code_rate_t fec_inner; - int errmode; -}; - -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -static int debug_legacy_dish_switch; -#define dprintk(args...) \ - do { \ - if (debug) \ - printk(KERN_DEBUG "stv0288: " args); \ - } while (0) - - -static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, - .buf = buf, - .len = 2 - }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return stv0288_writeregI(state, buf[0], buf[1]); -} - -static u8 stv0288_readreg(struct stv0288_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { - .addr = state->config->demod_address, - .flags = 0, - .buf = b0, - .len = 1 - }, { - .addr = state->config->demod_address, - .flags = I2C_M_RD, - .buf = b1, - .len = 1 - } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate) -{ - struct stv0288_state *state = fe->demodulator_priv; - unsigned int temp; - unsigned char b[3]; - - if ((srate < 1000000) || (srate > 45000000)) - return -EINVAL; - - temp = (unsigned int)srate / 1000; - - temp = temp * 32768; - temp = temp / 25; - temp = temp / 125; - b[0] = (unsigned char)((temp >> 12) & 0xff); - b[1] = (unsigned char)((temp >> 4) & 0xff); - b[2] = (unsigned char)((temp << 4) & 0xf0); - stv0288_writeregI(state, 0x28, 0x80); /* SFRH */ - stv0288_writeregI(state, 0x29, 0); /* SFRM */ - stv0288_writeregI(state, 0x2a, 0); /* SFRL */ - - stv0288_writeregI(state, 0x28, b[0]); - stv0288_writeregI(state, 0x29, b[1]); - stv0288_writeregI(state, 0x2a, b[2]); - dprintk("stv0288: stv0288_set_symbolrate\n"); - - return 0; -} - -static int stv0288_send_diseqc_msg(struct dvb_frontend *fe, - struct dvb_diseqc_master_cmd *m) -{ - struct stv0288_state *state = fe->demodulator_priv; - - int i; - - dprintk("%s\n", __func__); - - stv0288_writeregI(state, 0x09, 0); - msleep(30); - stv0288_writeregI(state, 0x05, 0x16); - - for (i = 0; i < m->msg_len; i++) { - if (stv0288_writeregI(state, 0x06, m->msg[i])) - return -EREMOTEIO; - msleep(12); - } - - return 0; -} - -static int stv0288_send_diseqc_burst(struct dvb_frontend *fe, - fe_sec_mini_cmd_t burst) -{ - struct stv0288_state *state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */ - return -EREMOTEIO; - - if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff)) - return -EREMOTEIO; - - if (stv0288_writeregI(state, 0x06, 0x12)) - return -EREMOTEIO; - - return 0; -} - -static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) -{ - struct stv0288_state *state = fe->demodulator_priv; - - switch (tone) { - case SEC_TONE_ON: - if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */ - return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0xff); - - case SEC_TONE_OFF: - if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */ - return -EREMOTEIO; - return stv0288_writeregI(state, 0x06, 0x00); - - default: - return -EINVAL; - } -} - -static u8 stv0288_inittab[] = { - 0x01, 0x15, - 0x02, 0x20, - 0x09, 0x0, - 0x0a, 0x4, - 0x0b, 0x0, - 0x0c, 0x0, - 0x0d, 0x0, - 0x0e, 0xd4, - 0x0f, 0x30, - 0x11, 0x80, - 0x12, 0x03, - 0x13, 0x48, - 0x14, 0x84, - 0x15, 0x45, - 0x16, 0xb7, - 0x17, 0x9c, - 0x18, 0x0, - 0x19, 0xa6, - 0x1a, 0x88, - 0x1b, 0x8f, - 0x1c, 0xf0, - 0x20, 0x0b, - 0x21, 0x54, - 0x22, 0x0, - 0x23, 0x0, - 0x2b, 0xff, - 0x2c, 0xf7, - 0x30, 0x0, - 0x31, 0x1e, - 0x32, 0x14, - 0x33, 0x0f, - 0x34, 0x09, - 0x35, 0x0c, - 0x36, 0x05, - 0x37, 0x2f, - 0x38, 0x16, - 0x39, 0xbe, - 0x3a, 0x0, - 0x3b, 0x13, - 0x3c, 0x11, - 0x3d, 0x30, - 0x40, 0x63, - 0x41, 0x04, - 0x42, 0x60, - 0x43, 0x00, - 0x44, 0x00, - 0x45, 0x00, - 0x46, 0x00, - 0x47, 0x00, - 0x4a, 0x00, - 0x50, 0x10, - 0x51, 0x38, - 0x52, 0x21, - 0x58, 0x54, - 0x59, 0x86, - 0x5a, 0x0, - 0x5b, 0x9b, - 0x5c, 0x08, - 0x5d, 0x7f, - 0x5e, 0x0, - 0x5f, 0xff, - 0x70, 0x0, - 0x71, 0x0, - 0x72, 0x0, - 0x74, 0x0, - 0x75, 0x0, - 0x76, 0x0, - 0x81, 0x0, - 0x82, 0x3f, - 0x83, 0x3f, - 0x84, 0x0, - 0x85, 0x0, - 0x88, 0x0, - 0x89, 0x0, - 0x8a, 0x0, - 0x8b, 0x0, - 0x8c, 0x0, - 0x90, 0x0, - 0x91, 0x0, - 0x92, 0x0, - 0x93, 0x0, - 0x94, 0x1c, - 0x97, 0x0, - 0xa0, 0x48, - 0xa1, 0x0, - 0xb0, 0xb8, - 0xb1, 0x3a, - 0xb2, 0x10, - 0xb3, 0x82, - 0xb4, 0x80, - 0xb5, 0x82, - 0xb6, 0x82, - 0xb7, 0x82, - 0xb8, 0x20, - 0xb9, 0x0, - 0xf0, 0x0, - 0xf1, 0x0, - 0xf2, 0xc0, - 0x51, 0x36, - 0x52, 0x09, - 0x53, 0x94, - 0x54, 0x62, - 0x55, 0x29, - 0x56, 0x64, - 0x57, 0x2b, - 0xff, 0xff, -}; - -static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt) -{ - dprintk("%s: %s\n", __func__, - volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - return 0; -} - -static int stv0288_init(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - int i; - u8 reg; - u8 val; - - dprintk("stv0288: init chip\n"); - stv0288_writeregI(state, 0x41, 0x04); - msleep(50); - - /* we have default inittab */ - if (state->config->inittab == NULL) { - for (i = 0; !(stv0288_inittab[i] == 0xff && - stv0288_inittab[i + 1] == 0xff); i += 2) - stv0288_writeregI(state, stv0288_inittab[i], - stv0288_inittab[i + 1]); - } else { - for (i = 0; ; i += 2) { - reg = state->config->inittab[i]; - val = state->config->inittab[i+1]; - if (reg == 0xff && val == 0xff) - break; - stv0288_writeregI(state, reg, val); - } - } - return 0; -} - -static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct stv0288_state *state = fe->demodulator_priv; - - u8 sync = stv0288_readreg(state, 0x24); - if (sync == 255) - sync = 0; - - dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); - - *status = 0; - - if ((sync & 0x08) == 0x08) { - *status |= FE_HAS_LOCK; - dprintk("stv0288 has locked\n"); - } - - return 0; -} - -static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return 0; - *ber = (stv0288_readreg(state, 0x26) << 8) | - stv0288_readreg(state, 0x27); - dprintk("stv0288_read_ber %d\n", *ber); - - return 0; -} - - -static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct stv0288_state *state = fe->demodulator_priv; - - s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8)); - - - signal = signal * 5 / 4; - *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal; - dprintk("stv0288_read_signal_strength %d\n", *strength); - - return 0; -} -static int stv0288_sleep(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - - stv0288_writeregI(state, 0x41, 0x84); - state->initialised = 0; - - return 0; -} -static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct stv0288_state *state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8) - | stv0288_readreg(state, 0x2e)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - dprintk("stv0288_read_snr %d\n", *snr); - - return 0; -} - -static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return 0; - *ucblocks = (stv0288_readreg(state, 0x26) << 8) | - stv0288_readreg(state, 0x27); - dprintk("stv0288_read_ber %d\n", *ucblocks); - - return 0; -} - -static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p) -{ - dprintk("%s(..)\n", __func__); - return 0; -} - -static int stv0288_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *dfp) -{ - struct stv0288_state *state = fe->demodulator_priv; - struct dtv_frontend_properties *c = &fe->dtv_property_cache; - - char tm; - unsigned char tda[3]; - - dprintk("%s : FE_SET_FRONTEND\n", __func__); - - if (c->delivery_system != SYS_DVBS) { - dprintk("%s: unsupported delivery " - "system selected (%d)\n", - __func__, c->delivery_system); - return -EOPNOTSUPP; - } - - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - /* only frequency & symbol_rate are used for tuner*/ - dfp->frequency = c->frequency; - dfp->u.qpsk.symbol_rate = c->symbol_rate; - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, dfp); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - udelay(10); - stv0288_set_symbolrate(fe, c->symbol_rate); - /* Carrier lock control register */ - stv0288_writeregI(state, 0x15, 0xc5); - - tda[0] = 0x2b; /* CFRM */ - tda[2] = 0x0; /* CFRL */ - for (tm = -6; tm < 7;) { - /* Viterbi status */ - if (stv0288_readreg(state, 0x24) & 0x80) - break; - - tda[2] += 40; - if (tda[2] < 40) - tm++; - 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; - - return 0; -} - -static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct stv0288_state *state = fe->demodulator_priv; - - if (enable) - stv0288_writeregI(state, 0x01, 0xb5); - else - stv0288_writeregI(state, 0x01, 0x35); - - udelay(1); - - return 0; -} - -static void stv0288_release(struct dvb_frontend *fe) -{ - struct stv0288_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0288_ops = { - - .info = { - .name = "ST STV0288 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1000, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO - }, - - .release = stv0288_release, - .init = stv0288_init, - .sleep = stv0288_sleep, - .write = stv0288_write, - .i2c_gate_ctrl = stv0288_i2c_gate_ctrl, - .read_status = stv0288_read_status, - .read_ber = stv0288_read_ber, - .read_signal_strength = stv0288_read_signal_strength, - .read_snr = stv0288_read_snr, - .read_ucblocks = stv0288_read_ucblocks, - .diseqc_send_master_cmd = stv0288_send_diseqc_msg, - .diseqc_send_burst = stv0288_send_diseqc_burst, - .set_tone = stv0288_set_tone, - .set_voltage = stv0288_set_voltage, - - .set_property = stv0288_set_property, - .get_property = stv0288_get_property, - .set_frontend = stv0288_set_frontend, -}; - -struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c) -{ - struct stv0288_state *state = NULL; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->tuner_frequency = 0; - state->symbol_rate = 0; - state->fec_inner = 0; - state->errmode = STATUS_BER; - - stv0288_writeregI(state, 0x41, 0x04); - msleep(200); - id = stv0288_readreg(state, 0x00); - dprintk("stv0288 id %x\n", id); - - /* register 0x00 contains 0x11 for STV0288 */ - if (id != 0x11) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0288_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - - return NULL; -} -EXPORT_SYMBOL(stv0288_attach); - -module_param(debug_legacy_dish_switch, int, 0444); -MODULE_PARM_DESC(debug_legacy_dish_switch, - "Enable timing analysis for Dish Network legacy switches"); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver"); -MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb/frontends/stv0288.h deleted file mode 100644 index f2b53db0606..00000000000 --- a/drivers/media/dvb/frontends/stv0288.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Driver for ST STV0288 demodulator - - Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de - for Reel Multimedia - Copyright (C) 2008 TurboSight.com, <bob@turbosight.com> - Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by> - Removed stb6000 specific tuner code and revised some - procedures. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef STV0288_H -#define STV0288_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -struct stv0288_config { - /* the demodulator's i2c address */ - u8 demod_address; - - u8* inittab; - - /* minimum delay before retuning */ - int min_delay_ms; - - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \ - defined(MODULE)) -extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_STV0288 */ - -static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val) -{ - int r = 0; - u8 buf[] = { reg, val }; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif /* STV0288_H */ diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c deleted file mode 100644 index 62caf802ed9..00000000000 --- a/drivers/media/dvb/frontends/stv0297.c +++ /dev/null @@ -1,723 +0,0 @@ -/* - Driver for STV0297 demodulator - - Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "stv0297.h" - -struct stv0297_state { - struct i2c_adapter *i2c; - const struct stv0297_config *config; - struct dvb_frontend frontend; - - unsigned long last_ber; - unsigned long base_freq; -}; - -#if 1 -#define dprintk(x...) printk(x) -#else -#define dprintk(x...) -#endif - -#define STV0297_CLOCK_KHZ 28900 - - -static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -1 : 0; -} - -static int stv0297_readreg(struct stv0297_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; - - // this device needs a STOP between the register and data - if (state->config->stop_during_read) { - if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret); - return -1; - } - } - - return b1[0]; -} - -static int stv0297_writereg_mask(struct stv0297_state *state, u8 reg, u8 mask, u8 data) -{ - int val; - - val = stv0297_readreg(state, reg); - val &= ~mask; - val |= (data & mask); - stv0297_writereg(state, reg, val); - - return 0; -} - -static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len) -{ - int ret; - struct i2c_msg msg[] = { {.addr = state->config->demod_address,.flags = 0,.buf = - ®1,.len = 1}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b,.len = len} - }; - - // this device needs a STOP between the register and data - if (state->config->stop_during_read) { - if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); - return -1; - } - if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); - return -1; - } - } else { - if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) { - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret); - return -1; - } - } - - return 0; -} - -static u32 stv0297_get_symbolrate(struct stv0297_state *state) -{ - u64 tmp; - - tmp = stv0297_readreg(state, 0x55); - tmp |= stv0297_readreg(state, 0x56) << 8; - tmp |= stv0297_readreg(state, 0x57) << 16; - tmp |= stv0297_readreg(state, 0x58) << 24; - - tmp *= STV0297_CLOCK_KHZ; - tmp >>= 32; - - return (u32) tmp; -} - -static void stv0297_set_symbolrate(struct stv0297_state *state, u32 srate) -{ - long tmp; - - tmp = 131072L * srate; /* 131072 = 2^17 */ - tmp = tmp / (STV0297_CLOCK_KHZ / 4); /* 1/4 = 2^-2 */ - tmp = tmp * 8192L; /* 8192 = 2^13 */ - - stv0297_writereg(state, 0x55, (unsigned char) (tmp & 0xFF)); - stv0297_writereg(state, 0x56, (unsigned char) (tmp >> 8)); - stv0297_writereg(state, 0x57, (unsigned char) (tmp >> 16)); - stv0297_writereg(state, 0x58, (unsigned char) (tmp >> 24)); -} - -static void stv0297_set_sweeprate(struct stv0297_state *state, short fshift, long symrate) -{ - long tmp; - - tmp = (long) fshift *262144L; /* 262144 = 2*18 */ - tmp /= symrate; - tmp *= 1024; /* 1024 = 2*10 */ - - // adjust - if (tmp >= 0) { - tmp += 500000; - } else { - tmp -= 500000; - } - tmp /= 1000000; - - stv0297_writereg(state, 0x60, tmp & 0xFF); - stv0297_writereg_mask(state, 0x69, 0xF0, (tmp >> 4) & 0xf0); -} - -static void stv0297_set_carrieroffset(struct stv0297_state *state, long offset) -{ - long tmp; - - /* symrate is hardcoded to 10000 */ - tmp = offset * 26844L; /* (2**28)/10000 */ - if (tmp < 0) - tmp += 0x10000000; - tmp &= 0x0FFFFFFF; - - stv0297_writereg(state, 0x66, (unsigned char) (tmp & 0xFF)); - stv0297_writereg(state, 0x67, (unsigned char) (tmp >> 8)); - stv0297_writereg(state, 0x68, (unsigned char) (tmp >> 16)); - stv0297_writereg_mask(state, 0x69, 0x0F, (tmp >> 24) & 0x0f); -} - -/* -static long stv0297_get_carrieroffset(struct stv0297_state *state) -{ - s64 tmp; - - stv0297_writereg(state, 0x6B, 0x00); - - tmp = stv0297_readreg(state, 0x66); - tmp |= (stv0297_readreg(state, 0x67) << 8); - tmp |= (stv0297_readreg(state, 0x68) << 16); - tmp |= (stv0297_readreg(state, 0x69) & 0x0F) << 24; - - tmp *= stv0297_get_symbolrate(state); - tmp >>= 28; - - return (s32) tmp; -} -*/ - -static void stv0297_set_initialdemodfreq(struct stv0297_state *state, long freq) -{ - s32 tmp; - - if (freq > 10000) - freq -= STV0297_CLOCK_KHZ; - - tmp = (STV0297_CLOCK_KHZ * 1000) / (1 << 16); - tmp = (freq * 1000) / tmp; - if (tmp > 0xffff) - tmp = 0xffff; - - stv0297_writereg_mask(state, 0x25, 0x80, 0x80); - stv0297_writereg(state, 0x21, tmp >> 8); - stv0297_writereg(state, 0x20, tmp); -} - -static int stv0297_set_qam(struct stv0297_state *state, fe_modulation_t modulation) -{ - int val = 0; - - switch (modulation) { - case QAM_16: - val = 0; - break; - - case QAM_32: - val = 1; - break; - - case QAM_64: - val = 4; - break; - - case QAM_128: - val = 2; - break; - - case QAM_256: - val = 3; - break; - - default: - return -EINVAL; - } - - stv0297_writereg_mask(state, 0x00, 0x70, val << 4); - - return 0; -} - -static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_inversion_t inversion) -{ - int val = 0; - - switch (inversion) { - case INVERSION_OFF: - val = 0; - break; - - case INVERSION_ON: - val = 1; - break; - - default: - return -EINVAL; - } - - stv0297_writereg_mask(state, 0x83, 0x08, val << 3); - - return 0; -} - -static int stv0297_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct stv0297_state *state = fe->demodulator_priv; - - if (enable) { - stv0297_writereg(state, 0x87, 0x78); - stv0297_writereg(state, 0x86, 0xc8); - } - - return 0; -} - -static int stv0297_init(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - int i; - - /* load init table */ - for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2) - stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); - msleep(200); - - state->last_ber = 0; - - return 0; -} - -static int stv0297_sleep(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - - stv0297_writereg_mask(state, 0x80, 1, 1); - - return 0; -} - -static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) -{ - struct stv0297_state *state = fe->demodulator_priv; - - u8 sync = stv0297_readreg(state, 0xDF); - - *status = 0; - if (sync & 0x80) - *status |= - FE_HAS_SYNC | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_LOCK; - return 0; -} - -static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 BER[3]; - - stv0297_readregs(state, 0xA0, BER, 3); - if (!(BER[0] & 0x80)) { - state->last_ber = BER[2] << 8 | BER[1]; - stv0297_writereg_mask(state, 0xA0, 0x80, 0x80); - } - - *ber = state->last_ber; - - return 0; -} - - -static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 STRENGTH[3]; - u16 tmp; - - stv0297_readregs(state, 0x41, STRENGTH, 3); - tmp = (STRENGTH[1] & 0x03) << 8 | STRENGTH[0]; - if (STRENGTH[2] & 0x20) { - if (tmp < 0x200) - tmp = 0; - else - tmp = tmp - 0x200; - } else { - if (tmp > 0x1ff) - tmp = 0; - else - tmp = 0x1ff - tmp; - } - *strength = (tmp << 7) | (tmp >> 2); - return 0; -} - -static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr) -{ - struct stv0297_state *state = fe->demodulator_priv; - u8 SNR[2]; - - stv0297_readregs(state, 0x07, SNR, 2); - *snr = SNR[1] << 8 | SNR[0]; - - return 0; -} - -static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) -{ - struct stv0297_state *state = fe->demodulator_priv; - - stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */ - - *ucblocks = (stv0297_readreg(state, 0xD5) << 8) - | stv0297_readreg(state, 0xD4); - - stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */ - stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */ - - return 0; -} - -static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stv0297_state *state = fe->demodulator_priv; - int u_threshold; - int initial_u; - int blind_u; - int delay; - int sweeprate; - int carrieroffset; - unsigned long starttime; - unsigned long timeout; - fe_spectral_inversion_t inversion; - - switch (p->u.qam.modulation) { - case QAM_16: - case QAM_32: - case QAM_64: - delay = 100; - sweeprate = 1000; - break; - - case QAM_128: - case QAM_256: - delay = 200; - sweeprate = 500; - break; - - default: - return -EINVAL; - } - - // determine inversion dependant parameters - inversion = p->inversion; - if (state->config->invert) - inversion = (inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; - carrieroffset = -330; - switch (inversion) { - case INVERSION_OFF: - break; - - case INVERSION_ON: - sweeprate = -sweeprate; - carrieroffset = -carrieroffset; - break; - - default: - return -EINVAL; - } - - stv0297_init(fe); - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* clear software interrupts */ - stv0297_writereg(state, 0x82, 0x0); - - /* set initial demodulation frequency */ - stv0297_set_initialdemodfreq(state, 7250); - - /* setup AGC */ - stv0297_writereg_mask(state, 0x43, 0x10, 0x00); - stv0297_writereg(state, 0x41, 0x00); - stv0297_writereg_mask(state, 0x42, 0x03, 0x01); - stv0297_writereg_mask(state, 0x36, 0x60, 0x00); - stv0297_writereg_mask(state, 0x36, 0x18, 0x00); - stv0297_writereg_mask(state, 0x71, 0x80, 0x80); - stv0297_writereg(state, 0x72, 0x00); - stv0297_writereg(state, 0x73, 0x00); - stv0297_writereg_mask(state, 0x74, 0x0F, 0x00); - stv0297_writereg_mask(state, 0x43, 0x08, 0x00); - stv0297_writereg_mask(state, 0x71, 0x80, 0x00); - - /* setup STL */ - stv0297_writereg_mask(state, 0x5a, 0x20, 0x20); - stv0297_writereg_mask(state, 0x5b, 0x02, 0x02); - stv0297_writereg_mask(state, 0x5b, 0x02, 0x00); - stv0297_writereg_mask(state, 0x5b, 0x01, 0x00); - stv0297_writereg_mask(state, 0x5a, 0x40, 0x40); - - /* disable frequency sweep */ - stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); - - /* reset deinterleaver */ - stv0297_writereg_mask(state, 0x81, 0x01, 0x01); - stv0297_writereg_mask(state, 0x81, 0x01, 0x00); - - /* ??? */ - stv0297_writereg_mask(state, 0x83, 0x20, 0x20); - stv0297_writereg_mask(state, 0x83, 0x20, 0x00); - - /* reset equaliser */ - u_threshold = stv0297_readreg(state, 0x00) & 0xf; - initial_u = stv0297_readreg(state, 0x01) >> 4; - blind_u = stv0297_readreg(state, 0x01) & 0xf; - stv0297_writereg_mask(state, 0x84, 0x01, 0x01); - stv0297_writereg_mask(state, 0x84, 0x01, 0x00); - stv0297_writereg_mask(state, 0x00, 0x0f, u_threshold); - stv0297_writereg_mask(state, 0x01, 0xf0, initial_u << 4); - stv0297_writereg_mask(state, 0x01, 0x0f, blind_u); - - /* data comes from internal A/D */ - stv0297_writereg_mask(state, 0x87, 0x80, 0x00); - - /* clear phase registers */ - stv0297_writereg(state, 0x63, 0x00); - stv0297_writereg(state, 0x64, 0x00); - stv0297_writereg(state, 0x65, 0x00); - stv0297_writereg(state, 0x66, 0x00); - stv0297_writereg(state, 0x67, 0x00); - stv0297_writereg(state, 0x68, 0x00); - stv0297_writereg_mask(state, 0x69, 0x0f, 0x00); - - /* set parameters */ - stv0297_set_qam(state, p->u.qam.modulation); - stv0297_set_symbolrate(state, p->u.qam.symbol_rate / 1000); - stv0297_set_sweeprate(state, sweeprate, p->u.qam.symbol_rate / 1000); - stv0297_set_carrieroffset(state, carrieroffset); - stv0297_set_inversion(state, inversion); - - /* kick off lock */ - /* Disable corner detection for higher QAMs */ - if (p->u.qam.modulation == QAM_128 || - p->u.qam.modulation == QAM_256) - stv0297_writereg_mask(state, 0x88, 0x08, 0x00); - else - stv0297_writereg_mask(state, 0x88, 0x08, 0x08); - - stv0297_writereg_mask(state, 0x5a, 0x20, 0x00); - stv0297_writereg_mask(state, 0x6a, 0x01, 0x01); - stv0297_writereg_mask(state, 0x43, 0x40, 0x40); - stv0297_writereg_mask(state, 0x5b, 0x30, 0x00); - stv0297_writereg_mask(state, 0x03, 0x0c, 0x0c); - stv0297_writereg_mask(state, 0x03, 0x03, 0x03); - stv0297_writereg_mask(state, 0x43, 0x10, 0x10); - - /* wait for WGAGC lock */ - starttime = jiffies; - timeout = jiffies + msecs_to_jiffies(2000); - while (time_before(jiffies, timeout)) { - msleep(10); - if (stv0297_readreg(state, 0x43) & 0x08) - break; - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - msleep(20); - - /* wait for equaliser partial convergence */ - timeout = jiffies + msecs_to_jiffies(500); - while (time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0x82) & 0x04) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - - /* wait for equaliser full convergence */ - timeout = jiffies + msecs_to_jiffies(delay); - while (time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0x82) & 0x08) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - - /* disable sweep */ - stv0297_writereg_mask(state, 0x6a, 1, 0); - stv0297_writereg_mask(state, 0x88, 8, 0); - - /* wait for main lock */ - timeout = jiffies + msecs_to_jiffies(20); - while (time_before(jiffies, timeout)) { - msleep(10); - - if (stv0297_readreg(state, 0xDF) & 0x80) { - break; - } - } - if (time_after(jiffies, timeout)) { - goto timeout; - } - msleep(100); - - /* is it still locked after that delay? */ - if (!(stv0297_readreg(state, 0xDF) & 0x80)) { - goto timeout; - } - - /* success!! */ - stv0297_writereg_mask(state, 0x5a, 0x40, 0x00); - state->base_freq = p->frequency; - return 0; - -timeout: - stv0297_writereg_mask(state, 0x6a, 0x01, 0x00); - return 0; -} - -static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) -{ - struct stv0297_state *state = fe->demodulator_priv; - int reg_00, reg_83; - - reg_00 = stv0297_readreg(state, 0x00); - reg_83 = stv0297_readreg(state, 0x83); - - p->frequency = state->base_freq; - p->inversion = (reg_83 & 0x08) ? INVERSION_ON : INVERSION_OFF; - if (state->config->invert) - p->inversion = (p->inversion == INVERSION_ON) ? INVERSION_OFF : INVERSION_ON; - p->u.qam.symbol_rate = stv0297_get_symbolrate(state) * 1000; - p->u.qam.fec_inner = FEC_NONE; - - switch ((reg_00 >> 4) & 0x7) { - case 0: - p->u.qam.modulation = QAM_16; - break; - case 1: - p->u.qam.modulation = QAM_32; - break; - case 2: - p->u.qam.modulation = QAM_128; - break; - case 3: - p->u.qam.modulation = QAM_256; - break; - case 4: - p->u.qam.modulation = QAM_64; - break; - } - - return 0; -} - -static void stv0297_release(struct dvb_frontend *fe) -{ - struct stv0297_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0297_ops; - -struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, - struct i2c_adapter *i2c) -{ - struct stv0297_state *state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->last_ber = 0; - state->base_freq = 0; - - /* check if the demod is there */ - if ((stv0297_readreg(state, 0x80) & 0x70) != 0x20) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0297_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops stv0297_ops = { - - .info = { - .name = "ST STV0297 DVB-C", - .type = FE_QAM, - .frequency_min = 47000000, - .frequency_max = 862000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 870000, - .symbol_rate_max = 11700000, - .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO}, - - .release = stv0297_release, - - .init = stv0297_init, - .sleep = stv0297_sleep, - .i2c_gate_ctrl = stv0297_i2c_gate_ctrl, - - .set_frontend = stv0297_set_frontend, - .get_frontend = stv0297_get_frontend, - - .read_status = stv0297_read_status, - .read_ber = stv0297_read_ber, - .read_signal_strength = stv0297_read_signal_strength, - .read_snr = stv0297_read_snr, - .read_ucblocks = stv0297_read_ucblocks, -}; - -MODULE_DESCRIPTION("ST STV0297 DVB-C Demodulator driver"); -MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(stv0297_attach); diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h deleted file mode 100644 index 3f8f9468f38..00000000000 --- a/drivers/media/dvb/frontends/stv0297.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Driver for STV0297 demodulator - - Copyright (C) 2003-2004 Dennis Noermann <dennis.noermann@noernet.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef STV0297_H -#define STV0297_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -struct stv0297_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* inittab - array of pairs of values. - * First of each pair is the register, second is the value. - * List should be terminated with an 0xff, 0xff pair. - */ - u8* inittab; - - /* does the "inversion" need inverted? */ - u8 invert:1; - - /* set to 1 if the device requires an i2c STOP during reading */ - u8 stop_during_read:1; -}; - -#if defined(CONFIG_DVB_STV0297) || (defined(CONFIG_DVB_STV0297_MODULE) && defined(MODULE)) -extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_STV0297 - -#endif // STV0297_H diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c deleted file mode 100644 index 6c1cb1973c6..00000000000 --- a/drivers/media/dvb/frontends/stv0299.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - Driver for ST STV0299 demodulator - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - <ralph@convergence.de>, - <holger@convergence.de>, - <js@convergence.de> - - - Philips SU1278/SH - - Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de> - - - LG TDQF-S001F - - Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net> - & Andreas Oberritter <obi@linuxtv.org> - - - Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B - - Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>: - - Support for Philips SU1278 on Technotrend hardware - - Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "stv0299.h" - -struct stv0299_state { - struct i2c_adapter* i2c; - const struct stv0299_config* config; - struct dvb_frontend frontend; - - u8 initialised:1; - u32 tuner_frequency; - u32 symbol_rate; - fe_code_rate_t fec_inner; - int errmode; - u32 ucblocks; -}; - -#define STATUS_BER 0 -#define STATUS_UCBLOCKS 1 - -static int debug; -static int debug_legacy_dish_switch; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "stv0299: " args); \ - } while (0) - - -static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - ret = i2c_transfer (state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, " - "ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return stv0299_writeregI(state, buf[0], buf[1]); -} - -static u8 stv0299_readreg (struct stv0299_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", - __func__, reg, ret); - - return b1[0]; -} - -static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) - dprintk("%s: readreg error (ret == %i)\n", __func__, ret); - - return ret == 2 ? 0 : ret; -} - -static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) -{ - dprintk ("%s\n", __func__); - - switch (fec) { - case FEC_AUTO: - { - return stv0299_writeregI (state, 0x31, 0x1f); - } - case FEC_1_2: - { - return stv0299_writeregI (state, 0x31, 0x01); - } - case FEC_2_3: - { - return stv0299_writeregI (state, 0x31, 0x02); - } - case FEC_3_4: - { - return stv0299_writeregI (state, 0x31, 0x04); - } - case FEC_5_6: - { - return stv0299_writeregI (state, 0x31, 0x08); - } - case FEC_7_8: - { - return stv0299_writeregI (state, 0x31, 0x10); - } - default: - { - return -EINVAL; - } - } -} - -static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state) -{ - static fe_code_rate_t fec_tab [] = { FEC_2_3, FEC_3_4, FEC_5_6, - FEC_7_8, FEC_1_2 }; - u8 index; - - dprintk ("%s\n", __func__); - - index = stv0299_readreg (state, 0x1b); - index &= 0x7; - - if (index > 4) - return FEC_AUTO; - - return fec_tab [index]; -} - -static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout) -{ - unsigned long start = jiffies; - - dprintk ("%s\n", __func__); - - while (stv0299_readreg(state, 0x0a) & 1) { - if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout) -{ - unsigned long start = jiffies; - - dprintk ("%s\n", __func__); - - while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) { - if (jiffies - start > timeout) { - dprintk ("%s: timeout!!\n", __func__); - return -ETIMEDOUT; - } - msleep(10); - }; - - return 0; -} - -static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate) -{ - struct stv0299_state* state = fe->demodulator_priv; - u64 big = srate; - u32 ratio; - - // check rate is within limits - if ((srate < 1000000) || (srate > 45000000)) return -EINVAL; - - // calculate value to program - big = big << 20; - big += (state->config->mclk-1); // round correctly - do_div(big, state->config->mclk); - ratio = big << 4; - - return state->config->set_symbol_rate(fe, srate, ratio); -} - -static int stv0299_get_symbolrate (struct stv0299_state* state) -{ - u32 Mclk = state->config->mclk / 4096L; - u32 srate; - s32 offset; - u8 sfr[3]; - s8 rtf; - - dprintk ("%s\n", __func__); - - stv0299_readregs (state, 0x1f, sfr, 3); - stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1); - - srate = (sfr[0] << 8) | sfr[1]; - srate *= Mclk; - srate /= 16; - srate += (sfr[2] >> 4) * Mclk / 256; - offset = (s32) rtf * (srate / 4096L); - offset /= 128; - - dprintk ("%s : srate = %i\n", __func__, srate); - dprintk ("%s : ofset = %i\n", __func__, offset); - - srate += offset; - - srate += 1000; - srate /= 2000; - srate *= 2000; - - return srate; -} - -static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 val; - int i; - - dprintk ("%s\n", __func__); - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - val = stv0299_readreg (state, 0x08); - - if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x6)) /* DiSEqC mode */ - return -EREMOTEIO; - - for (i=0; i<m->msg_len; i++) { - if (stv0299_wait_diseqc_fifo (state, 100) < 0) - return -ETIMEDOUT; - - if (stv0299_writeregI (state, 0x09, m->msg[i])) - return -EREMOTEIO; - } - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - return 0; -} - -static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 val; - - dprintk ("%s\n", __func__); - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - val = stv0299_readreg (state, 0x08); - - if (stv0299_writeregI (state, 0x08, (val & ~0x7) | 0x2)) /* burst mode */ - return -EREMOTEIO; - - if (stv0299_writeregI (state, 0x09, burst == SEC_MINI_A ? 0x00 : 0xff)) - return -EREMOTEIO; - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - if (stv0299_writeregI (state, 0x08, val)) - return -EREMOTEIO; - - return 0; -} - -static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 val; - - if (stv0299_wait_diseqc_idle (state, 100) < 0) - return -ETIMEDOUT; - - val = stv0299_readreg (state, 0x08); - - switch (tone) { - case SEC_TONE_ON: - return stv0299_writeregI (state, 0x08, val | 0x3); - - case SEC_TONE_OFF: - return stv0299_writeregI (state, 0x08, (val & ~0x3) | 0x02); - - default: - return -EINVAL; - } -} - -static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 reg0x08; - u8 reg0x0c; - - dprintk("%s: %s\n", __func__, - voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : - voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??"); - - reg0x08 = stv0299_readreg (state, 0x08); - reg0x0c = stv0299_readreg (state, 0x0c); - - /** - * H/V switching over OP0, OP1 and OP2 are LNB power enable bits - */ - reg0x0c &= 0x0f; - reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6); - - switch (voltage) { - case SEC_VOLTAGE_13: - if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) - reg0x0c |= 0x10; /* OP1 off, OP0 on */ - else - reg0x0c |= 0x40; /* OP1 on, OP0 off */ - break; - case SEC_VOLTAGE_18: - reg0x0c |= 0x50; /* OP1 on, OP0 on */ - break; - case SEC_VOLTAGE_OFF: - /* LNB power off! */ - reg0x08 = 0x00; - reg0x0c = 0x00; - break; - default: - return -EINVAL; - }; - - if (state->config->op0_off) - reg0x0c &= ~0x10; - - stv0299_writeregI(state, 0x08, reg0x08); - return stv0299_writeregI(state, 0x0c, reg0x0c); -} - -static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) -{ - struct stv0299_state* state = fe->demodulator_priv; - u8 reg0x08; - u8 reg0x0c; - u8 lv_mask = 0x40; - u8 last = 1; - int i; - struct timeval nexttime; - struct timeval tv[10]; - - reg0x08 = stv0299_readreg (state, 0x08); - reg0x0c = stv0299_readreg (state, 0x0c); - reg0x0c &= 0x0f; - stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6)); - if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) - lv_mask = 0x10; - - cmd = cmd << 1; - if (debug_legacy_dish_switch) - printk ("%s switch command: 0x%04lx\n",__func__, cmd); - - do_gettimeofday (&nexttime); - if (debug_legacy_dish_switch) - memcpy (&tv[0], &nexttime, sizeof (struct timeval)); - stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ - - dvb_frontend_sleep_until(&nexttime, 32000); - - for (i=0; i<9; i++) { - if (debug_legacy_dish_switch) - do_gettimeofday (&tv[i+1]); - if((cmd & 0x01) != last) { - /* set voltage to (last ? 13V : 18V) */ - stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50)); - last = (last) ? 0 : 1; - } - - cmd = cmd >> 1; - - if (i != 8) - dvb_frontend_sleep_until(&nexttime, 8000); - } - if (debug_legacy_dish_switch) { - printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", - __func__, fe->dvb->num); - for (i = 1; i < 10; i++) - printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i])); - } - - return 0; -} - -static int stv0299_init (struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - int i; - u8 reg; - u8 val; - - dprintk("stv0299: init chip\n"); - - for (i = 0; ; i += 2) { - reg = state->config->inittab[i]; - val = state->config->inittab[i+1]; - if (reg == 0xff && val == 0xff) - break; - if (reg == 0x0c && state->config->op0_off) - val &= ~0x10; - stv0299_writeregI(state, reg, val); - } - - return 0; -} - -static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct stv0299_state* state = fe->demodulator_priv; - - u8 signal = 0xff - stv0299_readreg (state, 0x18); - u8 sync = stv0299_readreg (state, 0x1b); - - dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x80) - *status |= FE_HAS_CARRIER; - - if (sync & 0x10) - *status |= FE_HAS_VITERBI; - - if (sync & 0x08) - *status |= FE_HAS_SYNC; - - if ((sync & 0x98) == 0x98) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (state->errmode != STATUS_BER) - return -ENOSYS; - - *ber = stv0299_readreg(state, 0x1e) | (stv0299_readreg(state, 0x1d) << 8); - - return 0; -} - -static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct stv0299_state* state = fe->demodulator_priv; - - s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8) - | stv0299_readreg (state, 0x19)); - - dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__, - stv0299_readreg (state, 0x18), - stv0299_readreg (state, 0x19), (int) signal); - - signal = signal * 5 / 4; - *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal; - - return 0; -} - -static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct stv0299_state* state = fe->demodulator_priv; - - s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8) - | stv0299_readreg (state, 0x25)); - xsnr = 3 * (xsnr - 0xa100); - *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr; - - return 0; -} - -static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (state->errmode != STATUS_UCBLOCKS) - return -ENOSYS; - - state->ucblocks += stv0299_readreg(state, 0x1e); - state->ucblocks += (stv0299_readreg(state, 0x1d) << 8); - *ucblocks = state->ucblocks; - - return 0; -} - -static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) -{ - struct stv0299_state* state = fe->demodulator_priv; - int invval = 0; - - dprintk ("%s : FE_SET_FRONTEND\n", __func__); - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - // set the inversion - if (p->inversion == INVERSION_OFF) invval = 0; - else if (p->inversion == INVERSION_ON) invval = 1; - else { - printk("stv0299 does not support auto-inversion\n"); - return -EINVAL; - } - if (state->config->invert) invval = (~invval) & 1; - stv0299_writeregI(state, 0x0c, (stv0299_readreg(state, 0x0c) & 0xfe) | invval); - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - stv0299_set_FEC (state, p->u.qpsk.fec_inner); - stv0299_set_symbolrate (fe, p->u.qpsk.symbol_rate); - stv0299_writeregI(state, 0x22, 0x00); - stv0299_writeregI(state, 0x23, 0x00); - - state->tuner_frequency = p->frequency; - state->fec_inner = p->u.qpsk.fec_inner; - state->symbol_rate = p->u.qpsk.symbol_rate; - - return 0; -} - -static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) -{ - struct stv0299_state* state = fe->demodulator_priv; - s32 derot_freq; - int invval; - - derot_freq = (s32)(s16) ((stv0299_readreg (state, 0x22) << 8) - | stv0299_readreg (state, 0x23)); - - derot_freq *= (state->config->mclk >> 16); - derot_freq += 500; - derot_freq /= 1000; - - p->frequency += derot_freq; - - invval = stv0299_readreg (state, 0x0c) & 1; - if (state->config->invert) invval = (~invval) & 1; - p->inversion = invval ? INVERSION_ON : INVERSION_OFF; - - p->u.qpsk.fec_inner = stv0299_get_fec (state); - p->u.qpsk.symbol_rate = stv0299_get_symbolrate (state); - - return 0; -} - -static int stv0299_sleep(struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - - stv0299_writeregI(state, 0x02, 0x80); - state->initialised = 0; - - return 0; -} - -static int stv0299_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct stv0299_state* state = fe->demodulator_priv; - - if (enable) { - stv0299_writeregI(state, 0x05, 0xb5); - } else { - stv0299_writeregI(state, 0x05, 0x35); - } - udelay(1); - return 0; -} - -static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - struct stv0299_state* state = fe->demodulator_priv; - - fesettings->min_delay_ms = state->config->min_delay_ms; - if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 32000; - fesettings->max_drift = 5000; - } else { - fesettings->step_size = fesettings->parameters.u.qpsk.symbol_rate / 16000; - fesettings->max_drift = fesettings->parameters.u.qpsk.symbol_rate / 2000; - } - return 0; -} - -static void stv0299_release(struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops stv0299_ops; - -struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, - struct i2c_adapter* i2c) -{ - struct stv0299_state* state = NULL; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->initialised = 0; - state->tuner_frequency = 0; - state->symbol_rate = 0; - state->fec_inner = 0; - state->errmode = STATUS_BER; - - /* check if the demod is there */ - stv0299_writeregI(state, 0x02, 0x34); /* standby off */ - msleep(200); - id = stv0299_readreg(state, 0x00); - - /* register 0x00 contains 0xa1 for STV0299 and STV0299B */ - /* register 0x00 might contain 0x80 when returning from standby */ - if (id != 0xa1 && id != 0x80) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &stv0299_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops stv0299_ops = { - - .info = { - .name = "ST STV0299 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 0, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO - }, - - .release = stv0299_release, - - .init = stv0299_init, - .sleep = stv0299_sleep, - .write = stv0299_write, - .i2c_gate_ctrl = stv0299_i2c_gate_ctrl, - - .set_frontend = stv0299_set_frontend, - .get_frontend = stv0299_get_frontend, - .get_tune_settings = stv0299_get_tune_settings, - - .read_status = stv0299_read_status, - .read_ber = stv0299_read_ber, - .read_signal_strength = stv0299_read_signal_strength, - .read_snr = stv0299_read_snr, - .read_ucblocks = stv0299_read_ucblocks, - - .diseqc_send_master_cmd = stv0299_send_diseqc_msg, - .diseqc_send_burst = stv0299_send_diseqc_burst, - .set_tone = stv0299_set_tone, - .set_voltage = stv0299_set_voltage, - .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd, -}; - -module_param(debug_legacy_dish_switch, int, 0444); -MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches"); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("ST STV0299 DVB Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " - "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(stv0299_attach); diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h deleted file mode 100644 index 0fd96e22b65..00000000000 --- a/drivers/media/dvb/frontends/stv0299.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - Driver for ST STV0299 demodulator - - Copyright (C) 2001-2002 Convergence Integrated Media GmbH - <ralph@convergence.de>, - <holger@convergence.de>, - <js@convergence.de> - - - Philips SU1278/SH - - Copyright (C) 2002 by Peter Schildmann <peter.schildmann@web.de> - - - LG TDQF-S001F - - Copyright (C) 2002 Felix Domke <tmbinc@elitedvb.net> - & Andreas Oberritter <obi@linuxtv.org> - - - Support for Samsung TBMU24112IMB used on Technisat SkyStar2 rev. 2.6B - - Copyright (C) 2003 Vadim Catana <skystar@moldova.cc>: - - Support for Philips SU1278 on Technotrend hardware - - Copyright (C) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef STV0299_H -#define STV0299_H - -#include <linux/dvb/frontend.h> -#include "dvb_frontend.h" - -#define STV0299_LOCKOUTPUT_0 0 -#define STV0299_LOCKOUTPUT_1 1 -#define STV0299_LOCKOUTPUT_CF 2 -#define STV0299_LOCKOUTPUT_LK 3 - -#define STV0299_VOLT13_OP0 0 -#define STV0299_VOLT13_OP1 1 - -struct stv0299_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* inittab - array of pairs of values. - * First of each pair is the register, second is the value. - * List should be terminated with an 0xff, 0xff pair. - */ - u8* inittab; - - /* master clock to use */ - u32 mclk; - - /* does the inversion require inversion? */ - u8 invert:1; - - /* Skip reinitialisation? */ - u8 skip_reinit:1; - - /* LOCK OUTPUT setting */ - u8 lock_output:2; - - /* Is 13v controlled by OP0 or OP1? */ - u8 volt13_op0_op1:1; - - /* Turn-off OP0? */ - u8 op0_off:1; - - /* minimum delay before retuning */ - int min_delay_ms; - - /* Set the symbol rate */ - int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio); - - /* Set device param to start dma */ - int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); -}; - -#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) -extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_STV0299 - -static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif // STV0299_H diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c deleted file mode 100644 index f648fdb64bb..00000000000 --- a/drivers/media/dvb/frontends/tda10021.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - TDA10021 - Single Chip Cable Channel Receiver driver module - used on the Siemens DVB-C cards - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> - Support for TDA10021 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda1002x.h" - - -struct tda10021_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda1002x_config* config; - struct dvb_frontend frontend; - - u8 pwm; - u8 reg0; -}; - - -#if 0 -#define dprintk(x...) printk(x) -#else -#define dprintk(x...) -#endif - -static int verbose; - -#define XIN 57840000UL - -#define FIN (XIN >> 4) - -static int tda10021_inittab_size = 0x40; -static u8 tda10021_inittab[0x40]= -{ - 0x73, 0x6a, 0x23, 0x0a, 0x02, 0x37, 0x77, 0x1a, - 0x37, 0x6a, 0x17, 0x8a, 0x1e, 0x86, 0x43, 0x40, - 0xb8, 0x3f, 0xa1, 0x00, 0xcd, 0x01, 0x00, 0xff, - 0x11, 0x00, 0x7c, 0x31, 0x30, 0x20, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x33, 0x11, 0x0d, 0x95, 0x08, 0x58, - 0x00, 0x00, 0x80, 0x00, 0x80, 0xff, 0x00, 0x00, - 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00, -}; - -static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int ret; - - ret = i2c_transfer (state->i2c, &msg, 1); - if (ret != 1) - printk("DVB: TDA10021(%d): %s, writereg error " - "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - state->frontend.dvb->num, __func__, reg, data, ret); - - msleep(10); - return (ret != 1) ? -EREMOTEIO : 0; -} - -static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) -{ - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - int ret; - - ret = i2c_transfer (state->i2c, msg, 2); - // Don't print an error message if the id is read. - if (ret != 2 && reg != 0x1a) - printk("DVB: TDA10021: %s: readreg error (ret == %i)\n", - __func__, ret); - return b1[0]; -} - -//get access to tuner -static int lock_tuner(struct tda10021_state* state) -{ - u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] | 0x80 }; - struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg, 1) != 1) - { - printk("tda10021: lock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -//release access from tuner -static int unlock_tuner(struct tda10021_state* state) -{ - u8 buf[2] = { 0x0f, tda10021_inittab[0x0f] & 0x7f }; - struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg_post, 1) != 1) - { - printk("tda10021: unlock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0, - fe_spectral_inversion_t inversion) -{ - reg0 |= state->reg0 & 0x63; - - if ((INVERSION_ON == inversion) ^ (state->config->invert == 0)) - reg0 &= ~0x20; - else - reg0 |= 0x20; - - _tda10021_writereg (state, 0x00, reg0 & 0xfe); - _tda10021_writereg (state, 0x00, reg0 | 0x01); - - state->reg0 = reg0; - return 0; -} - -static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate) -{ - s32 BDR; - s32 BDRI; - s16 SFIL=0; - u16 NDEC = 0; - u32 tmp, ratio; - - if (symbolrate > XIN/2) - symbolrate = XIN/2; - if (symbolrate < 500000) - symbolrate = 500000; - - if (symbolrate < XIN/16) NDEC = 1; - if (symbolrate < XIN/32) NDEC = 2; - if (symbolrate < XIN/64) NDEC = 3; - - if (symbolrate < (u32)(XIN/12.3)) SFIL = 1; - if (symbolrate < (u32)(XIN/16)) SFIL = 0; - if (symbolrate < (u32)(XIN/24.6)) SFIL = 1; - if (symbolrate < (u32)(XIN/32)) SFIL = 0; - if (symbolrate < (u32)(XIN/49.2)) SFIL = 1; - if (symbolrate < (u32)(XIN/64)) SFIL = 0; - if (symbolrate < (u32)(XIN/98.4)) SFIL = 1; - - symbolrate <<= NDEC; - ratio = (symbolrate << 4) / FIN; - tmp = ((symbolrate << 4) % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + (tmp + FIN/2) / FIN; - - BDR = ratio; - BDRI = (((XIN << 5) / symbolrate) + 1) / 2; - - if (BDRI > 0xFF) - BDRI = 0xFF; - - SFIL = (SFIL << 4) | tda10021_inittab[0x0E]; - - NDEC = (NDEC << 6) | tda10021_inittab[0x03]; - - _tda10021_writereg (state, 0x03, NDEC); - _tda10021_writereg (state, 0x0a, BDR&0xff); - _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff); - _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f); - - _tda10021_writereg (state, 0x0d, BDRI); - _tda10021_writereg (state, 0x0e, SFIL); - - return 0; -} - -static int tda10021_init (struct dvb_frontend *fe) -{ - struct tda10021_state* state = fe->demodulator_priv; - int i; - - dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num); - - //_tda10021_writereg (fe, 0, 0); - - for (i=0; i<tda10021_inittab_size; i++) - _tda10021_writereg (state, i, tda10021_inittab[i]); - - _tda10021_writereg (state, 0x34, state->pwm); - - //Comment by markus - //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0) - //0x2A[4] == BYPPLL -> Power down mode (default 1) - //0x2A[5] == LCK -> PLL Lock Flag - //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0) - - //Activate PLL - _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); - return 0; -} - -static int tda10021_set_parameters (struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10021_state* state = fe->demodulator_priv; - - //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256 - //CONF - static const u8 reg0x00 [] = { 0x14, 0x00, 0x04, 0x08, 0x0c, 0x10 }; - //AGCREF value - static const u8 reg0x01 [] = { 0x78, 0x8c, 0x8c, 0x6a, 0x78, 0x5c }; - //LTHR value - static const u8 reg0x05 [] = { 0x78, 0x87, 0x64, 0x46, 0x36, 0x26 }; - //MSETH - static const u8 reg0x08 [] = { 0x8c, 0xa2, 0x74, 0x43, 0x34, 0x23 }; - //AREF - static const u8 reg0x09 [] = { 0x96, 0x91, 0x96, 0x6a, 0x7e, 0x6b }; - - int qam = p->u.qam.modulation; - - if (qam < 0 || qam > 5) - return -EINVAL; - - if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF) - return -EINVAL; - - //printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate); - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - tda10021_set_symbolrate (state, p->u.qam.symbol_rate); - _tda10021_writereg (state, 0x34, state->pwm); - - _tda10021_writereg (state, 0x01, reg0x01[qam]); - _tda10021_writereg (state, 0x05, reg0x05[qam]); - _tda10021_writereg (state, 0x08, reg0x08[qam]); - _tda10021_writereg (state, 0x09, reg0x09[qam]); - - tda10021_setup_reg0 (state, reg0x00[qam], p->inversion); - - return 0; -} - -static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct tda10021_state* state = fe->demodulator_priv; - int sync; - - *status = 0; - //0x11[0] == EQALGO -> Equalizer algorithms state - //0x11[1] == CARLOCK -> Carrier locked - //0x11[2] == FSYNC -> Frame synchronisation - //0x11[3] == FEL -> Front End locked - //0x11[6] == NODVB -> DVB Mode Information - sync = tda10021_readreg (state, 0x11); - - if (sync & 2) - *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_SYNC|FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda10021_state* state = fe->demodulator_priv; - - u32 _ber = tda10021_readreg(state, 0x14) | - (tda10021_readreg(state, 0x15) << 8) | - ((tda10021_readreg(state, 0x16) & 0x0f) << 16); - _tda10021_writereg(state, 0x10, (tda10021_readreg(state, 0x10) & ~0xc0) - | (tda10021_inittab[0x10] & 0xc0)); - *ber = 10 * _ber; - - return 0; -} - -static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct tda10021_state* state = fe->demodulator_priv; - - u8 config = tda10021_readreg(state, 0x02); - u8 gain = tda10021_readreg(state, 0x17); - if (config & 0x02) - /* the agc value is inverted */ - gain = ~gain; - *strength = (gain << 8) | gain; - - return 0; -} - -static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct tda10021_state* state = fe->demodulator_priv; - - u8 quality = ~tda10021_readreg(state, 0x18); - *snr = (quality << 8) | quality; - - return 0; -} - -static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda10021_state* state = fe->demodulator_priv; - - *ucblocks = tda10021_readreg (state, 0x13) & 0x7f; - if (*ucblocks == 0x7f) - *ucblocks = 0xffffffff; - - /* reset uncorrected block counter */ - _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf); - _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]); - - return 0; -} - -static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda10021_state* state = fe->demodulator_priv; - int sync; - s8 afc = 0; - - sync = tda10021_readreg(state, 0x11); - afc = tda10021_readreg(state, 0x19); - if (verbose) { - /* AFC only valid when carrier has been recovered */ - printk(sync & 2 ? "DVB: TDA10021(%d): AFC (%d) %dHz\n" : - "DVB: TDA10021(%d): [AFC (%d) %dHz]\n", - state->frontend.dvb->num, afc, - -((s32)p->u.qam.symbol_rate * afc) >> 10); - } - - p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF; - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; - - p->u.qam.fec_inner = FEC_NONE; - p->frequency = ((p->frequency + 31250) / 62500) * 62500; - - if (sync & 2) - p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; - - return 0; -} - -static int tda10021_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10021_state* state = fe->demodulator_priv; - - if (enable) { - lock_tuner(state); - } else { - unlock_tuner(state); - } - return 0; -} - -static int tda10021_sleep(struct dvb_frontend* fe) -{ - struct tda10021_state* state = fe->demodulator_priv; - - _tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */ - _tda10021_writereg (state, 0x00, 0x80); /* standby */ - - return 0; -} - -static void tda10021_release(struct dvb_frontend* fe) -{ - struct tda10021_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda10021_ops; - -struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, - u8 pwm) -{ - struct tda10021_state* state = NULL; - u8 id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->pwm = pwm; - state->reg0 = tda10021_inittab[0]; - - /* check if the demod is there */ - id = tda10021_readreg(state, 0x1a); - if ((id & 0xf0) != 0x70) goto error; - - printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n", - state->config->demod_address, id); - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops tda10021_ops = { - - .info = { - .name = "Philips TDA10021 DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ - .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ - #if 0 - .frequency_tolerance = ???, - .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ - #endif - .caps = 0x400 | //FE_CAN_QAM_4 - FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = tda10021_release, - - .init = tda10021_init, - .sleep = tda10021_sleep, - .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, - - .set_frontend = tda10021_set_parameters, - .get_frontend = tda10021_get_frontend, - - .read_status = tda10021_read_status, - .read_ber = tda10021_read_ber, - .read_signal_strength = tda10021_read_signal_strength, - .read_snr = tda10021_read_snr, - .read_ucblocks = tda10021_read_ucblocks, -}; - -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting"); - -MODULE_DESCRIPTION("Philips TDA10021 DVB-C demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10021_attach); diff --git a/drivers/media/dvb/frontends/tda10023.c b/drivers/media/dvb/frontends/tda10023.c deleted file mode 100644 index a3c34eecdee..00000000000 --- a/drivers/media/dvb/frontends/tda10023.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - TDA10023 - DVB-C decoder - (as used in Philips CU1216-3 NIM and the Reelbox DVB-C tuner card) - - Copyright (C) 2005 Georg Acher, BayCom GmbH (acher at baycom dot de) - Copyright (c) 2006 Hartmut Birr (e9hack at gmail dot com) - - Remotely based on tda10021.c - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> - Support for TDA10021 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "tda1002x.h" - -#define REG0_INIT_VAL 0x23 - -struct tda10023_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda10023_config *config; - struct dvb_frontend frontend; - - u8 pwm; - u8 reg0; - - /* clock settings */ - u32 xtal; - u8 pll_m; - u8 pll_p; - u8 pll_n; - u32 sysclk; -}; - -#define dprintk(x...) - -static int verbose; - -static u8 tda10023_readreg (struct tda10023_state* state, u8 reg) -{ - u8 b0 [] = { reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - int ret; - - ret = i2c_transfer (state->i2c, msg, 2); - if (ret != 2) { - int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s: readreg error " - "(reg == 0x%02x, ret == %i)\n", - num, __func__, reg, ret); - } - return b1[0]; -} - -static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int ret; - - ret = i2c_transfer (state->i2c, &msg, 1); - if (ret != 1) { - int num = state->frontend.dvb ? state->frontend.dvb->num : -1; - printk(KERN_ERR "DVB: TDA10023(%d): %s, writereg error " - "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", - num, __func__, reg, data, ret); - } - return (ret != 1) ? -EREMOTEIO : 0; -} - - -static int tda10023_writebit (struct tda10023_state* state, u8 reg, u8 mask,u8 data) -{ - if (mask==0xff) - return tda10023_writereg(state, reg, data); - else { - u8 val; - val=tda10023_readreg(state,reg); - val&=~mask; - val|=(data&mask); - return tda10023_writereg(state, reg, val); - } -} - -static void tda10023_writetab(struct tda10023_state* state, u8* tab) -{ - u8 r,m,v; - while (1) { - r=*tab++; - m=*tab++; - v=*tab++; - if (r==0xff) { - if (m==0xff) - break; - else - msleep(m); - } - else - tda10023_writebit(state,r,m,v); - } -} - -//get access to tuner -static int lock_tuner(struct tda10023_state* state) -{ - u8 buf[2] = { 0x0f, 0xc0 }; - struct i2c_msg msg = {.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg, 1) != 1) - { - printk("tda10023: lock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -//release access from tuner -static int unlock_tuner(struct tda10023_state* state) -{ - u8 buf[2] = { 0x0f, 0x40 }; - struct i2c_msg msg_post={.addr=state->config->demod_address, .flags=0, .buf=buf, .len=2}; - - if(i2c_transfer(state->i2c, &msg_post, 1) != 1) - { - printk("tda10023: unlock tuner fails\n"); - return -EREMOTEIO; - } - return 0; -} - -static int tda10023_setup_reg0 (struct tda10023_state* state, u8 reg0) -{ - reg0 |= state->reg0 & 0x63; - - tda10023_writereg (state, 0x00, reg0 & 0xfe); - tda10023_writereg (state, 0x00, reg0 | 0x01); - - state->reg0 = reg0; - return 0; -} - -static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr) -{ - s32 BDR; - s32 BDRI; - s16 SFIL=0; - u16 NDEC = 0; - - /* avoid floating point operations multiplying syscloc and divider - by 10 */ - u32 sysclk_x_10 = state->sysclk * 10; - - if (sr < (u32)(sysclk_x_10/984)) { - NDEC=3; - SFIL=1; - } else if (sr < (u32)(sysclk_x_10/640)) { - NDEC=3; - SFIL=0; - } else if (sr < (u32)(sysclk_x_10/492)) { - NDEC=2; - SFIL=1; - } else if (sr < (u32)(sysclk_x_10/320)) { - NDEC=2; - SFIL=0; - } else if (sr < (u32)(sysclk_x_10/246)) { - NDEC=1; - SFIL=1; - } else if (sr < (u32)(sysclk_x_10/160)) { - NDEC=1; - SFIL=0; - } else if (sr < (u32)(sysclk_x_10/123)) { - NDEC=0; - SFIL=1; - } - - BDRI = (state->sysclk)*16; - BDRI>>=NDEC; - BDRI +=sr/2; - BDRI /=sr; - - if (BDRI>255) - BDRI=255; - - { - u64 BDRX; - - BDRX=1<<(24+NDEC); - BDRX*=sr; - do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */ - - BDR=(s32)BDRX; - } - dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n", - sr, BDR, BDRI, NDEC); - tda10023_writebit (state, 0x03, 0xc0, NDEC<<6); - tda10023_writereg (state, 0x0a, BDR&255); - tda10023_writereg (state, 0x0b, (BDR>>8)&255); - tda10023_writereg (state, 0x0c, (BDR>>16)&31); - tda10023_writereg (state, 0x0d, BDRI); - tda10023_writereg (state, 0x3d, (SFIL<<7)); - return 0; -} - -static int tda10023_init (struct dvb_frontend *fe) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 tda10023_inittab[] = { -/* reg mask val */ -/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */ -/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */ -/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ - /* PLL1 */ -/* 012 */ 0x28, 0xff, (state->pll_m-1), - /* PLL2 */ -/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1), - /* GPR FSAMPLING=1 */ -/* 018 */ 0x00, 0xff, REG0_INIT_VAL, -/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */ -/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 027 */ 0x1f, 0xff, 0x00, /* RESET */ -/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */ -/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */ - -/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */ -/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */ -/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 - PPWMTUN=0 PPWMIF=0 */ -/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */ -/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */ -/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */ -/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */ -/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */ -/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */ -/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */ -/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */ -/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */ -/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */ -/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */ -/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */ -/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */ -/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */ -/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */ -/* 093 */ 0x12, 0xff, TDA10023_OUTPUT_MODE_PARALLEL_B, /* - INTP1 POCLKP=1 FEL=1 MFS=0 */ -/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */ -/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */ -/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */ -/* 105 */ 0xc4, 0xff, 0x00, -/* 108 */ 0xc3, 0x30, 0x00, -/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */ -/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */ -/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */ -/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */ -/* 123 */ 0xff, 0xff, 0xff -}; - dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num); - - /* override default values if set in config */ - if (state->config->deltaf) { - tda10023_inittab[80] = (state->config->deltaf & 0xff); - tda10023_inittab[83] = (state->config->deltaf >> 8); - } - - if (state->config->output_mode) - tda10023_inittab[95] = state->config->output_mode; - - tda10023_writetab(state, tda10023_inittab); - - return 0; -} - -static int tda10023_set_parameters (struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10023_state* state = fe->demodulator_priv; - - static int qamvals[6][6] = { - // QAM LOCKTHR MSETH AREF AGCREFNYQ ERAGCNYQ_THD - { (5<<2), 0x78, 0x8c, 0x96, 0x78, 0x4c }, // 4 QAM - { (0<<2), 0x87, 0xa2, 0x91, 0x8c, 0x57 }, // 16 QAM - { (1<<2), 0x64, 0x74, 0x96, 0x8c, 0x57 }, // 32 QAM - { (2<<2), 0x46, 0x43, 0x6a, 0x6a, 0x44 }, // 64 QAM - { (3<<2), 0x36, 0x34, 0x7e, 0x78, 0x4c }, // 128 QAM - { (4<<2), 0x26, 0x23, 0x6c, 0x5c, 0x3c }, // 256 QAM - }; - - int qam = p->u.qam.modulation; - - if (qam < 0 || qam > 5) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - tda10023_set_symbolrate (state, p->u.qam.symbol_rate); - tda10023_writereg (state, 0x05, qamvals[qam][1]); - tda10023_writereg (state, 0x08, qamvals[qam][2]); - tda10023_writereg (state, 0x09, qamvals[qam][3]); - tda10023_writereg (state, 0xb4, qamvals[qam][4]); - tda10023_writereg (state, 0xb6, qamvals[qam][5]); - -// tda10023_writereg (state, 0x04, (p->inversion?0x12:0x32)); -// tda10023_writebit (state, 0x04, 0x60, (p->inversion?0:0x20)); - tda10023_writebit (state, 0x04, 0x40, 0x40); - tda10023_setup_reg0 (state, qamvals[qam][0]); - - return 0; -} - -static int tda10023_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct tda10023_state* state = fe->demodulator_priv; - int sync; - - *status = 0; - - //0x11[1] == CARLOCK -> Carrier locked - //0x11[2] == FSYNC -> Frame synchronisation - //0x11[3] == FEL -> Front End locked - //0x11[6] == NODVB -> DVB Mode Information - sync = tda10023_readreg (state, 0x11); - - if (sync & 2) - *status |= FE_HAS_SIGNAL|FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_SYNC|FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int tda10023_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 a,b,c; - a=tda10023_readreg(state, 0x14); - b=tda10023_readreg(state, 0x15); - c=tda10023_readreg(state, 0x16)&0xf; - tda10023_writebit (state, 0x10, 0xc0, 0x00); - - *ber = a | (b<<8)| (c<<16); - return 0; -} - -static int tda10023_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 ifgain=tda10023_readreg(state, 0x2f); - - u16 gain = ((255-tda10023_readreg(state, 0x17))) + (255-ifgain)/16; - // Max raw value is about 0xb0 -> Normalize to >0xf0 after 0x90 - if (gain>0x90) - gain=gain+2*(gain-0x90); - if (gain>255) - gain=255; - - *strength = (gain<<8)|gain; - return 0; -} - -static int tda10023_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct tda10023_state* state = fe->demodulator_priv; - - u8 quality = ~tda10023_readreg(state, 0x18); - *snr = (quality << 8) | quality; - return 0; -} - -static int tda10023_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda10023_state* state = fe->demodulator_priv; - u8 a,b,c,d; - a= tda10023_readreg (state, 0x74); - b= tda10023_readreg (state, 0x75); - c= tda10023_readreg (state, 0x76); - d= tda10023_readreg (state, 0x77); - *ucblocks = a | (b<<8)|(c<<16)|(d<<24); - - tda10023_writebit (state, 0x10, 0x20,0x00); - tda10023_writebit (state, 0x10, 0x20,0x20); - tda10023_writebit (state, 0x13, 0x01, 0x00); - - return 0; -} - -static int tda10023_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda10023_state* state = fe->demodulator_priv; - int sync,inv; - s8 afc = 0; - - sync = tda10023_readreg(state, 0x11); - afc = tda10023_readreg(state, 0x19); - inv = tda10023_readreg(state, 0x04); - - if (verbose) { - /* AFC only valid when carrier has been recovered */ - printk(sync & 2 ? "DVB: TDA10023(%d): AFC (%d) %dHz\n" : - "DVB: TDA10023(%d): [AFC (%d) %dHz]\n", - state->frontend.dvb->num, afc, - -((s32)p->u.qam.symbol_rate * afc) >> 10); - } - - p->inversion = (inv&0x20?0:1); - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; - - p->u.qam.fec_inner = FEC_NONE; - p->frequency = ((p->frequency + 31250) / 62500) * 62500; - - if (sync & 2) - p->frequency -= ((s32)p->u.qam.symbol_rate * afc) >> 10; - - return 0; -} - -static int tda10023_sleep(struct dvb_frontend* fe) -{ - struct tda10023_state* state = fe->demodulator_priv; - - tda10023_writereg (state, 0x1b, 0x02); /* pdown ADC */ - tda10023_writereg (state, 0x00, 0x80); /* standby */ - - return 0; -} - -static int tda10023_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10023_state* state = fe->demodulator_priv; - - if (enable) { - lock_tuner(state); - } else { - unlock_tuner(state); - } - return 0; -} - -static void tda10023_release(struct dvb_frontend* fe) -{ - struct tda10023_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda10023_ops; - -struct dvb_frontend *tda10023_attach(const struct tda10023_config *config, - struct i2c_adapter *i2c, - u8 pwm) -{ - struct tda10023_state* state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* wakeup if in standby */ - tda10023_writereg (state, 0x00, 0x33); - /* check if the demod is there */ - if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops)); - state->pwm = pwm; - state->reg0 = REG0_INIT_VAL; - if (state->config->xtal) { - state->xtal = state->config->xtal; - state->pll_m = state->config->pll_m; - state->pll_p = state->config->pll_p; - state->pll_n = state->config->pll_n; - } else { - /* set default values if not defined in config */ - state->xtal = 28920000; - state->pll_m = 8; - state->pll_p = 4; - state->pll_n = 1; - } - - /* calc sysclk */ - state->sysclk = (state->xtal * state->pll_m / \ - (state->pll_n * state->pll_p)); - - state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64; - state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4; - - dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n", - __func__, state->xtal, state->pll_m, state->pll_p, - state->pll_n); - - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops tda10023_ops = { - - .info = { - .name = "Philips TDA10023 DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .symbol_rate_min = 0, /* set in tda10023_attach */ - .symbol_rate_max = 0, /* set in tda10023_attach */ - .caps = 0x400 | //FE_CAN_QAM_4 - FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | - FE_CAN_QAM_128 | FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = tda10023_release, - - .init = tda10023_init, - .sleep = tda10023_sleep, - .i2c_gate_ctrl = tda10023_i2c_gate_ctrl, - - .set_frontend = tda10023_set_parameters, - .get_frontend = tda10023_get_frontend, - - .read_status = tda10023_read_status, - .read_ber = tda10023_read_ber, - .read_signal_strength = tda10023_read_signal_strength, - .read_snr = tda10023_read_snr, - .read_ucblocks = tda10023_read_ucblocks, -}; - - -MODULE_DESCRIPTION("Philips TDA10023 DVB-C demodulator driver"); -MODULE_AUTHOR("Georg Acher, Hartmut Birr"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10023_attach); diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h deleted file mode 100644 index 04d19418bf2..00000000000 --- a/drivers/media/dvb/frontends/tda1002x.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - TDA10021/TDA10023 - Single Chip Cable Channel Receiver driver module - used on the the Siemens DVB-C cards - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2004 Markus Schulz <msc@antzsystem.de> - Support for TDA10021 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef TDA1002x_H -#define TDA1002x_H - -#include <linux/dvb/frontend.h> - -struct tda1002x_config { - /* the demodulator's i2c address */ - u8 demod_address; - u8 invert; -}; - -enum tda10023_output_mode { - TDA10023_OUTPUT_MODE_PARALLEL_A = 0xe0, - TDA10023_OUTPUT_MODE_PARALLEL_B = 0xa1, - TDA10023_OUTPUT_MODE_PARALLEL_C = 0xa0, - TDA10023_OUTPUT_MODE_SERIAL, /* TODO: not implemented */ -}; - -struct tda10023_config { - /* the demodulator's i2c address */ - u8 demod_address; - u8 invert; - - /* clock settings */ - u32 xtal; /* defaults: 28920000 */ - u8 pll_m; /* defaults: 8 */ - u8 pll_p; /* defaults: 4 */ - u8 pll_n; /* defaults: 1 */ - - /* MPEG2 TS output mode */ - u8 output_mode; - - /* input freq offset + baseband conversion type */ - u16 deltaf; -}; - -#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, u8 pwm); -#else -static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, - struct i2c_adapter* i2c, u8 pwm) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA10021 - -#if defined(CONFIG_DVB_TDA10023) || \ - (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE)) -extern struct dvb_frontend *tda10023_attach( - const struct tda10023_config *config, - struct i2c_adapter *i2c, u8 pwm); -#else -static inline struct dvb_frontend *tda10023_attach( - const struct tda10023_config *config, - struct i2c_adapter *i2c, u8 pwm) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA10023 - -#endif // TDA1002x_H diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c deleted file mode 100644 index 2a8bbcd44cd..00000000000 --- a/drivers/media/dvb/frontends/tda10048.c +++ /dev/null @@ -1,887 +0,0 @@ -/* - NXP TDA10048HN DVB OFDM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> -#include "dvb_frontend.h" -#include "dvb_math.h" -#include "tda10048.h" - -#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw" -#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878 - -/* Register name definitions */ -#define TDA10048_IDENTITY 0x00 -#define TDA10048_VERSION 0x01 -#define TDA10048_DSP_CODE_CPT 0x0C -#define TDA10048_DSP_CODE_IN 0x0E -#define TDA10048_IN_CONF1 0x10 -#define TDA10048_IN_CONF2 0x11 -#define TDA10048_IN_CONF3 0x12 -#define TDA10048_OUT_CONF1 0x14 -#define TDA10048_OUT_CONF2 0x15 -#define TDA10048_OUT_CONF3 0x16 -#define TDA10048_AUTO 0x18 -#define TDA10048_SYNC_STATUS 0x1A -#define TDA10048_CONF_C4_1 0x1E -#define TDA10048_CONF_C4_2 0x1F -#define TDA10048_CODE_IN_RAM 0x20 -#define TDA10048_CHANNEL_INFO_1_R 0x22 -#define TDA10048_CHANNEL_INFO_2_R 0x23 -#define TDA10048_CHANNEL_INFO1 0x24 -#define TDA10048_CHANNEL_INFO2 0x25 -#define TDA10048_TIME_ERROR_R 0x26 -#define TDA10048_TIME_ERROR 0x27 -#define TDA10048_FREQ_ERROR_LSB_R 0x28 -#define TDA10048_FREQ_ERROR_MSB_R 0x29 -#define TDA10048_FREQ_ERROR_LSB 0x2A -#define TDA10048_FREQ_ERROR_MSB 0x2B -#define TDA10048_IT_SEL 0x30 -#define TDA10048_IT_STAT 0x32 -#define TDA10048_DSP_AD_LSB 0x3C -#define TDA10048_DSP_AD_MSB 0x3D -#define TDA10048_DSP_REF_LSB 0x3E -#define TDA10048_DSP_REF_MSB 0x3F -#define TDA10048_CONF_TRISTATE1 0x44 -#define TDA10048_CONF_TRISTATE2 0x45 -#define TDA10048_CONF_POLARITY 0x46 -#define TDA10048_GPIO_SP_DS0 0x48 -#define TDA10048_GPIO_SP_DS1 0x49 -#define TDA10048_GPIO_SP_DS2 0x4A -#define TDA10048_GPIO_SP_DS3 0x4B -#define TDA10048_GPIO_OUT_SEL 0x4C -#define TDA10048_GPIO_SELECT 0x4D -#define TDA10048_IC_MODE 0x4E -#define TDA10048_CONF_XO 0x50 -#define TDA10048_CONF_PLL1 0x51 -#define TDA10048_CONF_PLL2 0x52 -#define TDA10048_CONF_PLL3 0x53 -#define TDA10048_CONF_ADC 0x54 -#define TDA10048_CONF_ADC_2 0x55 -#define TDA10048_CONF_C1_1 0x60 -#define TDA10048_CONF_C1_3 0x62 -#define TDA10048_AGC_CONF 0x70 -#define TDA10048_AGC_THRESHOLD_LSB 0x72 -#define TDA10048_AGC_THRESHOLD_MSB 0x73 -#define TDA10048_AGC_RENORM 0x74 -#define TDA10048_AGC_GAINS 0x76 -#define TDA10048_AGC_TUN_MIN 0x78 -#define TDA10048_AGC_TUN_MAX 0x79 -#define TDA10048_AGC_IF_MIN 0x7A -#define TDA10048_AGC_IF_MAX 0x7B -#define TDA10048_AGC_TUN_LEVEL 0x7E -#define TDA10048_AGC_IF_LEVEL 0x7F -#define TDA10048_DIG_AGC_LEVEL 0x81 -#define TDA10048_FREQ_PHY2_LSB 0x86 -#define TDA10048_FREQ_PHY2_MSB 0x87 -#define TDA10048_TIME_INVWREF_LSB 0x88 -#define TDA10048_TIME_INVWREF_MSB 0x89 -#define TDA10048_TIME_WREF_LSB 0x8A -#define TDA10048_TIME_WREF_MID1 0x8B -#define TDA10048_TIME_WREF_MID2 0x8C -#define TDA10048_TIME_WREF_MSB 0x8D -#define TDA10048_NP_OUT 0xA2 -#define TDA10048_CELL_ID_LSB 0xA4 -#define TDA10048_CELL_ID_MSB 0xA5 -#define TDA10048_EXTTPS_ODD 0xAA -#define TDA10048_EXTTPS_EVEN 0xAB -#define TDA10048_TPS_LENGTH 0xAC -#define TDA10048_FREE_REG_1 0xB2 -#define TDA10048_FREE_REG_2 0xB3 -#define TDA10048_CONF_C3_1 0xC0 -#define TDA10048_CYBER_CTRL 0xC2 -#define TDA10048_CBER_NMAX_LSB 0xC4 -#define TDA10048_CBER_NMAX_MSB 0xC5 -#define TDA10048_CBER_LSB 0xC6 -#define TDA10048_CBER_MSB 0xC7 -#define TDA10048_VBER_LSB 0xC8 -#define TDA10048_VBER_MID 0xC9 -#define TDA10048_VBER_MSB 0xCA -#define TDA10048_CYBER_LUT 0xCC -#define TDA10048_UNCOR_CTRL 0xCD -#define TDA10048_UNCOR_CPT_LSB 0xCE -#define TDA10048_UNCOR_CPT_MSB 0xCF -#define TDA10048_SOFT_IT_C3 0xD6 -#define TDA10048_CONF_TS2 0xE0 -#define TDA10048_CONF_TS1 0xE1 - -static unsigned int debug; - -#define dprintk(level, fmt, arg...)\ - do { if (debug >= level)\ - printk(KERN_DEBUG "tda10048: " fmt, ## arg);\ - } while (0) - -struct tda10048_state { - - struct i2c_adapter *i2c; - - /* configuration settings */ - const struct tda10048_config *config; - struct dvb_frontend frontend; - - int fwloaded; -}; - -static struct init_tab { - u8 reg; - u16 data; -} init_tab[] = { - { TDA10048_CONF_PLL1, 0x08 }, - { TDA10048_CONF_ADC_2, 0x00 }, - { TDA10048_CONF_C4_1, 0x00 }, - { TDA10048_CONF_PLL1, 0x0f }, - { TDA10048_CONF_PLL2, 0x0a }, - { TDA10048_CONF_PLL3, 0x43 }, - { TDA10048_FREQ_PHY2_LSB, 0x02 }, - { TDA10048_FREQ_PHY2_MSB, 0x0a }, - { TDA10048_TIME_WREF_LSB, 0xbd }, - { TDA10048_TIME_WREF_MID1, 0xe4 }, - { TDA10048_TIME_WREF_MID2, 0xa8 }, - { TDA10048_TIME_WREF_MSB, 0x02 }, - { TDA10048_TIME_INVWREF_LSB, 0x04 }, - { TDA10048_TIME_INVWREF_MSB, 0x06 }, - { TDA10048_CONF_C4_1, 0x00 }, - { TDA10048_CONF_C1_1, 0xa8 }, - { TDA10048_AGC_CONF, 0x16 }, - { TDA10048_CONF_C1_3, 0x0b }, - { TDA10048_AGC_TUN_MIN, 0x00 }, - { TDA10048_AGC_TUN_MAX, 0xff }, - { TDA10048_AGC_IF_MIN, 0x00 }, - { TDA10048_AGC_IF_MAX, 0xff }, - { TDA10048_AGC_THRESHOLD_MSB, 0x00 }, - { TDA10048_AGC_THRESHOLD_LSB, 0x70 }, - { TDA10048_CYBER_CTRL, 0x38 }, - { TDA10048_AGC_GAINS, 0x12 }, - { TDA10048_CONF_XO, 0x00 }, - { TDA10048_CONF_TS1, 0x07 }, - { TDA10048_IC_MODE, 0x00 }, - { TDA10048_CONF_TS2, 0xc0 }, - { TDA10048_CONF_TRISTATE1, 0x21 }, - { TDA10048_CONF_TRISTATE2, 0x00 }, - { TDA10048_CONF_POLARITY, 0x00 }, - { TDA10048_CONF_C4_2, 0x04 }, - { TDA10048_CONF_ADC, 0x60 }, - { TDA10048_CONF_ADC_2, 0x10 }, - { TDA10048_CONF_ADC, 0x60 }, - { TDA10048_CONF_ADC_2, 0x00 }, - { TDA10048_CONF_C1_1, 0xa8 }, - { TDA10048_UNCOR_CTRL, 0x00 }, - { TDA10048_CONF_C4_2, 0x04 }, -}; - -static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { - .addr = state->config->demod_address, - .flags = 0, .buf = buf, .len = 2 }; - - dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data); - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("%s: writereg error (ret == %i)\n", __func__, ret); - - return (ret != 1) ? -1 : 0; -} - -static u8 tda10048_readreg(struct tda10048_state *state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, - .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, - .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg); - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk(KERN_ERR "%s: readreg error (ret == %i)\n", - __func__, ret); - - return b1[0]; -} - -static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg, - const u8 *data, u16 len) -{ - int ret = -EREMOTEIO; - struct i2c_msg msg; - u8 *buf; - - dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len); - - buf = kmalloc(len + 1, GFP_KERNEL); - if (buf == NULL) { - ret = -ENOMEM; - goto error; - } - - *buf = reg; - memcpy(buf + 1, data, len); - - msg.addr = state->config->demod_address; - msg.flags = 0; - msg.buf = buf; - msg.len = len + 1; - - dprintk(2, "%s(): write len = %d\n", - __func__, msg.len); - - ret = i2c_transfer(state->i2c, &msg, 1); - if (ret != 1) { - printk(KERN_ERR "%s(): writereg error err %i\n", - __func__, ret); - ret = -EREMOTEIO; - } - -error: - kfree(buf); - - return ret; -} - -static int tda10048_firmware_upload(struct dvb_frontend *fe) -{ - struct tda10048_state *state = fe->demodulator_priv; - const struct firmware *fw; - int ret; - int pos = 0; - int cnt; - u8 wlen = state->config->fwbulkwritelen; - - if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50)) - wlen = TDA10048_BULKWRITE_200; - - /* request the firmware, this will block and timeout */ - printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n", - __func__, - TDA10048_DEFAULT_FIRMWARE); - - ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, - &state->i2c->dev); - if (ret) { - printk(KERN_ERR "%s: Upload failed. (file not found?)\n", - __func__); - return -EIO; - } else { - printk(KERN_INFO "%s: firmware read %Zu bytes.\n", - __func__, - fw->size); - ret = 0; - } - - if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) { - printk(KERN_ERR "%s: firmware incorrect size\n", __func__); - ret = -EIO; - } else { - printk(KERN_INFO "%s: firmware uploading\n", __func__); - - /* Soft reset */ - tda10048_writereg(state, TDA10048_CONF_TRISTATE1, - tda10048_readreg(state, TDA10048_CONF_TRISTATE1) - & 0xfe); - tda10048_writereg(state, TDA10048_CONF_TRISTATE1, - tda10048_readreg(state, TDA10048_CONF_TRISTATE1) - | 0x01); - - /* Put the demod into host download mode */ - tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9); - - /* Boot the DSP */ - tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08); - - /* Prepare for download */ - tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0); - - /* Download the firmware payload */ - while (pos < fw->size) { - - if ((fw->size - pos) > wlen) - cnt = wlen; - else - cnt = fw->size - pos; - - tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN, - &fw->data[pos], cnt); - - pos += cnt; - } - - ret = -EIO; - /* Wait up to 250ms for the DSP to boot */ - for (cnt = 0; cnt < 250 ; cnt += 10) { - - msleep(10); - - if (tda10048_readreg(state, TDA10048_SYNC_STATUS) - & 0x40) { - ret = 0; - break; - } - } - } - - release_firmware(fw); - - if (ret == 0) { - printk(KERN_INFO "%s: firmware uploaded\n", __func__); - state->fwloaded = 1; - } else - printk(KERN_ERR "%s: firmware upload failed\n", __func__); - - return ret; -} - -static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s(%d)\n", __func__, inversion); - - if (inversion == TDA10048_INVERSION_ON) - tda10048_writereg(state, TDA10048_CONF_C1_1, - tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20); - else - tda10048_writereg(state, TDA10048_CONF_C1_1, - tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf); - - return 0; -} - -/* Retrieve the demod settings */ -static int tda10048_get_tps(struct tda10048_state *state, - struct dvb_ofdm_parameters *p) -{ - u8 val; - - /* Make sure the TPS regs are valid */ - if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01)) - return -EAGAIN; - - val = tda10048_readreg(state, TDA10048_OUT_CONF2); - switch ((val & 0x60) >> 5) { - case 0: - p->constellation = QPSK; - break; - case 1: - p->constellation = QAM_16; - break; - case 2: - p->constellation = QAM_64; - break; - } - switch ((val & 0x18) >> 3) { - case 0: - p->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - p->hierarchy_information = HIERARCHY_1; - break; - case 2: - p->hierarchy_information = HIERARCHY_2; - break; - case 3: - p->hierarchy_information = HIERARCHY_4; - break; - } - switch (val & 0x07) { - case 0: - p->code_rate_HP = FEC_1_2; - break; - case 1: - p->code_rate_HP = FEC_2_3; - break; - case 2: - p->code_rate_HP = FEC_3_4; - break; - case 3: - p->code_rate_HP = FEC_5_6; - break; - case 4: - p->code_rate_HP = FEC_7_8; - break; - } - - val = tda10048_readreg(state, TDA10048_OUT_CONF3); - switch (val & 0x07) { - case 0: - p->code_rate_LP = FEC_1_2; - break; - case 1: - p->code_rate_LP = FEC_2_3; - break; - case 2: - p->code_rate_LP = FEC_3_4; - break; - case 3: - p->code_rate_LP = FEC_5_6; - break; - case 4: - p->code_rate_LP = FEC_7_8; - break; - } - - val = tda10048_readreg(state, TDA10048_OUT_CONF1); - switch ((val & 0x0c) >> 2) { - case 0: - p->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - p->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - p->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - p->guard_interval = GUARD_INTERVAL_1_4; - break; - } - switch (val & 0x02) { - case 0: - p->transmission_mode = TRANSMISSION_MODE_2K; - break; - case 1: - p->transmission_mode = TRANSMISSION_MODE_8K; - break; - } - - return 0; -} - -static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) -{ - struct tda10048_state *state = fe->demodulator_priv; - dprintk(1, "%s(%d)\n", __func__, enable); - - if (enable) - return tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02); - else - return tda10048_writereg(state, TDA10048_CONF_C4_1, - tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd); -} - -static int tda10048_output_mode(struct dvb_frontend *fe, int serial) -{ - struct tda10048_state *state = fe->demodulator_priv; - dprintk(1, "%s(%d)\n", __func__, serial); - - /* Ensure pins are out of tri-state */ - tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21); - tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00); - - if (serial) { - tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20); - tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0); - } else { - tda10048_writereg(state, TDA10048_IC_MODE, 0x00); - tda10048_writereg(state, TDA10048_CONF_TS2, 0x01); - } - - return 0; -} - -/* Talk to the demod, set the FEC, GUARD, QAM settings etc */ -/* TODO: Support manual tuning with specific params */ -static int tda10048_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency); - - if (fe->ops.tuner_ops.set_params) { - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - - fe->ops.tuner_ops.set_params(fe, p); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* Enable demod TPS auto detection and begin acquisition */ - tda10048_writereg(state, TDA10048_AUTO, 0x57); - - return 0; -} - -/* Establish sane defaults and load firmware. */ -static int tda10048_init(struct dvb_frontend *fe) -{ - struct tda10048_state *state = fe->demodulator_priv; - int ret = 0, i; - - dprintk(1, "%s()\n", __func__); - - /* Apply register defaults */ - for (i = 0; i < ARRAY_SIZE(init_tab); i++) - tda10048_writereg(state, init_tab[i].reg, init_tab[i].data); - - if (state->fwloaded == 0) - ret = tda10048_firmware_upload(fe); - - /* Set either serial or parallel */ - tda10048_output_mode(fe, state->config->output_mode); - - /* set inversion */ - tda10048_set_inversion(fe, state->config->inversion); - - /* Ensure we leave the gate closed */ - tda10048_i2c_gate_ctrl(fe, 0); - - return ret; -} - -static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct tda10048_state *state = fe->demodulator_priv; - u8 reg; - - *status = 0; - - reg = tda10048_readreg(state, TDA10048_SYNC_STATUS); - - dprintk(1, "%s() status =0x%02x\n", __func__, reg); - - if (reg & 0x02) - *status |= FE_HAS_CARRIER; - - if (reg & 0x04) - *status |= FE_HAS_SIGNAL; - - if (reg & 0x08) { - *status |= FE_HAS_LOCK; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_SYNC; - } - - return 0; -} - -static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s()\n", __func__); - - /* TODO: A reset may be required here */ - *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 | - tda10048_readreg(state, TDA10048_CBER_LSB); - - return 0; -} - -static int tda10048_read_signal_strength(struct dvb_frontend *fe, - u16 *signal_strength) -{ - struct tda10048_state *state = fe->demodulator_priv; - u8 v; - - dprintk(1, "%s()\n", __func__); - - *signal_strength = 65535; - - v = tda10048_readreg(state, TDA10048_NP_OUT); - if (v > 0) - *signal_strength -= (v << 8) | v; - - return 0; -} - -/* SNR lookup table */ -static struct snr_tab { - u8 val; - u8 data; -} snr_tab[] = { - { 0, 0 }, - { 1, 246 }, - { 2, 215 }, - { 3, 198 }, - { 4, 185 }, - { 5, 176 }, - { 6, 168 }, - { 7, 161 }, - { 8, 155 }, - { 9, 150 }, - { 10, 146 }, - { 11, 141 }, - { 12, 138 }, - { 13, 134 }, - { 14, 131 }, - { 15, 128 }, - { 16, 125 }, - { 17, 122 }, - { 18, 120 }, - { 19, 118 }, - { 20, 115 }, - { 21, 113 }, - { 22, 111 }, - { 23, 109 }, - { 24, 107 }, - { 25, 106 }, - { 26, 104 }, - { 27, 102 }, - { 28, 101 }, - { 29, 99 }, - { 30, 98 }, - { 31, 96 }, - { 32, 95 }, - { 33, 94 }, - { 34, 92 }, - { 35, 91 }, - { 36, 90 }, - { 37, 89 }, - { 38, 88 }, - { 39, 86 }, - { 40, 85 }, - { 41, 84 }, - { 42, 83 }, - { 43, 82 }, - { 44, 81 }, - { 45, 80 }, - { 46, 79 }, - { 47, 78 }, - { 48, 77 }, - { 49, 76 }, - { 50, 76 }, - { 51, 75 }, - { 52, 74 }, - { 53, 73 }, - { 54, 72 }, - { 56, 71 }, - { 57, 70 }, - { 58, 69 }, - { 60, 68 }, - { 61, 67 }, - { 63, 66 }, - { 64, 65 }, - { 66, 64 }, - { 67, 63 }, - { 68, 62 }, - { 69, 62 }, - { 70, 61 }, - { 72, 60 }, - { 74, 59 }, - { 75, 58 }, - { 77, 57 }, - { 79, 56 }, - { 81, 55 }, - { 83, 54 }, - { 85, 53 }, - { 87, 52 }, - { 89, 51 }, - { 91, 50 }, - { 93, 49 }, - { 95, 48 }, - { 97, 47 }, - { 100, 46 }, - { 102, 45 }, - { 104, 44 }, - { 107, 43 }, - { 109, 42 }, - { 112, 41 }, - { 114, 40 }, - { 117, 39 }, - { 120, 38 }, - { 123, 37 }, - { 125, 36 }, - { 128, 35 }, - { 131, 34 }, - { 134, 33 }, - { 138, 32 }, - { 141, 31 }, - { 144, 30 }, - { 147, 29 }, - { 151, 28 }, - { 154, 27 }, - { 158, 26 }, - { 162, 25 }, - { 165, 24 }, - { 169, 23 }, - { 173, 22 }, - { 177, 21 }, - { 181, 20 }, - { 186, 19 }, - { 190, 18 }, - { 194, 17 }, - { 199, 16 }, - { 204, 15 }, - { 208, 14 }, - { 213, 13 }, - { 218, 12 }, - { 223, 11 }, - { 229, 10 }, - { 234, 9 }, - { 239, 8 }, - { 245, 7 }, - { 251, 6 }, - { 255, 5 }, -}; - -static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct tda10048_state *state = fe->demodulator_priv; - u8 v; - int i, ret = -EINVAL; - - dprintk(1, "%s()\n", __func__); - - v = tda10048_readreg(state, TDA10048_NP_OUT); - for (i = 0; i < ARRAY_SIZE(snr_tab); i++) { - if (v <= snr_tab[i].val) { - *snr = snr_tab[i].data; - ret = 0; - break; - } - } - - return ret; -} - -static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s()\n", __func__); - - *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 | - tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB); - - return 0; -} - -static int tda10048_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct tda10048_state *state = fe->demodulator_priv; - - dprintk(1, "%s()\n", __func__); - - p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1) - & 0x20 ? INVERSION_ON : INVERSION_OFF; - - return tda10048_get_tps(state, &p->u.ofdm); -} - -static int tda10048_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - tune->min_delay_ms = 1000; - return 0; -} - -static void tda10048_release(struct dvb_frontend *fe) -{ - struct tda10048_state *state = fe->demodulator_priv; - dprintk(1, "%s()\n", __func__); - kfree(state); -} - -static struct dvb_frontend_ops tda10048_ops; - -struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, - struct i2c_adapter *i2c) -{ - struct tda10048_state *state = NULL; - - dprintk(1, "%s()\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->fwloaded = 0; - - /* check if the demod is present */ - if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10048_ops, - sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - /* Leave the gate closed */ - tda10048_i2c_gate_ctrl(&state->frontend, 0); - - return &state->frontend; - -error: - kfree(state); - return NULL; -} -EXPORT_SYMBOL(tda10048_attach); - -static struct dvb_frontend_ops tda10048_ops = { - - .info = { - .name = "NXP TDA10048HN DVB-T", - .type = FE_OFDM, - .frequency_min = 177000000, - .frequency_max = 858000000, - .frequency_stepsize = 166666, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER - }, - - .release = tda10048_release, - .init = tda10048_init, - .i2c_gate_ctrl = tda10048_i2c_gate_ctrl, - .set_frontend = tda10048_set_frontend, - .get_frontend = tda10048_get_frontend, - .get_tune_settings = tda10048_get_tune_settings, - .read_status = tda10048_read_status, - .read_ber = tda10048_read_ber, - .read_signal_strength = tda10048_read_signal_strength, - .read_snr = tda10048_read_snr, - .read_ucblocks = tda10048_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Enable verbose debug messages"); - -MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h deleted file mode 100644 index 0457b24601f..00000000000 --- a/drivers/media/dvb/frontends/tda10048.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - NXP TDA10048HN DVB OFDM demodulator driver - - Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef TDA10048_H -#define TDA10048_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -struct tda10048_config { - - /* the demodulator's i2c address */ - u8 demod_address; - - /* serial/parallel output */ -#define TDA10048_PARALLEL_OUTPUT 0 -#define TDA10048_SERIAL_OUTPUT 1 - u8 output_mode; - -#define TDA10048_BULKWRITE_200 200 -#define TDA10048_BULKWRITE_50 50 - u8 fwbulkwritelen; - - /* Spectral Inversion */ -#define TDA10048_INVERSION_OFF 0 -#define TDA10048_INVERSION_ON 1 - u8 inversion; -}; - -#if defined(CONFIG_DVB_TDA10048) || \ - (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE)) -extern struct dvb_frontend *tda10048_attach( - const struct tda10048_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend *tda10048_attach( - const struct tda10048_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_TDA10048 */ - -#endif /* TDA10048_H */ diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c deleted file mode 100644 index 1465ff77b0c..00000000000 --- a/drivers/media/dvb/frontends/tda1004x.c +++ /dev/null @@ -1,1362 +0,0 @@ - /* - Driver for Philips tda1004xh OFDM Demodulator - - (c) 2003, 2004 Andrew de Quincey & Robert Schlabbach - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ -/* - * This driver needs external firmware. Please use the commands - * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045", - * "<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to - * download/extract them, and then copy them to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). - */ -#define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" -#define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda1004x.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda1004x: " args); \ - } while (0) - -#define TDA1004X_CHIPID 0x00 -#define TDA1004X_AUTO 0x01 -#define TDA1004X_IN_CONF1 0x02 -#define TDA1004X_IN_CONF2 0x03 -#define TDA1004X_OUT_CONF1 0x04 -#define TDA1004X_OUT_CONF2 0x05 -#define TDA1004X_STATUS_CD 0x06 -#define TDA1004X_CONFC4 0x07 -#define TDA1004X_DSSPARE2 0x0C -#define TDA10045H_CODE_IN 0x0D -#define TDA10045H_FWPAGE 0x0E -#define TDA1004X_SCAN_CPT 0x10 -#define TDA1004X_DSP_CMD 0x11 -#define TDA1004X_DSP_ARG 0x12 -#define TDA1004X_DSP_DATA1 0x13 -#define TDA1004X_DSP_DATA2 0x14 -#define TDA1004X_CONFADC1 0x15 -#define TDA1004X_CONFC1 0x16 -#define TDA10045H_S_AGC 0x1a -#define TDA10046H_AGC_TUN_LEVEL 0x1a -#define TDA1004X_SNR 0x1c -#define TDA1004X_CONF_TS1 0x1e -#define TDA1004X_CONF_TS2 0x1f -#define TDA1004X_CBER_RESET 0x20 -#define TDA1004X_CBER_MSB 0x21 -#define TDA1004X_CBER_LSB 0x22 -#define TDA1004X_CVBER_LUT 0x23 -#define TDA1004X_VBER_MSB 0x24 -#define TDA1004X_VBER_MID 0x25 -#define TDA1004X_VBER_LSB 0x26 -#define TDA1004X_UNCOR 0x27 - -#define TDA10045H_CONFPLL_P 0x2D -#define TDA10045H_CONFPLL_M_MSB 0x2E -#define TDA10045H_CONFPLL_M_LSB 0x2F -#define TDA10045H_CONFPLL_N 0x30 - -#define TDA10046H_CONFPLL1 0x2D -#define TDA10046H_CONFPLL2 0x2F -#define TDA10046H_CONFPLL3 0x30 -#define TDA10046H_TIME_WREF1 0x31 -#define TDA10046H_TIME_WREF2 0x32 -#define TDA10046H_TIME_WREF3 0x33 -#define TDA10046H_TIME_WREF4 0x34 -#define TDA10046H_TIME_WREF5 0x35 - -#define TDA10045H_UNSURW_MSB 0x31 -#define TDA10045H_UNSURW_LSB 0x32 -#define TDA10045H_WREF_MSB 0x33 -#define TDA10045H_WREF_MID 0x34 -#define TDA10045H_WREF_LSB 0x35 -#define TDA10045H_MUXOUT 0x36 -#define TDA1004X_CONFADC2 0x37 - -#define TDA10045H_IOFFSET 0x38 - -#define TDA10046H_CONF_TRISTATE1 0x3B -#define TDA10046H_CONF_TRISTATE2 0x3C -#define TDA10046H_CONF_POLARITY 0x3D -#define TDA10046H_FREQ_OFFSET 0x3E -#define TDA10046H_GPIO_OUT_SEL 0x41 -#define TDA10046H_GPIO_SELECT 0x42 -#define TDA10046H_AGC_CONF 0x43 -#define TDA10046H_AGC_THR 0x44 -#define TDA10046H_AGC_RENORM 0x45 -#define TDA10046H_AGC_GAINS 0x46 -#define TDA10046H_AGC_TUN_MIN 0x47 -#define TDA10046H_AGC_TUN_MAX 0x48 -#define TDA10046H_AGC_IF_MIN 0x49 -#define TDA10046H_AGC_IF_MAX 0x4A - -#define TDA10046H_FREQ_PHY2_MSB 0x4D -#define TDA10046H_FREQ_PHY2_LSB 0x4E - -#define TDA10046H_CVBER_CTRL 0x4F -#define TDA10046H_AGC_IF_LEVEL 0x52 -#define TDA10046H_CODE_CPT 0x57 -#define TDA10046H_CODE_IN 0x58 - - -static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) -{ - int ret; - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; - - dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data); - - msg.addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", - __func__, reg, data, ret); - - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, - reg, data, ret); - return (ret != 1) ? -1 : 0; -} - -static int tda1004x_read_byte(struct tda1004x_state *state, int reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, - { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; - - dprintk("%s: reg=0x%x\n", __func__, reg); - - msg[0].addr = state->config->demod_address; - msg[1].addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, - ret); - return -1; - } - - dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__, - reg, b1[0], ret); - return b1[0]; -} - -static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data) -{ - int val; - dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg, - mask, data); - - // read a byte and check - val = tda1004x_read_byte(state, reg); - if (val < 0) - return val; - - // mask if off - val = val & ~mask; - val |= data & 0xff; - - // write it out again - return tda1004x_write_byteI(state, reg, val); -} - -static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned char *buf, int len) -{ - int i; - int result; - - dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len); - - result = 0; - for (i = 0; i < len; i++) { - result = tda1004x_write_byteI(state, reg + i, buf[i]); - if (result != 0) - break; - } - - return result; -} - -static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state) -{ - int result; - dprintk("%s\n", __func__); - - result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2); - msleep(20); - return result; -} - -static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state) -{ - dprintk("%s\n", __func__); - - return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0); -} - -static int tda10045h_set_bandwidth(struct tda1004x_state *state, - fe_bandwidth_t bandwidth) -{ - static u8 bandwidth_6mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x60, 0x1e, 0xa7, 0x45, 0x4f }; - static u8 bandwidth_7mhz[] = { 0x02, 0x00, 0x37, 0x00, 0x4a, 0x2f, 0x6d, 0x76, 0xdb }; - static u8 bandwidth_8mhz[] = { 0x02, 0x00, 0x3d, 0x00, 0x48, 0x17, 0x89, 0xc7, 0x14 }; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_6mhz, sizeof(bandwidth_6mhz)); - break; - - case BANDWIDTH_7_MHZ: - tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_7mhz, sizeof(bandwidth_7mhz)); - break; - - case BANDWIDTH_8_MHZ: - tda1004x_write_buf(state, TDA10045H_CONFPLL_P, bandwidth_8mhz, sizeof(bandwidth_8mhz)); - break; - - default: - return -EINVAL; - } - - tda1004x_write_byteI(state, TDA10045H_IOFFSET, 0); - - return 0; -} - -static int tda10046h_set_bandwidth(struct tda1004x_state *state, - fe_bandwidth_t bandwidth) -{ - static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; - static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; - static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d }; - - static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 }; - static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab }; - static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 }; - int tda10046_clk53m; - - if ((state->config->if_freq == TDA10046_FREQ_045) || - (state->config->if_freq == TDA10046_FREQ_052)) - tda10046_clk53m = 0; - else - tda10046_clk53m = 1; - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, - sizeof(bandwidth_6mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M, - sizeof(bandwidth_6mhz_48M)); - if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab); - } - break; - - case BANDWIDTH_7_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, - sizeof(bandwidth_7mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M, - sizeof(bandwidth_7mhz_48M)); - if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); - } - break; - - case BANDWIDTH_8_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, - sizeof(bandwidth_8mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M, - sizeof(bandwidth_8mhz_48M)); - if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55); - } - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int tda1004x_do_upload(struct tda1004x_state *state, - const unsigned char *mem, unsigned int len, - u8 dspCodeCounterReg, u8 dspCodeInReg) -{ - u8 buf[65]; - struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 }; - int tx_size; - int pos = 0; - - /* clear code counter */ - tda1004x_write_byteI(state, dspCodeCounterReg, 0); - fw_msg.addr = state->config->demod_address; - - buf[0] = dspCodeInReg; - while (pos != len) { - // work out how much to send this time - tx_size = len - pos; - if (tx_size > 0x10) - tx_size = 0x10; - - // send the chunk - memcpy(buf + 1, mem + pos, tx_size); - fw_msg.len = tx_size + 1; - if (i2c_transfer(state->i2c, &fw_msg, 1) != 1) { - printk(KERN_ERR "tda1004x: Error during firmware upload\n"); - return -EIO; - } - pos += tx_size; - - dprintk("%s: fw_pos=0x%x\n", __func__, pos); - } - // give the DSP a chance to settle 03/10/05 Hac - msleep(100); - - return 0; -} - -static int tda1004x_check_upload_ok(struct tda1004x_state *state) -{ - u8 data1, data2; - unsigned long timeout; - - if (state->demod_type == TDA1004X_DEMOD_TDA10046) { - timeout = jiffies + 2 * HZ; - while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) { - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n"); - break; - } - msleep(1); - } - } else - msleep(100); - - // check upload was OK - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); // we want to read from the DSP - tda1004x_write_byteI(state, TDA1004X_DSP_CMD, 0x67); - - data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); - data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); - if (data1 != 0x67 || data2 < 0x20 || data2 > 0x2e) { - printk(KERN_INFO "tda1004x: found firmware revision %x -- invalid\n", data2); - return -EIO; - } - printk(KERN_INFO "tda1004x: found firmware revision %x -- ok\n", data2); - return 0; -} - -static int tda10045_fwupload(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int ret; - const struct firmware *fw; - - /* don't re-upload unless necessary */ - if (tda1004x_check_upload_ok(state) == 0) - return 0; - - /* request the firmware, this will block until someone uploads it */ - printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); - ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); - if (ret) { - printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); - return ret; - } - - /* reset chip */ - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); - msleep(10); - - /* set parameters */ - tda10045h_set_bandwidth(state, BANDWIDTH_8_MHZ); - - ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10045H_FWPAGE, TDA10045H_CODE_IN); - release_firmware(fw); - if (ret) - return ret; - printk(KERN_INFO "tda1004x: firmware upload complete\n"); - - /* wait for DSP to initialise */ - /* DSPREADY doesn't seem to work on the TDA10045H */ - msleep(100); - - return tda1004x_check_upload_ok(state); -} - -static void tda10046_init_plls(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tda10046_clk53m; - - if ((state->config->if_freq == TDA10046_FREQ_045) || - (state->config->if_freq == TDA10046_FREQ_052)) - tda10046_clk53m = 0; - else - tda10046_clk53m = 1; - - tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); - if(tda10046_clk53m) { - printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n"); - tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8 - } else { - printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n"); - tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 - } - if (state->config->xtal_freq == TDA10046_XTAL_4M ) { - dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__); - tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 - } else { - dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__); - tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 - } - if(tda10046_clk53m) - tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67); - else - tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72); - /* Note clock frequency is handled implicitly */ - switch (state->config->if_freq) { - case TDA10046_FREQ_045: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); - break; - case TDA10046_FREQ_052: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7); - break; - case TDA10046_FREQ_3617: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59); - break; - case TDA10046_FREQ_3613: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); - break; - } - tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz - /* let the PLLs settle */ - msleep(120); -} - -static int tda10046_fwupload(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int ret; - const struct firmware *fw; - - /* reset + wake up chip */ - if (state->config->xtal_freq == TDA10046_XTAL_4M) { - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0); - } else { - dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__); - tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80); - } - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0); - /* set GPIO 1 and 3 */ - if (state->config->gpio_config != TDA10046_GPTRI) { - tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x33); - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, state->config->gpio_config &0x0f); - } - /* let the clocks recover from sleep */ - msleep(10); - - /* The PLLs need to be reprogrammed after sleep */ - tda10046_init_plls(fe); - tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0); - - /* don't re-upload unless necessary */ - if (tda1004x_check_upload_ok(state) == 0) - return 0; - - printk(KERN_INFO "tda1004x: trying to boot from eeprom\n"); - tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); - msleep(300); - /* don't re-upload unless necessary */ - if (tda1004x_check_upload_ok(state) == 0) - return 0; - - if (state->config->request_firmware != NULL) { - /* request the firmware, this will block until someone uploads it */ - printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); - ret = state->config->request_firmware(fe, &fw, TDA10046_DEFAULT_FIRMWARE); - if (ret) { - /* remain compatible to old bug: try to load with tda10045 image name */ - ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); - if (ret) { - printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); - return ret; - } else { - printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", - TDA10046_DEFAULT_FIRMWARE); - } - } - } else { - printk(KERN_ERR "tda1004x: no request function defined, can't upload from file\n"); - return -EIO; - } - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); // going to boot from HOST - ret = tda1004x_do_upload(state, fw->data, fw->size, TDA10046H_CODE_CPT, TDA10046H_CODE_IN); - release_firmware(fw); - return tda1004x_check_upload_ok(state); -} - -static int tda1004x_encode_fec(int fec) -{ - // convert known FEC values - switch (fec) { - case FEC_1_2: - return 0; - case FEC_2_3: - return 1; - case FEC_3_4: - return 2; - case FEC_5_6: - return 3; - case FEC_7_8: - return 4; - } - - // unsupported - return -EINVAL; -} - -static int tda1004x_decode_fec(int tdafec) -{ - // convert known FEC values - switch (tdafec) { - case 0: - return FEC_1_2; - case 1: - return FEC_2_3; - case 2: - return FEC_3_4; - case 3: - return FEC_5_6; - case 4: - return FEC_7_8; - } - - // unsupported - return -1; -} - -static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - if (len != 2) - return -EINVAL; - - return tda1004x_write_byteI(state, buf[0], buf[1]); -} - -static int tda10045_init(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - if (tda10045_fwupload(fe)) { - printk("tda1004x: firmware upload failed\n"); - return -EIO; - } - - tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0); // wake up the ADC - - // tda setup - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer - tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x40, 0); // set polarity of VAGC signal - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0x80); // enable pulse killer - tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); // enable auto offset - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0x0); // no frequency offset - tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 0); // setup MPEG2 TS interface - tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0); // setup MPEG2 TS interface - tda1004x_write_mask(state, TDA1004X_VBER_MSB, 0xe0, 0xa0); // 10^6 VBER measurement bits - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x10, 0); // VAGC polarity - tda1004x_write_byteI(state, TDA1004X_CONFADC1, 0x2e); - - tda1004x_write_mask(state, 0x1f, 0x01, state->config->invert_oclk); - - return 0; -} - -static int tda10046_init(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - dprintk("%s\n", __func__); - - if (tda10046_fwupload(fe)) { - printk("tda1004x: firmware upload failed\n"); - return -EIO; - } - - // tda setup - tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer - tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream - tda1004x_write_byteI(state, TDA1004X_CONFC1, 0x88); // enable pulse killer - - switch (state->config->agc_config) { - case TDA10046_AGC_DEFAULT: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities - break; - case TDA10046_AGC_IFO_AUTO_NEG: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities - break; - case TDA10046_AGC_IFO_AUTO_POS: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x00); // set AGC polarities - break; - case TDA10046_AGC_TDA827X: - tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup - tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold - tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities - break; - } - if (state->config->ts_mode == 0) { - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x40); - tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); - } else { - tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 0xc0, 0x80); - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x10, - state->config->invert_oclk << 4); - } - tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); - tda1004x_write_mask (state, TDA10046H_CONF_TRISTATE1, 0x3e, 0x38); // Turn IF AGC output on - tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } - tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values - tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } - tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } - tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1 - tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits - tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config - tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config - // tda1004x_write_mask(state, 0x50, 0x80, 0x80); // handle out of guard echoes - - return 0; -} - -static int tda1004x_set_fe(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fe_params) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - int inversion; - - dprintk("%s\n", __func__); - - if (state->demod_type == TDA1004X_DEMOD_TDA10046) { - // setup auto offset - tda1004x_write_mask(state, TDA1004X_AUTO, 0x10, 0x10); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x80, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0xC0, 0); - - // disable agc_conf[2] - tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 0); - } - - // set frequency - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - // Hardcoded to use auto as much as possible on the TDA10045 as it - // is very unreliable if AUTO mode is _not_ used. - if (state->demod_type == TDA1004X_DEMOD_TDA10045) { - fe_params->u.ofdm.code_rate_HP = FEC_AUTO; - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; - } - - // Set standard params.. or put them to auto - if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || - (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || - (fe_params->u.ofdm.constellation == QAM_AUTO) || - (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { - tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x3f, 0); // turn off FEC bits - } else { - tda1004x_write_mask(state, TDA1004X_AUTO, 1, 0); // disable auto - - // set HP FEC - tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); - if (tmp < 0) - return tmp; - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); - - // set LP FEC - tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); - if (tmp < 0) - return tmp; - tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); - - // set constellation - switch (fe_params->u.ofdm.constellation) { - case QPSK: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 0); - break; - - case QAM_16: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 1); - break; - - case QAM_64: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 3, 2); - break; - - default: - return -EINVAL; - } - - // set hierarchy - switch (fe_params->u.ofdm.hierarchy_information) { - case HIERARCHY_NONE: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0 << 5); - break; - - case HIERARCHY_1: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 1 << 5); - break; - - case HIERARCHY_2: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 2 << 5); - break; - - case HIERARCHY_4: - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 3 << 5); - break; - - default: - return -EINVAL; - } - } - - // set bandwidth - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); - break; - - case TDA1004X_DEMOD_TDA10046: - tda10046h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); - break; - } - - // set inversion - inversion = fe_params->inversion; - if (state->config->invert) - inversion = inversion ? INVERSION_OFF : INVERSION_ON; - switch (inversion) { - case INVERSION_OFF: - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); - break; - - case INVERSION_ON: - tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0x20); - break; - - default: - return -EINVAL; - } - - // set guard interval - switch (fe_params->u.ofdm.guard_interval) { - case GUARD_INTERVAL_1_32: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2); - break; - - case GUARD_INTERVAL_1_16: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 1 << 2); - break; - - case GUARD_INTERVAL_1_8: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 2 << 2); - break; - - case GUARD_INTERVAL_1_4: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 3 << 2); - break; - - case GUARD_INTERVAL_AUTO: - tda1004x_write_mask(state, TDA1004X_AUTO, 2, 2); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x0c, 0 << 2); - break; - - default: - return -EINVAL; - } - - // set transmission mode - switch (fe_params->u.ofdm.transmission_mode) { - case TRANSMISSION_MODE_2K: - tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0 << 4); - break; - - case TRANSMISSION_MODE_8K: - tda1004x_write_mask(state, TDA1004X_AUTO, 4, 0); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 1 << 4); - break; - - case TRANSMISSION_MODE_AUTO: - tda1004x_write_mask(state, TDA1004X_AUTO, 4, 4); - tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x10, 0); - break; - - default: - return -EINVAL; - } - - // start the lock - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); - tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); - break; - - case TDA1004X_DEMOD_TDA10046: - tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); - msleep(1); - tda1004x_write_mask(state, TDA10046H_AGC_CONF, 4, 1); - break; - } - - msleep(10); - - return 0; -} - -static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - dprintk("%s\n", __func__); - - // inversion status - fe_params->inversion = INVERSION_OFF; - if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) - fe_params->inversion = INVERSION_ON; - if (state->config->invert) - fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; - - // bandwidth - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { - case 0x14: - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - case 0xdb: - fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 0x4f: - fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - } - break; - case TDA1004X_DEMOD_TDA10046: - switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { - case 0x5c: - case 0x54: - fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; - break; - case 0x6a: - case 0x60: - fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; - break; - case 0x7b: - case 0x70: - fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; - break; - } - break; - } - - // FEC - fe_params->u.ofdm.code_rate_HP = - tda1004x_decode_fec(tda1004x_read_byte(state, TDA1004X_OUT_CONF2) & 7); - fe_params->u.ofdm.code_rate_LP = - tda1004x_decode_fec((tda1004x_read_byte(state, TDA1004X_OUT_CONF2) >> 3) & 7); - - // constellation - switch (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 3) { - case 0: - fe_params->u.ofdm.constellation = QPSK; - break; - case 1: - fe_params->u.ofdm.constellation = QAM_16; - break; - case 2: - fe_params->u.ofdm.constellation = QAM_64; - break; - } - - // transmission mode - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; - if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) - fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; - - // guard interval - switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { - case 0: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - fe_params->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; - break; - } - - // hierarchy - switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x60) >> 5) { - case 0: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_NONE; - break; - case 1: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_1; - break; - case 2: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_2; - break; - case 3: - fe_params->u.ofdm.hierarchy_information = HIERARCHY_4; - break; - } - - return 0; -} - -static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int status; - int cber; - int vber; - - dprintk("%s\n", __func__); - - // read status - status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); - if (status == -1) - return -EIO; - - // decode - *fe_status = 0; - if (status & 4) - *fe_status |= FE_HAS_SIGNAL; - if (status & 2) - *fe_status |= FE_HAS_CARRIER; - if (status & 8) - *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; - - // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi - // is getting anything valid - if (!(*fe_status & FE_HAS_VITERBI)) { - // read the CBER - cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); - if (cber == -1) - return -EIO; - status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); - if (status == -1) - return -EIO; - cber |= (status << 8); - // The address 0x20 should be read to cope with a TDA10046 bug - tda1004x_read_byte(state, TDA1004X_CBER_RESET); - - if (cber != 65535) - *fe_status |= FE_HAS_VITERBI; - } - - // if we DO have some valid VITERBI output, but don't already have SYNC - // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid. - if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { - // read the VBER - vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); - if (vber == -1) - return -EIO; - status = tda1004x_read_byte(state, TDA1004X_VBER_MID); - if (status == -1) - return -EIO; - vber |= (status << 8); - status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); - if (status == -1) - return -EIO; - vber |= (status & 0x0f) << 16; - // The CVBER_LUT should be read to cope with TDA10046 hardware bug - tda1004x_read_byte(state, TDA1004X_CVBER_LUT); - - // if RS has passed some valid TS packets, then we must be - // getting some SYNC bytes - if (vber < 16632) - *fe_status |= FE_HAS_SYNC; - } - - // success - dprintk("%s: fe_status=0x%x\n", __func__, *fe_status); - return 0; -} - -static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - int reg = 0; - - dprintk("%s\n", __func__); - - // determine the register to use - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - reg = TDA10045H_S_AGC; - break; - - case TDA1004X_DEMOD_TDA10046: - reg = TDA10046H_AGC_IF_LEVEL; - break; - } - - // read it - tmp = tda1004x_read_byte(state, reg); - if (tmp < 0) - return -EIO; - - *signal = (tmp << 8) | tmp; - dprintk("%s: signal=0x%x\n", __func__, *signal); - return 0; -} - -static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - - dprintk("%s\n", __func__); - - // read it - tmp = tda1004x_read_byte(state, TDA1004X_SNR); - if (tmp < 0) - return -EIO; - tmp = 255 - tmp; - - *snr = ((tmp << 8) | tmp); - dprintk("%s: snr=0x%x\n", __func__, *snr); - return 0; -} - -static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - int tmp2; - int counter; - - dprintk("%s\n", __func__); - - // read the UCBLOCKS and reset - counter = 0; - tmp = tda1004x_read_byte(state, TDA1004X_UNCOR); - if (tmp < 0) - return -EIO; - tmp &= 0x7f; - while (counter++ < 5) { - tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0); - tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0); - tda1004x_write_mask(state, TDA1004X_UNCOR, 0x80, 0); - - tmp2 = tda1004x_read_byte(state, TDA1004X_UNCOR); - if (tmp2 < 0) - return -EIO; - tmp2 &= 0x7f; - if ((tmp2 < tmp) || (tmp2 == 0)) - break; - } - - if (tmp != 0x7f) - *ucblocks = tmp; - else - *ucblocks = 0xffffffff; - - dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks); - return 0; -} - -static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int tmp; - - dprintk("%s\n", __func__); - - // read it in - tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); - if (tmp < 0) - return -EIO; - *ber = tmp << 1; - tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); - if (tmp < 0) - return -EIO; - *ber |= (tmp << 9); - // The address 0x20 should be read to cope with a TDA10046 bug - tda1004x_read_byte(state, TDA1004X_CBER_RESET); - - dprintk("%s: ber=0x%x\n", __func__, *ber); - return 0; -} - -static int tda1004x_sleep(struct dvb_frontend* fe) -{ - struct tda1004x_state* state = fe->demodulator_priv; - int gpio_conf; - - switch (state->demod_type) { - case TDA1004X_DEMOD_TDA10045: - tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10); - break; - - case TDA1004X_DEMOD_TDA10046: - /* set outputs to tristate */ - tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xff); - /* invert GPIO 1 and 3 if desired*/ - gpio_conf = state->config->gpio_config; - if (gpio_conf >= TDA10046_GP00_I) - tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0x0f, - (gpio_conf & 0x0f) ^ 0x0a); - - tda1004x_write_mask(state, TDA1004X_CONFADC2, 0xc0, 0xc0); - tda1004x_write_mask(state, TDA1004X_CONFC4, 1, 1); - break; - } - - return 0; -} - -static int tda1004x_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda1004x_state* state = fe->demodulator_priv; - - if (enable) { - return tda1004x_enable_tuner_i2c(state); - } else { - return tda1004x_disable_tuner_i2c(state); - } -} - -static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 800; - /* Drift compensation makes no sense for DVB-T */ - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void tda1004x_release(struct dvb_frontend* fe) -{ - struct tda1004x_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda10045_ops = { - .info = { - .name = "Philips TDA10045H DVB-T", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 166667, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO - }, - - .release = tda1004x_release, - - .init = tda10045_init, - .sleep = tda1004x_sleep, - .write = tda1004x_write, - .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, - - .set_frontend = tda1004x_set_fe, - .get_frontend = tda1004x_get_fe, - .get_tune_settings = tda1004x_get_tune_settings, - - .read_status = tda1004x_read_status, - .read_ber = tda1004x_read_ber, - .read_signal_strength = tda1004x_read_signal_strength, - .read_snr = tda1004x_read_snr, - .read_ucblocks = tda1004x_read_ucblocks, -}; - -struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - struct tda1004x_state *state; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10045 state\n"); - return NULL; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->demod_type = TDA1004X_DEMOD_TDA10045; - - /* check if the demod is there */ - id = tda1004x_read_byte(state, TDA1004X_CHIPID); - if (id < 0) { - printk(KERN_ERR "tda10045: chip is not answering. Giving up.\n"); - kfree(state); - return NULL; - } - - if (id != 0x25) { - printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); - kfree(state); - return NULL; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops tda10046_ops = { - .info = { - .name = "Philips TDA10046H DVB-T", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 166667, - .caps = - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO - }, - - .release = tda1004x_release, - - .init = tda10046_init, - .sleep = tda1004x_sleep, - .write = tda1004x_write, - .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, - - .set_frontend = tda1004x_set_fe, - .get_frontend = tda1004x_get_fe, - .get_tune_settings = tda1004x_get_tune_settings, - - .read_status = tda1004x_read_status, - .read_ber = tda1004x_read_ber, - .read_signal_strength = tda1004x_read_signal_strength, - .read_snr = tda1004x_read_snr, - .read_ucblocks = tda1004x_read_ucblocks, -}; - -struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - struct tda1004x_state *state; - int id; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); - if (!state) { - printk(KERN_ERR "Can't alocate memory for tda10046 state\n"); - return NULL; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->demod_type = TDA1004X_DEMOD_TDA10046; - - /* check if the demod is there */ - id = tda1004x_read_byte(state, TDA1004X_CHIPID); - if (id < 0) { - printk(KERN_ERR "tda10046: chip is not answering. Giving up.\n"); - kfree(state); - return NULL; - } - if (id != 0x46) { - printk(KERN_ERR "Invalid tda1004x ID = 0x%02x. Can't proceed\n", id); - kfree(state); - return NULL; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Philips TDA10045H & TDA10046H DVB-T Demodulator"); -MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10045_attach); -EXPORT_SYMBOL(tda10046_attach); diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h deleted file mode 100644 index 4e27ffb0f14..00000000000 --- a/drivers/media/dvb/frontends/tda1004x.h +++ /dev/null @@ -1,149 +0,0 @@ - /* - Driver for Philips tda1004xh OFDM Frontend - - (c) 2004 Andrew de Quincey - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#ifndef TDA1004X_H -#define TDA1004X_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -enum tda10046_xtal { - TDA10046_XTAL_4M, - TDA10046_XTAL_16M, -}; - -enum tda10046_agc { - TDA10046_AGC_DEFAULT, /* original configuration */ - TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */ - TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */ - TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */ -}; - -/* Many (hybrid) boards use GPIO 1 and 3 - GPIO1 analog - dvb switch - GPIO3 firmware eeprom address switch -*/ -enum tda10046_gpio { - TDA10046_GPTRI = 0x00, /* All GPIOs tristate */ - TDA10046_GP00 = 0x40, /* GPIO3=0, GPIO1=0 */ - TDA10046_GP01 = 0x42, /* GPIO3=0, GPIO1=1 */ - TDA10046_GP10 = 0x48, /* GPIO3=1, GPIO1=0 */ - TDA10046_GP11 = 0x4a, /* GPIO3=1, GPIO1=1 */ - TDA10046_GP00_I = 0x80, /* GPIO3=0, GPIO1=0, invert in sleep mode*/ - TDA10046_GP01_I = 0x82, /* GPIO3=0, GPIO1=1, invert in sleep mode */ - TDA10046_GP10_I = 0x88, /* GPIO3=1, GPIO1=0, invert in sleep mode */ - TDA10046_GP11_I = 0x8a, /* GPIO3=1, GPIO1=1, invert in sleep mode */ -}; - -enum tda10046_if { - TDA10046_FREQ_3617, /* original config, 36,166 MHZ */ - TDA10046_FREQ_3613, /* 36,13 MHZ */ - TDA10046_FREQ_045, /* low IF, 4.0, 4.5, or 5.0 MHZ */ - TDA10046_FREQ_052, /* low IF, 5.1667 MHZ for tda9889 */ -}; - -enum tda10046_tsout { - TDA10046_TS_PARALLEL = 0x00, /* parallel transport stream, default */ - TDA10046_TS_SERIAL = 0x01, /* serial transport stream */ -}; - -struct tda1004x_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* does the "inversion" need inverted? */ - u8 invert; - - /* Does the OCLK signal need inverted? */ - u8 invert_oclk; - - /* parallel or serial transport stream */ - enum tda10046_tsout ts_mode; - - /* Xtal frequency, 4 or 16MHz*/ - enum tda10046_xtal xtal_freq; - - /* IF frequency */ - enum tda10046_if if_freq; - - /* AGC configuration */ - enum tda10046_agc agc_config; - - /* setting of GPIO1 and 3 */ - enum tda10046_gpio gpio_config; - - /* slave address and configuration of the tuner */ - u8 tuner_address; - u8 antenna_switch; - - /* if the board uses another I2c Bridge (tda8290), its address */ - u8 i2c_gate; - - /* request firmware for device */ - int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); -}; - -enum tda1004x_demod { - TDA1004X_DEMOD_TDA10045, - TDA1004X_DEMOD_TDA10046, -}; - -struct tda1004x_state { - struct i2c_adapter* i2c; - const struct tda1004x_config* config; - struct dvb_frontend frontend; - - /* private demod data */ - enum tda1004x_demod demod_type; -}; - -#if defined(CONFIG_DVB_TDA1004X) || (defined(CONFIG_DVB_TDA1004X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c); - -extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA1004X - -static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) { - int r = 0; - u8 buf[] = {reg, val}; - if (fe->ops.write) - r = fe->ops.write(fe, buf, 2); - return r; -} - -#endif // TDA1004X_H diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c deleted file mode 100644 index a17ce3c4ad8..00000000000 --- a/drivers/media/dvb/frontends/tda10086.c +++ /dev/null @@ -1,775 +0,0 @@ - /* - Driver for Philips tda10086 DVBS Demodulator - - (c) 2006 Andrew de Quincey - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/jiffies.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include "dvb_frontend.h" -#include "tda10086.h" - -#define SACLK 96000000 - -struct tda10086_state { - struct i2c_adapter* i2c; - const struct tda10086_config* config; - struct dvb_frontend frontend; - - /* private demod data */ - u32 frequency; - u32 symbol_rate; - bool has_lock; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda10086: " args); \ - } while (0) - -static int tda10086_write_byte(struct tda10086_state *state, int reg, int data) -{ - int ret; - u8 b0[] = { reg, data }; - struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 }; - - msg.addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", - __func__, reg, data, ret); - - return (ret != 1) ? ret : 0; -} - -static int tda10086_read_byte(struct tda10086_state *state, int reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, - { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; - - msg[0].addr = state->config->demod_address; - msg[1].addr = state->config->demod_address; - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, - ret); - return ret; - } - - return b1[0]; -} - -static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data) -{ - int val; - - /* read a byte and check */ - val = tda10086_read_byte(state, reg); - if (val < 0) - return val; - - /* mask if off */ - val = val & ~mask; - val |= data & 0xff; - - /* write it out again */ - return tda10086_write_byte(state, reg, val); -} - -static int tda10086_init(struct dvb_frontend* fe) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - /* reset */ - tda10086_write_byte(state, 0x00, 0x00); - msleep(10); - - /* misc setup */ - tda10086_write_byte(state, 0x01, 0x94); - tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */ - tda10086_write_byte(state, 0x03, 0xe4); - tda10086_write_byte(state, 0x04, 0x43); - tda10086_write_byte(state, 0x0c, 0x0c); - tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */ - tda10086_write_byte(state, 0x20, 0x89); /* misc */ - tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */ - tda10086_write_byte(state, 0x32, 0x00); /* irq off */ - tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */ - - /* setup PLL (this assumes SACLK = 96MHz) */ - tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */ - if (state->config->xtal_freq == TDA10086_XTAL_16M) { - tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */ - tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */ - } else { - tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */ - tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */ - } - tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */ - - /* setup TS interface */ - tda10086_write_byte(state, 0x11, 0x81); - tda10086_write_byte(state, 0x12, 0x81); - tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */ - tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */ - tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */ - tda10086_write_byte(state, 0x10, 0x2a); - - /* setup ADC */ - tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */ - tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */ - - /* setup AGC */ - tda10086_write_byte(state, 0x05, 0x0B); - tda10086_write_byte(state, 0x37, 0x63); - tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */ - tda10086_write_byte(state, 0x40, 0x64); - tda10086_write_byte(state, 0x41, 0x4f); - tda10086_write_byte(state, 0x42, 0x43); - - /* setup viterbi */ - tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */ - - /* setup carrier recovery */ - tda10086_write_byte(state, 0x3d, 0x80); - - /* setup SEC */ - tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */ - tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); - tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); - - return 0; -} - -static void tda10086_diseqc_wait(struct tda10086_state *state) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(200); - while (!(tda10086_read_byte(state, 0x50) & 0x01)) { - if(time_after(jiffies, timeout)) { - printk("%s: diseqc queue not ready, command may be lost.\n", __func__); - break; - } - msleep(10); - } -} - -static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - - switch (tone) { - case SEC_TONE_OFF: - tda10086_write_byte(state, 0x36, t22k_off); - break; - - case SEC_TONE_ON: - tda10086_write_byte(state, 0x36, 0x01 + t22k_off); - break; - } - - return 0; -} - -static int tda10086_send_master_cmd (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct tda10086_state* state = fe->demodulator_priv; - int i; - u8 oldval; - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - - if (cmd->msg_len > 6) - return -EINVAL; - oldval = tda10086_read_byte(state, 0x36); - - for(i=0; i< cmd->msg_len; i++) { - tda10086_write_byte(state, 0x48+i, cmd->msg[i]); - } - tda10086_write_byte(state, 0x36, (0x08 + t22k_off) - | ((cmd->msg_len - 1) << 4)); - - tda10086_diseqc_wait(state); - - tda10086_write_byte(state, 0x36, oldval); - - return 0; -} - -static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 oldval = tda10086_read_byte(state, 0x36); - u8 t22k_off = 0x80; - - dprintk ("%s\n", __func__); - - if (state->config->diseqc_tone) - t22k_off = 0; - - switch(minicmd) { - case SEC_MINI_A: - tda10086_write_byte(state, 0x36, 0x04 + t22k_off); - break; - - case SEC_MINI_B: - tda10086_write_byte(state, 0x36, 0x06 + t22k_off); - break; - } - - tda10086_diseqc_wait(state); - - tda10086_write_byte(state, 0x36, oldval); - - return 0; -} - -static int tda10086_set_inversion(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) -{ - u8 invval = 0x80; - - dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert); - - switch(fe_params->inversion) { - case INVERSION_OFF: - if (state->config->invert) - invval = 0x40; - break; - case INVERSION_ON: - if (!state->config->invert) - invval = 0x40; - break; - case INVERSION_AUTO: - invval = 0x00; - break; - } - tda10086_write_mask(state, 0x0c, 0xc0, invval); - - return 0; -} - -static int tda10086_set_symbol_rate(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) -{ - u8 dfn = 0; - u8 afs = 0; - u8 byp = 0; - u8 reg37 = 0x43; - u8 reg42 = 0x43; - u64 big; - u32 tmp; - u32 bdr; - u32 bdri; - u32 symbol_rate = fe_params->u.qpsk.symbol_rate; - - dprintk ("%s %i\n", __func__, symbol_rate); - - /* setup the decimation and anti-aliasing filters.. */ - if (symbol_rate < (u32) (SACLK * 0.0137)) { - dfn=4; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.0208)) { - dfn=4; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.0270)) { - dfn=3; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.0416)) { - dfn=3; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.0550)) { - dfn=2; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.0833)) { - dfn=2; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.1100)) { - dfn=1; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.1666)) { - dfn=1; - afs=0; - } else if (symbol_rate < (u32) (SACLK * 0.2200)) { - dfn=0; - afs=1; - } else if (symbol_rate < (u32) (SACLK * 0.3333)) { - dfn=0; - afs=0; - } else { - reg37 = 0x63; - reg42 = 0x4f; - byp=1; - } - - /* calculate BDR */ - big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn); - big += ((SACLK/1000ULL)-1ULL); - do_div(big, (SACLK/1000ULL)); - bdr = big & 0xfffff; - - /* calculate BDRI */ - tmp = (1<<dfn)*(symbol_rate/1000); - bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp; - - tda10086_write_byte(state, 0x21, (afs << 7) | dfn); - tda10086_write_mask(state, 0x20, 0x08, byp << 3); - tda10086_write_byte(state, 0x06, bdr); - tda10086_write_byte(state, 0x07, bdr >> 8); - tda10086_write_byte(state, 0x08, bdr >> 16); - tda10086_write_byte(state, 0x09, bdri); - tda10086_write_byte(state, 0x37, reg37); - tda10086_write_byte(state, 0x42, reg42); - - return 0; -} - -static int tda10086_set_fec(struct tda10086_state *state, - struct dvb_frontend_parameters *fe_params) -{ - u8 fecval; - - dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner); - - switch(fe_params->u.qpsk.fec_inner) { - case FEC_1_2: - fecval = 0x00; - break; - case FEC_2_3: - fecval = 0x01; - break; - case FEC_3_4: - fecval = 0x02; - break; - case FEC_4_5: - fecval = 0x03; - break; - case FEC_5_6: - fecval = 0x04; - break; - case FEC_6_7: - fecval = 0x05; - break; - case FEC_7_8: - fecval = 0x06; - break; - case FEC_8_9: - fecval = 0x07; - break; - case FEC_AUTO: - fecval = 0x08; - break; - default: - return -1; - } - tda10086_write_byte(state, 0x0d, fecval); - - return 0; -} - -static int tda10086_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters *fe_params) -{ - struct tda10086_state *state = fe->demodulator_priv; - int ret; - u32 freq = 0; - int freqoff; - - dprintk ("%s\n", __func__); - - /* modify parameters for tuning */ - tda10086_write_byte(state, 0x02, 0x35); - state->has_lock = false; - - /* set params */ - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, fe_params); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (fe->ops.tuner_ops.get_frequency) - fe->ops.tuner_ops.get_frequency(fe, &freq); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - - /* calcluate the frequency offset (in *Hz* not kHz) */ - freqoff = fe_params->frequency - freq; - freqoff = ((1<<16) * freqoff) / (SACLK/1000); - tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f)); - tda10086_write_byte(state, 0x3e, freqoff); - - if ((ret = tda10086_set_inversion(state, fe_params)) < 0) - return ret; - if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0) - return ret; - if ((ret = tda10086_set_fec(state, fe_params)) < 0) - return ret; - - /* soft reset + disable TS output until lock */ - tda10086_write_mask(state, 0x10, 0x40, 0x40); - tda10086_write_mask(state, 0x00, 0x01, 0x00); - - state->symbol_rate = fe_params->u.qpsk.symbol_rate; - state->frequency = fe_params->frequency; - return 0; -} - -static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 val; - int tmp; - u64 tmp64; - - dprintk ("%s\n", __func__); - - /* check for invalid symbol rate */ - if (fe_params->u.qpsk.symbol_rate < 500000) - return -EINVAL; - - /* calculate the updated frequency (note: we convert from Hz->kHz) */ - tmp64 = tda10086_read_byte(state, 0x52); - tmp64 |= (tda10086_read_byte(state, 0x51) << 8); - if (tmp64 & 0x8000) - tmp64 |= 0xffffffffffff0000ULL; - tmp64 = (tmp64 * (SACLK/1000ULL)); - do_div(tmp64, (1ULL<<15) * (1ULL<<1)); - fe_params->frequency = (int) state->frequency + (int) tmp64; - - /* the inversion */ - val = tda10086_read_byte(state, 0x0c); - if (val & 0x80) { - switch(val & 0x40) { - case 0x00: - fe_params->inversion = INVERSION_OFF; - if (state->config->invert) - fe_params->inversion = INVERSION_ON; - break; - default: - fe_params->inversion = INVERSION_ON; - if (state->config->invert) - fe_params->inversion = INVERSION_OFF; - break; - } - } else { - tda10086_read_byte(state, 0x0f); - switch(val & 0x02) { - case 0x00: - fe_params->inversion = INVERSION_OFF; - if (state->config->invert) - fe_params->inversion = INVERSION_ON; - break; - default: - fe_params->inversion = INVERSION_ON; - if (state->config->invert) - fe_params->inversion = INVERSION_OFF; - break; - } - } - - /* calculate the updated symbol rate */ - tmp = tda10086_read_byte(state, 0x1d); - if (tmp & 0x80) - tmp |= 0xffffff00; - tmp = (tmp * 480 * (1<<1)) / 128; - tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000); - fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp; - - /* the FEC */ - val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4; - switch(val) { - case 0x00: - fe_params->u.qpsk.fec_inner = FEC_1_2; - break; - case 0x01: - fe_params->u.qpsk.fec_inner = FEC_2_3; - break; - case 0x02: - fe_params->u.qpsk.fec_inner = FEC_3_4; - break; - case 0x03: - fe_params->u.qpsk.fec_inner = FEC_4_5; - break; - case 0x04: - fe_params->u.qpsk.fec_inner = FEC_5_6; - break; - case 0x05: - fe_params->u.qpsk.fec_inner = FEC_6_7; - break; - case 0x06: - fe_params->u.qpsk.fec_inner = FEC_7_8; - break; - case 0x07: - fe_params->u.qpsk.fec_inner = FEC_8_9; - break; - } - - return 0; -} - -static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 val; - - dprintk ("%s\n", __func__); - - val = tda10086_read_byte(state, 0x0e); - *fe_status = 0; - if (val & 0x01) - *fe_status |= FE_HAS_SIGNAL; - if (val & 0x02) - *fe_status |= FE_HAS_CARRIER; - if (val & 0x04) - *fe_status |= FE_HAS_VITERBI; - if (val & 0x08) - *fe_status |= FE_HAS_SYNC; - if (val & 0x10) { - *fe_status |= FE_HAS_LOCK; - if (!state->has_lock) { - state->has_lock = true; - /* modify parameters for stable reception */ - tda10086_write_byte(state, 0x02, 0x00); - } - } - - return 0; -} - -static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 _str; - - dprintk ("%s\n", __func__); - - _str = 0xff - tda10086_read_byte(state, 0x43); - *signal = (_str << 8) | _str; - - return 0; -} - -static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr) -{ - struct tda10086_state* state = fe->demodulator_priv; - u8 _snr; - - dprintk ("%s\n", __func__); - - _snr = 0xff - tda10086_read_byte(state, 0x1c); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - /* read it */ - *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f; - - /* reset counter */ - tda10086_write_byte(state, 0x18, 0x00); - tda10086_write_byte(state, 0x18, 0x80); - - return 0; -} - -static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - /* read it */ - *ber = 0; - *ber |= tda10086_read_byte(state, 0x15); - *ber |= tda10086_read_byte(state, 0x16) << 8; - *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16; - - return 0; -} - -static int tda10086_sleep(struct dvb_frontend* fe) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - tda10086_write_mask(state, 0x00, 0x08, 0x08); - - return 0; -} - -static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct tda10086_state* state = fe->demodulator_priv; - - dprintk ("%s\n", __func__); - - if (enable) { - tda10086_write_mask(state, 0x00, 0x10, 0x10); - } else { - tda10086_write_mask(state, 0x00, 0x10, 0x00); - } - - return 0; -} - -static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { - fesettings->min_delay_ms = 50; - fesettings->step_size = 2000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1500; - fesettings->max_drift = 9000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 1000; - fesettings->max_drift = 8000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { - fesettings->min_delay_ms = 100; - fesettings->step_size = 500; - fesettings->max_drift = 7000; - } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 14 * fesettings->step_size; - } else { - fesettings->min_delay_ms = 200; - fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); - fesettings->max_drift = 18 * fesettings->step_size; - } - - return 0; -} - -static void tda10086_release(struct dvb_frontend* fe) -{ - struct tda10086_state *state = fe->demodulator_priv; - tda10086_sleep(fe); - kfree(state); -} - -static struct dvb_frontend_ops tda10086_ops = { - - .info = { - .name = "Philips TDA10086 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = tda10086_release, - - .init = tda10086_init, - .sleep = tda10086_sleep, - .i2c_gate_ctrl = tda10086_i2c_gate_ctrl, - - .set_frontend = tda10086_set_frontend, - .get_frontend = tda10086_get_frontend, - .get_tune_settings = tda10086_get_tune_settings, - - .read_status = tda10086_read_status, - .read_ber = tda10086_read_ber, - .read_signal_strength = tda10086_read_signal_strength, - .read_snr = tda10086_read_snr, - .read_ucblocks = tda10086_read_ucblocks, - - .diseqc_send_master_cmd = tda10086_send_master_cmd, - .diseqc_send_burst = tda10086_send_burst, - .set_tone = tda10086_set_tone, -}; - -struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c) -{ - struct tda10086_state *state; - - dprintk ("%s\n", __func__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL); - if (!state) - return NULL; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if (tda10086_read_byte(state, 0x1e) != 0xe1) { - kfree(state); - return NULL; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda10086_attach); diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h deleted file mode 100644 index 61148c558d8..00000000000 --- a/drivers/media/dvb/frontends/tda10086.h +++ /dev/null @@ -1,61 +0,0 @@ - /* - Driver for Philips tda10086 DVBS Frontend - - (c) 2006 Andrew de Quincey - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#ifndef TDA10086_H -#define TDA10086_H - -#include <linux/dvb/frontend.h> -#include <linux/firmware.h> - -enum tda10086_xtal { - TDA10086_XTAL_16M, - TDA10086_XTAL_4M -}; - -struct tda10086_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* does the "inversion" need inverted? */ - u8 invert; - - /* do we need the diseqc signal with carrier? */ - u8 diseqc_tone; - - /* frequency of the reference xtal */ - enum tda10086_xtal xtal_freq; -}; - -#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_TDA10086 */ - -#endif /* TDA10086_H */ diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c deleted file mode 100644 index 5b843b2e67e..00000000000 --- a/drivers/media/dvb/frontends/tda8083.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - Driver for Philips TDA8083 based QPSK Demodulator - - Copyright (C) 2001 Convergence Integrated Media GmbH - - written by Ralph Metzler <ralph@convergence.de> - - adoption to the new DVB frontend API and diagnostic ioctl's - by Holger Waechtler <holger@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include "dvb_frontend.h" -#include "tda8083.h" - - -struct tda8083_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct tda8083_config* config; - struct dvb_frontend frontend; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda8083: " args); \ - } while (0) - - -static u8 tda8083_init_tab [] = { - 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea, - 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10, - 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8, - 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00, - 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - - -static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data) -{ - int ret; - u8 buf [] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - dprintk ("%s: writereg error (reg %02x, ret == %i)\n", - __func__, reg, ret); - - return (ret != 1) ? -1 : 0; -} - -static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len) -{ - int ret; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - dprintk ("%s: readreg error (reg %02x, ret == %i)\n", - __func__, reg1, ret); - - return ret == 2 ? 0 : -1; -} - -static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg) -{ - u8 val; - - tda8083_readregs (state, reg, &val, 1); - - return val; -} - -static int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion) -{ - /* XXX FIXME: implement other modes than FEC_AUTO */ - if (inversion == INVERSION_AUTO) - return 0; - - return -EINVAL; -} - -static int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec) -{ - if (fec == FEC_AUTO) - return tda8083_writereg (state, 0x07, 0xff); - - if (fec >= FEC_1_2 && fec <= FEC_8_9) - return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec)); - - return -EINVAL; -} - -static fe_code_rate_t tda8083_get_fec (struct tda8083_state* state) -{ - u8 index; - static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, - FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 }; - - index = tda8083_readreg(state, 0x0e) & 0x07; - - return fec_tab [index]; -} - -static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate) -{ - u32 ratio; - u32 tmp; - u8 filter; - - if (srate > 32000000) - srate = 32000000; - if (srate < 500000) - srate = 500000; - - filter = 0; - if (srate < 24000000) - filter = 2; - if (srate < 16000000) - filter = 3; - - tmp = 31250 << 16; - ratio = tmp / srate; - - tmp = (tmp % srate) << 8; - ratio = (ratio << 8) + tmp / srate; - - tmp = (tmp % srate) << 8; - ratio = (ratio << 8) + tmp / srate; - - dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio); - - tda8083_writereg (state, 0x05, filter); - tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff); - tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff); - tda8083_writereg (state, 0x04, (ratio ) & 0xff); - - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 1; -} - -static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout) -{ - unsigned long start = jiffies; - - while (jiffies - start < timeout && - !(tda8083_readreg(state, 0x02) & 0x80)) - { - msleep(50); - }; -} - -static int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone) -{ - tda8083_writereg (state, 0x26, 0xf1); - - switch (tone) { - case SEC_TONE_OFF: - return tda8083_writereg (state, 0x29, 0x00); - case SEC_TONE_ON: - return tda8083_writereg (state, 0x29, 0x80); - default: - return -EINVAL; - }; -} - -static int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) -{ - switch (voltage) { - case SEC_VOLTAGE_13: - return tda8083_writereg (state, 0x20, 0x00); - case SEC_VOLTAGE_18: - return tda8083_writereg (state, 0x20, 0x11); - default: - return -EINVAL; - }; -} - -static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) -{ - switch (burst) { - case SEC_MINI_A: - tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */ - break; - case SEC_MINI_B: - tda8083_writereg (state, 0x29, (7 << 2)); /* send B */ - break; - default: - return -EINVAL; - }; - - tda8083_wait_diseqc_fifo (state, 100); - - return 0; -} - -static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) -{ - struct tda8083_state* state = fe->demodulator_priv; - int i; - - tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */ - - for (i=0; i<m->msg_len; i++) - tda8083_writereg (state, 0x23 + i, m->msg[i]); - - tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */ - - tda8083_wait_diseqc_fifo (state, 100); - - return 0; -} - -static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct tda8083_state* state = fe->demodulator_priv; - - u8 signal = ~tda8083_readreg (state, 0x01); - u8 sync = tda8083_readreg (state, 0x02); - - *status = 0; - - if (signal > 10) - *status |= FE_HAS_SIGNAL; - - if (sync & 0x01) - *status |= FE_HAS_CARRIER; - - if (sync & 0x02) - *status |= FE_HAS_VITERBI; - - if (sync & 0x10) - *status |= FE_HAS_SYNC; - - if (sync & 0x20) /* frontend can not lock */ - *status |= FE_TIMEDOUT; - - if ((sync & 0x1f) == 0x1f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct tda8083_state* state = fe->demodulator_priv; - int ret; - u8 buf[3]; - - if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf)))) - return ret; - - *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2]; - - return 0; -} - -static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct tda8083_state* state = fe->demodulator_priv; - - u8 signal = ~tda8083_readreg (state, 0x01); - *strength = (signal << 8) | signal; - - return 0; -} - -static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct tda8083_state* state = fe->demodulator_priv; - - u8 _snr = tda8083_readreg (state, 0x08); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct tda8083_state* state = fe->demodulator_priv; - - *ucblocks = tda8083_readreg(state, 0x0f); - if (*ucblocks == 0xff) - *ucblocks = 0xffffffff; - - return 0; -} - -static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda8083_state* state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - tda8083_set_inversion (state, p->inversion); - tda8083_set_fec (state, p->u.qpsk.fec_inner); - tda8083_set_symbolrate (state, p->u.qpsk.symbol_rate); - - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct tda8083_state* state = fe->demodulator_priv; - - /* FIXME: get symbolrate & frequency offset...*/ - /*p->frequency = ???;*/ - p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ? - INVERSION_ON : INVERSION_OFF; - p->u.qpsk.fec_inner = tda8083_get_fec (state); - /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (state);*/ - - return 0; -} - -static int tda8083_sleep(struct dvb_frontend* fe) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_writereg (state, 0x00, 0x02); - return 0; -} - -static int tda8083_init(struct dvb_frontend* fe) -{ - struct tda8083_state* state = fe->demodulator_priv; - int i; - - for (i=0; i<44; i++) - tda8083_writereg (state, i, tda8083_init_tab[i]); - - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_send_diseqc_burst (state, burst); - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_set_tone (state, tone); - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct tda8083_state* state = fe->demodulator_priv; - - tda8083_set_voltage (state, voltage); - tda8083_writereg (state, 0x00, 0x3c); - tda8083_writereg (state, 0x00, 0x04); - - return 0; -} - -static void tda8083_release(struct dvb_frontend* fe) -{ - struct tda8083_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops tda8083_ops; - -struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c) -{ - struct tda8083_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct tda8083_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - - /* check if the demod is there */ - if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops tda8083_ops = { - - .info = { - .name = "Philips TDA8083 DVB-S", - .type = FE_QPSK, - .frequency_min = 920000, /* TDA8060 */ - .frequency_max = 2200000, /* TDA8060 */ - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - /* .frequency_tolerance = ???,*/ - .symbol_rate_min = 12000000, - .symbol_rate_max = 30000000, - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_MUTE_TS - }, - - .release = tda8083_release, - - .init = tda8083_init, - .sleep = tda8083_sleep, - - .set_frontend = tda8083_set_frontend, - .get_frontend = tda8083_get_frontend, - - .read_status = tda8083_read_status, - .read_signal_strength = tda8083_read_signal_strength, - .read_snr = tda8083_read_snr, - .read_ber = tda8083_read_ber, - .read_ucblocks = tda8083_read_ucblocks, - - .diseqc_send_master_cmd = tda8083_send_diseqc_msg, - .diseqc_send_burst = tda8083_diseqc_send_burst, - .set_tone = tda8083_diseqc_set_tone, - .set_voltage = tda8083_diseqc_set_voltage, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(tda8083_attach); diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h deleted file mode 100644 index 5a03c14a10e..00000000000 --- a/drivers/media/dvb/frontends/tda8083.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend - - Copyright (C) 2001 Convergence Integrated Media GmbH - - written by Ralph Metzler <ralph@convergence.de> - - adoption to the new DVB frontend API and diagnostic ioctl's - by Holger Waechtler <holger@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef TDA8083_H -#define TDA8083_H - -#include <linux/dvb/frontend.h> - -struct tda8083_config -{ - /* the demodulator's i2c address */ - u8 demod_address; -}; - -#if defined(CONFIG_DVB_TDA8083) || (defined(CONFIG_DVB_TDA8083_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA8083 - -#endif // TDA8083_H diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c deleted file mode 100644 index b6d17779910..00000000000 --- a/drivers/media/dvb/frontends/tda8261.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - TDA8261 8PSK/QPSK tuner driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> - -#include "dvb_frontend.h" -#include "tda8261.h" - -struct tda8261_state { - struct dvb_frontend *fe; - struct i2c_adapter *i2c; - const struct tda8261_config *config; - - /* state cache */ - u32 frequency; - u32 bandwidth; -}; - -static int tda8261_read(struct tda8261_state *state, u8 *buf) -{ - const struct tda8261_config *config = state->config; - int err = 0; - struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 }; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) - printk("%s: read error, err=%d\n", __func__, err); - - return err; -} - -static int tda8261_write(struct tda8261_state *state, u8 *buf) -{ - const struct tda8261_config *config = state->config; - int err = 0; - struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 }; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) - printk("%s: write error, err=%d\n", __func__, err); - - return err; -} - -static int tda8261_get_status(struct dvb_frontend *fe, u32 *status) -{ - struct tda8261_state *state = fe->tuner_priv; - u8 result = 0; - int err = 0; - - *status = 0; - - if ((err = tda8261_read(state, &result)) < 0) { - printk("%s: I/O Error\n", __func__); - return err; - } - if ((result >> 6) & 0x01) { - printk("%s: Tuner Phase Locked\n", __func__); - *status = 1; - } - - return err; -} - -static const u32 div_tab[] = { 2000, 1000, 500, 250, 125 }; /* kHz */ -static const u8 ref_div[] = { 0x00, 0x01, 0x02, 0x05, 0x07 }; - -static int tda8261_get_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) -{ - struct tda8261_state *state = fe->tuner_priv; - int err = 0; - - switch (param) { - case DVBFE_TUNER_FREQUENCY: - tstate->frequency = state->frequency; - break; - case DVBFE_TUNER_BANDWIDTH: - tstate->bandwidth = 40000000; /* FIXME! need to calculate Bandwidth */ - break; - default: - printk("%s: Unknown parameter (param=%d)\n", __func__, param); - err = -EINVAL; - break; - } - - return err; -} - -static int tda8261_set_state(struct dvb_frontend *fe, - enum tuner_param param, - struct tuner_state *tstate) -{ - struct tda8261_state *state = fe->tuner_priv; - const struct tda8261_config *config = state->config; - u32 frequency, N, status = 0; - u8 buf[4]; - int err = 0; - - if (param & DVBFE_TUNER_FREQUENCY) { - /** - * N = Max VCO Frequency / Channel Spacing - * Max VCO Frequency = VCO frequency + (channel spacing - 1) - * (to account for half channel spacing on either side) - */ - frequency = tstate->frequency; - if ((frequency < 950000) || (frequency > 2150000)) { - printk("%s: Frequency beyond limits, frequency=%d\n", __func__, frequency); - return -EINVAL; - } - N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size]; - printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n", - __func__, config->step_size, div_tab[config->step_size], N, N); - - buf[0] = (N >> 8) & 0xff; - buf[1] = N & 0xff; - buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1); - - if (frequency < 1450000) - buf[3] = 0x00; - if (frequency < 2000000) - buf[3] = 0x40; - if (frequency < 2150000) - buf[3] = 0x80; - - /* Set params */ - if ((err = tda8261_write(state, buf)) < 0) { - printk("%s: I/O Error\n", __func__); - return err; - } - /* sleep for some time */ - printk("%s: Waiting to Phase LOCK\n", __func__); - msleep(20); - /* check status */ - if ((err = tda8261_get_status(fe, &status)) < 0) { - printk("%s: I/O Error\n", __func__); - return err; - } - if (status == 1) { - printk("%s: Tuner Phase locked: status=%d\n", __func__, status); - state->frequency = frequency; /* cache successful state */ - } else { - printk("%s: No Phase lock: status=%d\n", __func__, status); - } - } else { - printk("%s: Unknown parameter (param=%d)\n", __func__, param); - return -EINVAL; - } - - return 0; -} - -static int tda8261_release(struct dvb_frontend *fe) -{ - struct tda8261_state *state = fe->tuner_priv; - - fe->tuner_priv = NULL; - kfree(state); - return 0; -} - -static struct dvb_tuner_ops tda8261_ops = { - - .info = { - .name = "TDA8261", -// .tuner_name = NULL, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 0 - }, - - .set_state = tda8261_set_state, - .get_state = tda8261_get_state, - .get_status = tda8261_get_status, - .release = tda8261_release -}; - -struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, - const struct tda8261_config *config, - struct i2c_adapter *i2c) -{ - struct tda8261_state *state = NULL; - - if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL) - goto exit; - - state->config = config; - state->i2c = i2c; - state->fe = fe; - fe->tuner_priv = state; - fe->ops.tuner_ops = tda8261_ops; - - fe->ops.tuner_ops.info.frequency_step = div_tab[config->step_size]; -// fe->ops.tuner_ops.tuner_name = &config->buf; - -// printk("%s: Attaching %s TDA8261 8PSK/QPSK tuner\n", -// __func__, fe->ops.tuner_ops.tuner_name); - printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__); - - return fe; - -exit: - kfree(state); - return NULL; -} - -EXPORT_SYMBOL(tda8261_attach); -MODULE_PARM_DESC(verbose, "Set verbosity level"); - -MODULE_AUTHOR("Manu Abraham"); -MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tda8261.h b/drivers/media/dvb/frontends/tda8261.h deleted file mode 100644 index 006e45351b9..00000000000 --- a/drivers/media/dvb/frontends/tda8261.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - TDA8261 8PSK/QPSK tuner driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __TDA8261_H -#define __TDA8261_H - -enum tda8261_step { - TDA8261_STEP_2000 = 0, /* 2000 kHz */ - TDA8261_STEP_1000, /* 1000 kHz */ - TDA8261_STEP_500, /* 500 kHz */ - TDA8261_STEP_250, /* 250 kHz */ - TDA8261_STEP_125 /* 125 kHz */ -}; - -struct tda8261_config { -// u8 buf[16]; - u8 addr; - enum tda8261_step step_size; -}; - -#if defined(CONFIG_DVB_TDA8261) || (defined(CONFIG_DVB_TDA8261_MODULE) && defined(MODULE)) - -extern struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, - const struct tda8261_config *config, - struct i2c_adapter *i2c); - -#else - -static inline struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, - const struct tda8261_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__); - return NULL; -} - -#endif //CONFIG_DVB_TDA8261 - -#endif// __TDA8261_H diff --git a/drivers/media/dvb/frontends/tda8261_cfg.h b/drivers/media/dvb/frontends/tda8261_cfg.h deleted file mode 100644 index 1af1ee49b54..00000000000 --- a/drivers/media/dvb/frontends/tda8261_cfg.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - TDA8261 8PSK/QPSK tuner driver - Copyright (C) Manu Abraham (abraham.manu@gmail.com) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -static int tda8261_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *frequency = t_state.frequency; - printk("%s: Frequency=%d\n", __func__, t_state.frequency); - } - return 0; -} - -static int tda8261_set_frequency(struct dvb_frontend *fe, u32 frequency) -{ - struct dvb_frontend_ops *frontend_ops = NULL; - struct dvb_tuner_ops *tuner_ops = NULL; - struct tuner_state t_state; - int err = 0; - - t_state.frequency = frequency; - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->set_state) { - if ((err = tuner_ops->set_state(fe, DVBFE_TUNER_FREQUENCY, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - } - printk("%s: Frequency=%d\n", __func__, t_state.frequency); - return 0; -} - -static int tda8261_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) -{ - struct dvb_frontend_ops *frontend_ops = &fe->ops; - struct dvb_tuner_ops *tuner_ops = &frontend_ops->tuner_ops; - struct tuner_state t_state; - int err = 0; - - if (&fe->ops) - frontend_ops = &fe->ops; - if (&frontend_ops->tuner_ops) - tuner_ops = &frontend_ops->tuner_ops; - if (tuner_ops->get_state) { - if ((err = tuner_ops->get_state(fe, DVBFE_TUNER_BANDWIDTH, &t_state)) < 0) { - printk("%s: Invalid parameter\n", __func__); - return err; - } - *bandwidth = t_state.bandwidth; - } - printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth); - return 0; -} diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c deleted file mode 100644 index a051554b5e2..00000000000 --- a/drivers/media/dvb/frontends/tda826x.c +++ /dev/null @@ -1,186 +0,0 @@ - /* - Driver for Philips tda8262/tda8263 DVBS Silicon tuners - - (c) 2006 Andrew de Quincey - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#include <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "tda826x.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "tda826x: " args); \ - } while (0) - -struct tda826x_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u8 has_loopthrough:1; - u32 frequency; -}; - -static int tda826x_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int tda826x_sleep(struct dvb_frontend *fe) -{ - struct tda826x_priv *priv = fe->tuner_priv; - int ret; - u8 buf [] = { 0x00, 0x8d }; - struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 }; - - dprintk("%s:\n", __func__); - - if (!priv->has_loopthrough) - buf[1] = 0xad; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - dprintk("%s: i2c error\n", __func__); - } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct tda826x_priv *priv = fe->tuner_priv; - int ret; - u32 div; - u32 ksyms; - u32 bandwidth; - u8 buf [11]; - struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 }; - - dprintk("%s:\n", __func__); - - div = (params->frequency + (1000-1)) / 1000; - - /* BW = ((1 + RO) * SR/2 + 5) * 1.3 [SR in MSPS, BW in MHz] */ - /* with R0 = 0.35 and some transformations: */ - ksyms = params->u.qpsk.symbol_rate / 1000; - bandwidth = (878 * ksyms + 6500000) / 1000000 + 1; - if (bandwidth < 5) - bandwidth = 5; - else if (bandwidth > 36) - bandwidth = 36; - - buf[0] = 0x00; // subaddress - buf[1] = 0x09; // powerdown RSSI + the magic value 1 - if (!priv->has_loopthrough) - buf[1] |= 0x20; // power down loopthrough if not needed - buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO - buf[3] = div >> 7; - buf[4] = div << 1; - buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */ - buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation - buf[7] = 0x83; // charge pumps at high, tests off - buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports. - buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL - buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - dprintk("%s: i2c error\n", __func__); - } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - priv->frequency = div * 1000; - - return (ret == 1) ? 0 : ret; -} - -static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct tda826x_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops tda826x_tuner_ops = { - .info = { - .name = "Philips TDA826X", - .frequency_min = 950000, - .frequency_max = 2175000 - }, - .release = tda826x_release, - .sleep = tda826x_sleep, - .set_params = tda826x_set_params, - .get_frequency = tda826x_get_frequency, -}; - -struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough) -{ - struct tda826x_priv *priv = NULL; - u8 b1 [] = { 0, 0 }; - struct i2c_msg msg[2] = { - { .addr = addr, .flags = 0, .buf = NULL, .len = 0 }, - { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } - }; - int ret; - - dprintk("%s:\n", __func__); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer (i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - if (!(b1[1] & 0x80)) - return NULL; - - priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - priv->has_loopthrough = has_loopthrough; - - memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops)); - - fe->tuner_priv = priv; - - return fe; -} -EXPORT_SYMBOL(tda826x_attach); - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("DVB TDA826x driver"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h deleted file mode 100644 index 89e97926ab2..00000000000 --- a/drivers/media/dvb/frontends/tda826x.h +++ /dev/null @@ -1,53 +0,0 @@ - /* - Driver for Philips tda8262/tda8263 DVBS Silicon tuners - - (c) 2006 Andrew de Quincey - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - */ - -#ifndef __DVB_TDA826X_H__ -#define __DVB_TDA826X_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -/** - * Attach a tda826x tuner to the supplied frontend structure. - * - * @param fe Frontend to attach to. - * @param addr i2c address of the tuner. - * @param i2c i2c adapter to use. - * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. - * @return FE pointer on success, NULL on failure. - */ -#if defined(CONFIG_DVB_TDA826X) || (defined(CONFIG_DVB_TDA826X_MODULE) && defined(MODULE)) -extern struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, int addr, - struct i2c_adapter *i2c, - int has_loopthrough); -#else -static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe, - int addr, - struct i2c_adapter *i2c, - int has_loopthrough) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TDA826X - -#endif // __DVB_TDA826X_H__ diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h deleted file mode 100644 index 51f17067865..00000000000 --- a/drivers/media/dvb/frontends/tdhd1.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * tdhd1.h - ALPS TDHD1-204A tuner support - * - * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de> - * - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * The project's page is at http://www.linuxtv.org - */ - -#ifndef TDHD1_H -#define TDHD1_H - -#include "tda1004x.h" - -static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name); - -static struct tda1004x_config alps_tdhd1_204a_config = { - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = alps_tdhd1_204_request_firmware -}; - -static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct i2c_adapter *i2c = fe->tuner_priv; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - u32 div; - - div = (params->frequency + 36166666) / 166666; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85; - - if (params->frequency >= 174000000 && params->frequency <= 230000000) - data[3] = 0x02; - else if (params->frequency >= 470000000 && params->frequency <= 823000000) - data[3] = 0x0C; - else if (params->frequency > 823000000 && params->frequency <= 862000000) - data[3] = 0x8C; - else - return -EINVAL; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - - return 0; -} - -#endif /* TDHD1_H */ diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c deleted file mode 100644 index 1790baee014..00000000000 --- a/drivers/media/dvb/frontends/tua6100.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - * Driver for Infineon tua6100 pll. - * - * (c) 2006 Andrew de Quincey - * - * Based on code found in budget-av.c, which has the following: - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & - * Andrew de Quincey <adq_dvb@lidskialf.net> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/dvb/frontend.h> -#include <asm/types.h> - -#include "tua6100.h" - -struct tua6100_priv { - /* i2c details */ - int i2c_address; - struct i2c_adapter *i2c; - u32 frequency; -}; - -static int tua6100_release(struct dvb_frontend *fe) -{ - kfree(fe->tuner_priv); - fe->tuner_priv = NULL; - return 0; -} - -static int tua6100_sleep(struct dvb_frontend *fe) -{ - struct tua6100_priv *priv = fe->tuner_priv; - int ret; - u8 reg0[] = { 0x00, 0x00 }; - struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 }; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { - printk("%s: i2c error\n", __func__); - } - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return (ret == 1) ? 0 : ret; -} - -static int tua6100_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct tua6100_priv *priv = fe->tuner_priv; - u32 div; - u32 prediv; - u8 reg0[] = { 0x00, 0x00 }; - u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 }; - u8 reg2[] = { 0x02, 0x00, 0x00 }; - struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 }; - struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 }; - struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 }; - -#define _R 4 -#define _P 32 -#define _ri 4000000 - - // setup register 0 - if (params->frequency < 2000000) { - reg0[1] = 0x03; - } else { - reg0[1] = 0x07; - } - - // setup register 1 - if (params->frequency < 1630000) { - reg1[1] = 0x2c; - } else { - reg1[1] = 0x0c; - } - if (_P == 64) - reg1[1] |= 0x40; - if (params->frequency >= 1525000) - reg1[1] |= 0x80; - - // register 2 - reg2[1] = (_R >> 8) & 0x03; - reg2[2] = _R; - if (params->frequency < 1455000) { - reg2[1] |= 0x1c; - } else if (params->frequency < 1630000) { - reg2[1] |= 0x0c; - } else { - reg2[1] |= 0x1c; - } - - // The N divisor ratio (note: params->frequency is in kHz, but we need it in Hz) - prediv = (params->frequency * _R) / (_ri / 1000); - div = prediv / _P; - reg1[1] |= (div >> 9) & 0x03; - reg1[2] = div >> 1; - reg1[3] = (div << 7); - priv->frequency = ((div * _P) * (_ri / 1000)) / _R; - - // Finally, calculate and store the value for A - reg1[3] |= (prediv - (div*_P)) & 0x7f; - -#undef _R -#undef _P -#undef _ri - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c, &msg0, 1) != 1) - return -EIO; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c, &msg2, 1) != 1) - return -EIO; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(priv->i2c, &msg1, 1) != 1) - return -EIO; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - return 0; -} - -static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency) -{ - struct tua6100_priv *priv = fe->tuner_priv; - *frequency = priv->frequency; - return 0; -} - -static struct dvb_tuner_ops tua6100_tuner_ops = { - .info = { - .name = "Infineon TUA6100", - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_step = 1000, - }, - .release = tua6100_release, - .sleep = tua6100_sleep, - .set_params = tua6100_set_params, - .get_frequency = tua6100_get_frequency, -}; - -struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) -{ - struct tua6100_priv *priv = NULL; - u8 b1 [] = { 0x80 }; - u8 b2 [] = { 0x00 }; - struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 }, - { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } }; - int ret; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer (i2c, msg, 2); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - if (ret != 2) - return NULL; - - priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL); - if (priv == NULL) - return NULL; - - priv->i2c_address = addr; - priv->i2c = i2c; - - memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops)); - fe->tuner_priv = priv; - return fe; -} -EXPORT_SYMBOL(tua6100_attach); - -MODULE_DESCRIPTION("DVB tua6100 driver"); -MODULE_AUTHOR("Andrew de Quincey"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h deleted file mode 100644 index f83dbd5e42a..00000000000 --- a/drivers/media/dvb/frontends/tua6100.h +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Driver for Infineon tua6100 PLL. - * - * (c) 2006 Andrew de Quincey - * - * Based on code found in budget-av.c, which has the following: - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & - * Andrew de Quincey <adq_dvb@lidskialf.net> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __DVB_TUA6100_H__ -#define __DVB_TUA6100_H__ - -#include <linux/i2c.h> -#include "dvb_frontend.h" - -#if defined(CONFIG_DVB_TUA6100) || (defined(CONFIG_DVB_TUA6100_MODULE) && defined(MODULE)) -extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_TUA6100 - -#endif diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c deleted file mode 100644 index a184597f1d9..00000000000 --- a/drivers/media/dvb/frontends/ves1820.c +++ /dev/null @@ -1,446 +0,0 @@ -/* - VES1820 - Single Chip Cable Channel Receiver driver module - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "ves1820.h" - - - -struct ves1820_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct ves1820_config* config; - struct dvb_frontend frontend; - - /* private demodulator data */ - u8 reg0; - u8 pwm; -}; - - -static int verbose; - -static u8 ves1820_inittab[] = { - 0x69, 0x6A, 0x93, 0x1A, 0x12, 0x46, 0x26, 0x1A, - 0x43, 0x6A, 0xAA, 0xAA, 0x1E, 0x85, 0x43, 0x20, - 0xE0, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40 -}; - -static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data) -{ - u8 buf[] = { 0x00, reg, data }; - struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 3 }; - int ret; - - ret = i2c_transfer(state->i2c, &msg, 1); - - if (ret != 1) - printk("ves1820: %s(): writereg error (reg == 0x%02x, " - "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret); - - return (ret != 1) ? -EREMOTEIO : 0; -} - -static u8 ves1820_readreg(struct ves1820_state *state, u8 reg) -{ - u8 b0[] = { 0x00, reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 2}, - {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1} - }; - int ret; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) - printk("ves1820: %s(): readreg error (reg == 0x%02x, " - "ret == %i)\n", __func__, reg, ret); - - return b1[0]; -} - -static int ves1820_setup_reg0(struct ves1820_state *state, u8 reg0, fe_spectral_inversion_t inversion) -{ - reg0 |= state->reg0 & 0x62; - - if (INVERSION_ON == inversion) { - if (!state->config->invert) reg0 |= 0x20; - else reg0 &= ~0x20; - } else if (INVERSION_OFF == inversion) { - if (!state->config->invert) reg0 &= ~0x20; - else reg0 |= 0x20; - } - - ves1820_writereg(state, 0x00, reg0 & 0xfe); - ves1820_writereg(state, 0x00, reg0 | 0x01); - - state->reg0 = reg0; - - return 0; -} - -static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate) -{ - s32 BDR; - s32 BDRI; - s16 SFIL = 0; - u16 NDEC = 0; - u32 ratio; - u32 fin; - u32 tmp; - u64 fptmp; - u64 fpxin; - - if (symbolrate > state->config->xin / 2) - symbolrate = state->config->xin / 2; - - if (symbolrate < 500000) - symbolrate = 500000; - - if (symbolrate < state->config->xin / 16) - NDEC = 1; - if (symbolrate < state->config->xin / 32) - NDEC = 2; - if (symbolrate < state->config->xin / 64) - NDEC = 3; - - /* yeuch! */ - fpxin = state->config->xin * 10; - fptmp = fpxin; do_div(fptmp, 123); - if (symbolrate < fptmp) - SFIL = 1; - fptmp = fpxin; do_div(fptmp, 160); - if (symbolrate < fptmp) - SFIL = 0; - fptmp = fpxin; do_div(fptmp, 246); - if (symbolrate < fptmp) - SFIL = 1; - fptmp = fpxin; do_div(fptmp, 320); - if (symbolrate < fptmp) - SFIL = 0; - fptmp = fpxin; do_div(fptmp, 492); - if (symbolrate < fptmp) - SFIL = 1; - fptmp = fpxin; do_div(fptmp, 640); - if (symbolrate < fptmp) - SFIL = 0; - fptmp = fpxin; do_div(fptmp, 984); - if (symbolrate < fptmp) - SFIL = 1; - - fin = state->config->xin >> 4; - symbolrate <<= NDEC; - ratio = (symbolrate << 4) / fin; - tmp = ((symbolrate << 4) % fin) << 8; - ratio = (ratio << 8) + tmp / fin; - tmp = (tmp % fin) << 8; - ratio = (ratio << 8) + (tmp + fin / 2) / fin; - - BDR = ratio; - BDRI = (((state->config->xin << 5) / symbolrate) + 1) / 2; - - if (BDRI > 0xFF) - BDRI = 0xFF; - - SFIL = (SFIL << 4) | ves1820_inittab[0x0E]; - - NDEC = (NDEC << 6) | ves1820_inittab[0x03]; - - ves1820_writereg(state, 0x03, NDEC); - ves1820_writereg(state, 0x0a, BDR & 0xff); - ves1820_writereg(state, 0x0b, (BDR >> 8) & 0xff); - ves1820_writereg(state, 0x0c, (BDR >> 16) & 0x3f); - - ves1820_writereg(state, 0x0d, BDRI); - ves1820_writereg(state, 0x0e, SFIL); - - return 0; -} - -static int ves1820_init(struct dvb_frontend* fe) -{ - struct ves1820_state* state = fe->demodulator_priv; - int i; - - ves1820_writereg(state, 0, 0); - - for (i = 0; i < sizeof(ves1820_inittab); i++) - ves1820_writereg(state, i, ves1820_inittab[i]); - if (state->config->selagc) - ves1820_writereg(state, 2, ves1820_inittab[2] | 0x08); - - ves1820_writereg(state, 0x34, state->pwm); - - return 0; -} - -static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1820_state* state = fe->demodulator_priv; - static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 }; - static const u8 reg0x01[] = { 140, 140, 106, 100, 92 }; - static const u8 reg0x05[] = { 135, 100, 70, 54, 38 }; - static const u8 reg0x08[] = { 162, 116, 67, 52, 35 }; - static const u8 reg0x09[] = { 145, 150, 106, 126, 107 }; - int real_qam = p->u.qam.modulation - QAM_16; - - if (real_qam < 0 || real_qam > 4) - return -EINVAL; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - - ves1820_set_symbolrate(state, p->u.qam.symbol_rate); - ves1820_writereg(state, 0x34, state->pwm); - - ves1820_writereg(state, 0x01, reg0x01[real_qam]); - ves1820_writereg(state, 0x05, reg0x05[real_qam]); - ves1820_writereg(state, 0x08, reg0x08[real_qam]); - ves1820_writereg(state, 0x09, reg0x09[real_qam]); - - ves1820_setup_reg0(state, reg0x00[real_qam], p->inversion); - ves1820_writereg(state, 2, ves1820_inittab[2] | (state->config->selagc ? 0x08 : 0)); - return 0; -} - -static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct ves1820_state* state = fe->demodulator_priv; - int sync; - - *status = 0; - sync = ves1820_readreg(state, 0x11); - - if (sync & 1) - *status |= FE_HAS_SIGNAL; - - if (sync & 2) - *status |= FE_HAS_CARRIER; - - if (sync & 2) /* XXX FIXME! */ - *status |= FE_HAS_VITERBI; - - if (sync & 4) - *status |= FE_HAS_SYNC; - - if (sync & 8) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct ves1820_state* state = fe->demodulator_priv; - - u32 _ber = ves1820_readreg(state, 0x14) | - (ves1820_readreg(state, 0x15) << 8) | - ((ves1820_readreg(state, 0x16) & 0x0f) << 16); - *ber = 10 * _ber; - - return 0; -} - -static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct ves1820_state* state = fe->demodulator_priv; - - u8 gain = ves1820_readreg(state, 0x17); - *strength = (gain << 8) | gain; - - return 0; -} - -static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct ves1820_state* state = fe->demodulator_priv; - - u8 quality = ~ves1820_readreg(state, 0x18); - *snr = (quality << 8) | quality; - - return 0; -} - -static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct ves1820_state* state = fe->demodulator_priv; - - *ucblocks = ves1820_readreg(state, 0x13) & 0x7f; - if (*ucblocks == 0x7f) - *ucblocks = 0xffffffff; - - /* reset uncorrected block counter */ - ves1820_writereg(state, 0x10, ves1820_inittab[0x10] & 0xdf); - ves1820_writereg(state, 0x10, ves1820_inittab[0x10]); - - return 0; -} - -static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1820_state* state = fe->demodulator_priv; - int sync; - s8 afc = 0; - - sync = ves1820_readreg(state, 0x11); - afc = ves1820_readreg(state, 0x19); - if (verbose) { - /* AFC only valid when carrier has been recovered */ - printk(sync & 2 ? "ves1820: AFC (%d) %dHz\n" : - "ves1820: [AFC (%d) %dHz]\n", afc, -((s32) p->u.qam.symbol_rate * afc) >> 10); - } - - if (!state->config->invert) { - p->inversion = (state->reg0 & 0x20) ? INVERSION_ON : INVERSION_OFF; - } else { - p->inversion = (!(state->reg0 & 0x20)) ? INVERSION_ON : INVERSION_OFF; - } - - p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16; - - p->u.qam.fec_inner = FEC_NONE; - - p->frequency = ((p->frequency + 31250) / 62500) * 62500; - if (sync & 2) - p->frequency -= ((s32) p->u.qam.symbol_rate * afc) >> 10; - - return 0; -} - -static int ves1820_sleep(struct dvb_frontend* fe) -{ - struct ves1820_state* state = fe->demodulator_priv; - - ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */ - ves1820_writereg(state, 0x00, 0x80); /* standby */ - - return 0; -} - -static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) -{ - - fesettings->min_delay_ms = 200; - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static void ves1820_release(struct dvb_frontend* fe) -{ - struct ves1820_state* state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops ves1820_ops; - -struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, - u8 pwm) -{ - struct ves1820_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ves1820_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->reg0 = ves1820_inittab[0]; - state->config = config; - state->i2c = i2c; - state->pwm = pwm; - - /* check if the demod is there */ - if ((ves1820_readreg(state, 0x1a) & 0xf0) != 0x70) - goto error; - - if (verbose) - printk("ves1820: pwm=0x%02x\n", state->pwm); - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ves1820_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.ops.info.symbol_rate_min = (state->config->xin / 2) / 64; /* SACLK/64 == (XIN/2)/64 */ - state->frontend.ops.info.symbol_rate_max = (state->config->xin / 2) / 4; /* SACLK/4 */ - state->frontend.demodulator_priv = state; - - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops ves1820_ops = { - - .info = { - .name = "VLSI VES1820 DVB-C", - .type = FE_QAM, - .frequency_stepsize = 62500, - .frequency_min = 47000000, - .frequency_max = 862000000, - .caps = FE_CAN_QAM_16 | - FE_CAN_QAM_32 | - FE_CAN_QAM_64 | - FE_CAN_QAM_128 | - FE_CAN_QAM_256 | - FE_CAN_FEC_AUTO - }, - - .release = ves1820_release, - - .init = ves1820_init, - .sleep = ves1820_sleep, - - .set_frontend = ves1820_set_parameters, - .get_frontend = ves1820_get_frontend, - .get_tune_settings = ves1820_get_tune_settings, - - .read_status = ves1820_read_status, - .read_ber = ves1820_read_ber, - .read_signal_strength = ves1820_read_signal_strength, - .read_snr = ves1820_read_snr, - .read_ucblocks = ves1820_read_ucblocks, -}; - -module_param(verbose, int, 0644); -MODULE_PARM_DESC(verbose, "print AFC offset after tuning for debugging the PWM setting"); - -MODULE_DESCRIPTION("VLSI VES1820 DVB-C Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ves1820_attach); diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h deleted file mode 100644 index e902ed634ec..00000000000 --- a/drivers/media/dvb/frontends/ves1820.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - VES1820 - Single Chip Cable Channel Receiver driver module - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef VES1820_H -#define VES1820_H - -#include <linux/dvb/frontend.h> - -#define VES1820_SELAGC_PWM 0 -#define VES1820_SELAGC_SIGNAMPERR 1 - -struct ves1820_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* value of XIN to use */ - u32 xin; - - /* does inversion need inverted? */ - u8 invert:1; - - /* SELAGC control */ - u8 selagc:1; -}; - -#if defined(CONFIG_DVB_VES1820) || (defined(CONFIG_DVB_VES1820_MODULE) && defined(MODULE)) -extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, u8 pwm); -#else -static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, - struct i2c_adapter* i2c, u8 pwm) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_VES1820 - -#endif // VES1820_H diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c deleted file mode 100644 index bd558960bd8..00000000000 --- a/drivers/media/dvb/frontends/ves1x93.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - Driver for VES1893 and VES1993 QPSK Demodulators - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> - Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de> - Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/delay.h> - -#include "dvb_frontend.h" -#include "ves1x93.h" - - -struct ves1x93_state { - struct i2c_adapter* i2c; - /* configuration settings */ - const struct ves1x93_config* config; - struct dvb_frontend frontend; - - /* previous uncorrected block counter */ - fe_spectral_inversion_t inversion; - u8 *init_1x93_tab; - u8 *init_1x93_wtab; - u8 tab_size; - u8 demod_type; -}; - -static int debug; -#define dprintk if (debug) printk - -#define DEMOD_VES1893 0 -#define DEMOD_VES1993 1 - -static u8 init_1893_tab [] = { - 0x01, 0xa4, 0x35, 0x80, 0x2a, 0x0b, 0x55, 0xc4, - 0x09, 0x69, 0x00, 0x86, 0x4c, 0x28, 0x7f, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x21, 0xb0, 0x14, 0x00, 0xdc, 0x00, - 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x55, 0x00, 0x00, 0x7f, 0x00 -}; - -static u8 init_1993_tab [] = { - 0x00, 0x9c, 0x35, 0x80, 0x6a, 0x09, 0x72, 0x8c, - 0x09, 0x6b, 0x00, 0x00, 0x4c, 0x08, 0x00, 0x00, - 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x40, 0x21, 0xb0, 0x00, 0x00, 0x00, 0x10, - 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x55, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x0e, 0x80, 0x00 -}; - -static u8 init_1893_wtab[] = -{ - 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, - 0,1,0,0,0,0,0,0, 1,0,1,1,0,0,0,1, - 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, - 1,1,1,0,1,1 -}; - -static u8 init_1993_wtab[] = -{ - 1,1,1,1,1,1,1,1, 1,1,0,0,1,1,0,0, - 0,1,0,0,0,0,0,0, 1,1,1,1,0,0,0,1, - 1,1,1,0,0,0,0,0, 0,0,1,1,0,0,0,0, - 1,1,1,0,1,1,1,1, 1,1,1,1,1 -}; - -static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data) -{ - u8 buf [] = { 0x00, reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 3 }; - int err; - - if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { - dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static u8 ves1x93_readreg (struct ves1x93_state* state, u8 reg) -{ - int ret; - u8 b0 [] = { 0x00, reg }; - u8 b1 [] = { 0 }; - struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 2 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; - - ret = i2c_transfer (state->i2c, msg, 2); - - if (ret != 2) return ret; - - return b1[0]; -} - -static int ves1x93_clr_bit (struct ves1x93_state* state) -{ - msleep(10); - ves1x93_writereg (state, 0, state->init_1x93_tab[0] & 0xfe); - ves1x93_writereg (state, 0, state->init_1x93_tab[0]); - msleep(50); - return 0; -} - -static int ves1x93_set_inversion (struct ves1x93_state* state, fe_spectral_inversion_t inversion) -{ - u8 val; - - /* - * inversion on/off are interchanged because i and q seem to - * be swapped on the hardware - */ - - switch (inversion) { - case INVERSION_OFF: - val = 0xc0; - break; - case INVERSION_ON: - val = 0x80; - break; - case INVERSION_AUTO: - val = 0x00; - break; - default: - return -EINVAL; - } - - return ves1x93_writereg (state, 0x0c, (state->init_1x93_tab[0x0c] & 0x3f) | val); -} - -static int ves1x93_set_fec (struct ves1x93_state* state, fe_code_rate_t fec) -{ - if (fec == FEC_AUTO) - return ves1x93_writereg (state, 0x0d, 0x08); - else if (fec < FEC_1_2 || fec > FEC_8_9) - return -EINVAL; - else - return ves1x93_writereg (state, 0x0d, fec - FEC_1_2); -} - -static fe_code_rate_t ves1x93_get_fec (struct ves1x93_state* state) -{ - return FEC_1_2 + ((ves1x93_readreg (state, 0x0d) >> 4) & 0x7); -} - -static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate) -{ - u32 BDR; - u32 ratio; - u8 ADCONF, FCONF, FNR, AGCR; - u32 BDRI; - u32 tmp; - u32 FIN; - - dprintk("%s: srate == %d\n", __func__, (unsigned int) srate); - - if (srate > state->config->xin/2) - srate = state->config->xin/2; - - if (srate < 500000) - srate = 500000; - -#define MUL (1UL<<26) - - FIN = (state->config->xin + 6000) >> 4; - - tmp = srate << 6; - ratio = tmp / FIN; - - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - - tmp = (tmp % FIN) << 8; - ratio = (ratio << 8) + tmp / FIN; - - FNR = 0xff; - - if (ratio < MUL/3) FNR = 0; - if (ratio < (MUL*11)/50) FNR = 1; - if (ratio < MUL/6) FNR = 2; - if (ratio < MUL/9) FNR = 3; - if (ratio < MUL/12) FNR = 4; - if (ratio < (MUL*11)/200) FNR = 5; - if (ratio < MUL/24) FNR = 6; - if (ratio < (MUL*27)/1000) FNR = 7; - if (ratio < MUL/48) FNR = 8; - if (ratio < (MUL*137)/10000) FNR = 9; - - if (FNR == 0xff) { - ADCONF = 0x89; - FCONF = 0x80; - FNR = 0; - } else { - ADCONF = 0x81; - FCONF = 0x88 | (FNR >> 1) | ((FNR & 0x01) << 5); - /*FCONF = 0x80 | ((FNR & 0x01) << 5) | (((FNR > 1) & 0x03) << 3) | ((FNR >> 1) & 0x07);*/ - } - - BDR = (( (ratio << (FNR >> 1)) >> 4) + 1) >> 1; - BDRI = ( ((FIN << 8) / ((srate << (FNR >> 1)) >> 2)) + 1) >> 1; - - dprintk("FNR= %d\n", FNR); - dprintk("ratio= %08x\n", (unsigned int) ratio); - dprintk("BDR= %08x\n", (unsigned int) BDR); - dprintk("BDRI= %02x\n", (unsigned int) BDRI); - - if (BDRI > 0xff) - BDRI = 0xff; - - ves1x93_writereg (state, 0x06, 0xff & BDR); - ves1x93_writereg (state, 0x07, 0xff & (BDR >> 8)); - ves1x93_writereg (state, 0x08, 0x0f & (BDR >> 16)); - - ves1x93_writereg (state, 0x09, BDRI); - ves1x93_writereg (state, 0x20, ADCONF); - ves1x93_writereg (state, 0x21, FCONF); - - AGCR = state->init_1x93_tab[0x05]; - if (state->config->invert_pwm) - AGCR |= 0x20; - - if (srate < 6000000) - AGCR |= 0x80; - else - AGCR &= ~0x80; - - ves1x93_writereg (state, 0x05, AGCR); - - /* ves1993 hates this, will lose lock */ - if (state->demod_type != DEMOD_VES1993) - ves1x93_clr_bit (state); - - return 0; -} - -static int ves1x93_init (struct dvb_frontend* fe) -{ - struct ves1x93_state* state = fe->demodulator_priv; - int i; - int val; - - dprintk("%s: init chip\n", __func__); - - for (i = 0; i < state->tab_size; i++) { - if (state->init_1x93_wtab[i]) { - val = state->init_1x93_tab[i]; - - if (state->config->invert_pwm && (i == 0x05)) val |= 0x20; /* invert PWM */ - ves1x93_writereg (state, i, val); - } - } - - return 0; -} - -static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - return ves1x93_writereg (state, 0x1f, 0x20); - case SEC_VOLTAGE_18: - return ves1x93_writereg (state, 0x1f, 0x30); - case SEC_VOLTAGE_OFF: - return ves1x93_writereg (state, 0x1f, 0x00); - default: - return -EINVAL; - } -} - -static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - u8 sync = ves1x93_readreg (state, 0x0e); - - /* - * The ves1893 sometimes returns sync values that make no sense, - * because, e.g., the SIGNAL bit is 0, while some of the higher - * bits are 1 (and how can there be a CARRIER w/o a SIGNAL?). - * Tests showed that the VITERBI and SYNC bits are returned - * reliably, while the SIGNAL and CARRIER bits ar sometimes wrong. - * If such a case occurs, we read the value again, until we get a - * valid value. - */ - int maxtry = 10; /* just for safety - let's not get stuck here */ - while ((sync & 0x03) != 0x03 && (sync & 0x0c) && maxtry--) { - msleep(10); - sync = ves1x93_readreg (state, 0x0e); - } - - *status = 0; - - if (sync & 1) - *status |= FE_HAS_SIGNAL; - - if (sync & 2) - *status |= FE_HAS_CARRIER; - - if (sync & 4) - *status |= FE_HAS_VITERBI; - - if (sync & 8) - *status |= FE_HAS_SYNC; - - if ((sync & 0x1f) == 0x1f) - *status |= FE_HAS_LOCK; - - return 0; -} - -static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - *ber = ves1x93_readreg (state, 0x15); - *ber |= (ves1x93_readreg (state, 0x16) << 8); - *ber |= ((ves1x93_readreg (state, 0x17) & 0x0F) << 16); - *ber *= 10; - - return 0; -} - -static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - u8 signal = ~ves1x93_readreg (state, 0x0b); - *strength = (signal << 8) | signal; - - return 0; -} - -static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - u8 _snr = ~ves1x93_readreg (state, 0x1c); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f; - - if (*ucblocks == 0x7f) - *ucblocks = 0xffffffff; /* counter overflow... */ - - ves1x93_writereg (state, 0x18, 0x00); /* reset the counter */ - ves1x93_writereg (state, 0x18, 0x80); /* dto. */ - - return 0; -} - -static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, p); - if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); - } - ves1x93_set_inversion (state, p->inversion); - ves1x93_set_fec (state, p->u.qpsk.fec_inner); - ves1x93_set_symbolrate (state, p->u.qpsk.symbol_rate); - state->inversion = p->inversion; - - return 0; -} - -static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ves1x93_state* state = fe->demodulator_priv; - int afc; - - afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; - afc = (afc * (int)(p->u.qpsk.symbol_rate/1000/8))/16; - - p->frequency -= afc; - - /* - * inversion indicator is only valid - * if auto inversion was used - */ - if (state->inversion == INVERSION_AUTO) - p->inversion = (ves1x93_readreg (state, 0x0f) & 2) ? - INVERSION_OFF : INVERSION_ON; - p->u.qpsk.fec_inner = ves1x93_get_fec (state); - /* XXX FIXME: timing offset !! */ - - return 0; -} - -static int ves1x93_sleep(struct dvb_frontend* fe) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - return ves1x93_writereg (state, 0x00, 0x08); -} - -static void ves1x93_release(struct dvb_frontend* fe) -{ - struct ves1x93_state* state = fe->demodulator_priv; - kfree(state); -} - -static int ves1x93_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct ves1x93_state* state = fe->demodulator_priv; - - if (enable) { - return ves1x93_writereg(state, 0x00, 0x11); - } else { - return ves1x93_writereg(state, 0x00, 0x01); - } -} - -static struct dvb_frontend_ops ves1x93_ops; - -struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c) -{ - struct ves1x93_state* state = NULL; - u8 identity; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL); - if (state == NULL) goto error; - - /* setup the state */ - state->config = config; - state->i2c = i2c; - state->inversion = INVERSION_OFF; - - /* check if the demod is there + identify it */ - identity = ves1x93_readreg(state, 0x1e); - switch (identity) { - case 0xdc: /* VES1893A rev1 */ - printk("ves1x93: Detected ves1893a rev1\n"); - state->demod_type = DEMOD_VES1893; - state->init_1x93_tab = init_1893_tab; - state->init_1x93_wtab = init_1893_wtab; - state->tab_size = sizeof(init_1893_tab); - break; - - case 0xdd: /* VES1893A rev2 */ - printk("ves1x93: Detected ves1893a rev2\n"); - state->demod_type = DEMOD_VES1893; - state->init_1x93_tab = init_1893_tab; - state->init_1x93_wtab = init_1893_wtab; - state->tab_size = sizeof(init_1893_tab); - break; - - case 0xde: /* VES1993 */ - printk("ves1x93: Detected ves1993\n"); - state->demod_type = DEMOD_VES1993; - state->init_1x93_tab = init_1993_tab; - state->init_1x93_wtab = init_1993_wtab; - state->tab_size = sizeof(init_1993_tab); - break; - - default: - goto error; - } - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ves1x93_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops ves1x93_ops = { - - .info = { - .name = "VLSI VES1x93 DVB-S", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - /* .symbol_rate_tolerance = ???,*/ - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = ves1x93_release, - - .init = ves1x93_init, - .sleep = ves1x93_sleep, - .i2c_gate_ctrl = ves1x93_i2c_gate_ctrl, - - .set_frontend = ves1x93_set_frontend, - .get_frontend = ves1x93_get_frontend, - - .read_status = ves1x93_read_status, - .read_ber = ves1x93_read_ber, - .read_signal_strength = ves1x93_read_signal_strength, - .read_snr = ves1x93_read_snr, - .read_ucblocks = ves1x93_read_ucblocks, - - .set_voltage = ves1x93_set_voltage, -}; - -module_param(debug, int, 0644); - -MODULE_DESCRIPTION("VLSI VES1x93 DVB-S Demodulator driver"); -MODULE_AUTHOR("Ralph Metzler"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ves1x93_attach); diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h deleted file mode 100644 index 8a5a49e808f..00000000000 --- a/drivers/media/dvb/frontends/ves1x93.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - Driver for VES1893 and VES1993 QPSK Demodulators - - Copyright (C) 1999 Convergence Integrated Media GmbH <ralph@convergence.de> - Copyright (C) 2001 Ronny Strutz <3des@elitedvb.de> - Copyright (C) 2002 Dennis Noermann <dennis.noermann@noernet.de> - Copyright (C) 2002-2003 Andreas Oberritter <obi@linuxtv.org> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef VES1X93_H -#define VES1X93_H - -#include <linux/dvb/frontend.h> - -struct ves1x93_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* value of XIN to use */ - u32 xin; - - /* should PWM be inverted? */ - u8 invert_pwm:1; -}; - -#if defined(CONFIG_DVB_VES1X93) || (defined(CONFIG_DVB_VES1X93_MODULE) && defined(MODULE)) -extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c); -#else -static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, - struct i2c_adapter* i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif // CONFIG_DVB_VES1X93 - -#endif // VES1X93_H diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h deleted file mode 100644 index 07f3fc0998f..00000000000 --- a/drivers/media/dvb/frontends/z0194a.h +++ /dev/null @@ -1,85 +0,0 @@ -/* z0194a.h Sharp z0194a tuner support -* -* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by) -* -* This program is free software; you can redistribute it and/or modify it -* under the terms of the GNU General Public License as published by the -* Free Software Foundation, version 2. -* -* see Documentation/dvb/README.dvb-usb for more information -*/ - -#ifndef Z0194A -#define Z0194A - -static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe, - u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { - aclk = 0xb7; bclk = 0x47; } - else if (srate < 3000000) { - aclk = 0xb7; bclk = 0x4b; } - else if (srate < 7000000) { - aclk = 0xb7; bclk = 0x4f; } - else if (srate < 14000000) { - aclk = 0xb7; bclk = 0x53; } - else if (srate < 30000000) { - aclk = 0xb6; bclk = 0x53; } - else if (srate < 45000000) { - aclk = 0xb4; bclk = 0x51; } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - - return 0; -} - -static u8 sharp_z0194a_inittab[] = { - 0x01, 0x15, - 0x02, 0x00, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, /* AGC2 0x3d */ - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, /* lock detector threshold */ - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, /* out imp: normal out type: parallel FEC mode:0 */ - 0x29, 0x1e, /* 1/2 threshold */ - 0x2a, 0x14, /* 2/3 threshold */ - 0x2b, 0x0f, /* 3/4 threshold */ - 0x2c, 0x09, /* 5/6 threshold */ - 0x2d, 0x05, /* 7/8 threshold */ - 0x2e, 0x01, - 0x31, 0x1f, /* test all FECs */ - 0x32, 0x19, /* viterbi and synchro search */ - 0x33, 0xfc, /* rs control */ - 0x34, 0x93, /* error control */ - 0x0f, 0x52, - 0xff, 0xff -}; - -#endif diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c deleted file mode 100644 index 170720b0281..00000000000 --- a/drivers/media/dvb/frontends/zl10353.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <asm/div64.h> - -#include "dvb_frontend.h" -#include "zl10353_priv.h" -#include "zl10353.h" - -struct zl10353_state { - struct i2c_adapter *i2c; - struct dvb_frontend frontend; - - struct zl10353_config config; - - enum fe_bandwidth bandwidth; -}; - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk(KERN_DEBUG "zl10353: " args); \ - } while (0) - -static int debug_regs; - -static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 buf[2] = { reg, val }; - struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, - .buf = buf, .len = 2 }; - int err = i2c_transfer(state->i2c, &msg, 1); - if (err != 1) { - printk("zl10353: write to reg %x failed (err = %d)!\n", reg, err); - return err; - } - return 0; -} - -static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) -{ - int err, i; - for (i = 0; i < ilen - 1; i++) - if ((err = zl10353_single_write(fe, ibuf[0] + i, ibuf[i + 1]))) - return err; - - return 0; -} - -static int zl10353_read_register(struct zl10353_state *state, u8 reg) -{ - int ret; - u8 b0[1] = { reg }; - u8 b1[1] = { 0 }; - struct i2c_msg msg[2] = { { .addr = state->config.demod_address, - .flags = 0, - .buf = b0, .len = 1 }, - { .addr = state->config.demod_address, - .flags = I2C_M_RD, - .buf = b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: readreg error (reg=%d, ret==%i)\n", - __func__, reg, ret); - return ret; - } - - return b1[0]; -} - -static void zl10353_dump_regs(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - char buf[52], buf2[4]; - int ret; - u8 reg; - - /* Dump all registers. */ - for (reg = 0; ; reg++) { - if (reg % 16 == 0) { - if (reg) - printk(KERN_DEBUG "%s\n", buf); - sprintf(buf, "%02x: ", reg); - } - ret = zl10353_read_register(state, reg); - if (ret >= 0) - sprintf(buf2, "%02x ", (u8)ret); - else - strcpy(buf2, "-- "); - strcat(buf, buf2); - if (reg == 0xff) - break; - } - printk(KERN_DEBUG "%s\n", buf); -} - -static void zl10353_calc_nominal_rate(struct dvb_frontend *fe, - enum fe_bandwidth bandwidth, - u16 *nominal_rate) -{ - struct zl10353_state *state = fe->demodulator_priv; - u32 adc_clock = 450560; /* 45.056 MHz */ - u64 value; - u8 bw; - - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - - switch (bandwidth) { - case BANDWIDTH_6_MHZ: - bw = 6; - break; - case BANDWIDTH_7_MHZ: - bw = 7; - break; - case BANDWIDTH_8_MHZ: - default: - bw = 8; - break; - } - - value = (u64)10 * (1 << 23) / 7 * 125; - value = (bw * value) + adc_clock / 2; - do_div(value, adc_clock); - *nominal_rate = value; - - dprintk("%s: bw %d, adc_clock %d => 0x%x\n", - __func__, bw, adc_clock, *nominal_rate); -} - -static void zl10353_calc_input_freq(struct dvb_frontend *fe, - u16 *input_freq) -{ - struct zl10353_state *state = fe->demodulator_priv; - u32 adc_clock = 450560; /* 45.056 MHz */ - int if2 = 361667; /* 36.1667 MHz */ - int ife; - u64 value; - - if (state->config.adc_clock) - adc_clock = state->config.adc_clock; - if (state->config.if2) - if2 = state->config.if2; - - if (adc_clock >= if2 * 2) - ife = if2; - else { - ife = adc_clock - (if2 % adc_clock); - if (ife > adc_clock / 2) - ife = adc_clock - ife; - } - value = (u64)65536 * ife + adc_clock / 2; - do_div(value, adc_clock); - *input_freq = -value; - - dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n", - __func__, if2, ife, adc_clock, -(int)value, *input_freq); -} - -static int zl10353_sleep(struct dvb_frontend *fe) -{ - static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; - - zl10353_write(fe, zl10353_softdown, sizeof(zl10353_softdown)); - return 0; -} - -static int zl10353_set_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct zl10353_state *state = fe->demodulator_priv; - u16 nominal_rate, input_freq; - u8 pllbuf[6] = { 0x67 }, acq_ctl = 0; - u16 tps = 0; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - - zl10353_single_write(fe, RESET, 0x80); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x01); - udelay(200); - zl10353_single_write(fe, 0xEA, 0x00); - - zl10353_single_write(fe, AGC_TARGET, 0x28); - - if (op->transmission_mode != TRANSMISSION_MODE_AUTO) - acq_ctl |= (1 << 0); - if (op->guard_interval != GUARD_INTERVAL_AUTO) - acq_ctl |= (1 << 1); - zl10353_single_write(fe, ACQ_CTL, acq_ctl); - - switch (op->bandwidth) { - case BANDWIDTH_6_MHZ: - /* These are extrapolated from the 7 and 8MHz values */ - zl10353_single_write(fe, MCLK_RATIO, 0x97); - zl10353_single_write(fe, 0x64, 0x34); - zl10353_single_write(fe, 0xcc, 0xdd); - break; - case BANDWIDTH_7_MHZ: - zl10353_single_write(fe, MCLK_RATIO, 0x86); - zl10353_single_write(fe, 0x64, 0x35); - zl10353_single_write(fe, 0xcc, 0x73); - break; - case BANDWIDTH_8_MHZ: - default: - zl10353_single_write(fe, MCLK_RATIO, 0x75); - zl10353_single_write(fe, 0x64, 0x36); - zl10353_single_write(fe, 0xcc, 0x73); - } - - zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate); - zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate)); - zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate)); - state->bandwidth = op->bandwidth; - - zl10353_calc_input_freq(fe, &input_freq); - zl10353_single_write(fe, INPUT_FREQ_1, msb(input_freq)); - zl10353_single_write(fe, INPUT_FREQ_0, lsb(input_freq)); - - /* Hint at TPS settings */ - switch (op->code_rate_HP) { - case FEC_2_3: - tps |= (1 << 7); - break; - case FEC_3_4: - tps |= (2 << 7); - break; - case FEC_5_6: - tps |= (3 << 7); - break; - case FEC_7_8: - tps |= (4 << 7); - break; - case FEC_1_2: - case FEC_AUTO: - break; - default: - return -EINVAL; - } - - switch (op->code_rate_LP) { - case FEC_2_3: - tps |= (1 << 4); - break; - case FEC_3_4: - tps |= (2 << 4); - break; - case FEC_5_6: - tps |= (3 << 4); - break; - case FEC_7_8: - tps |= (4 << 4); - break; - case FEC_1_2: - case FEC_AUTO: - break; - case FEC_NONE: - if (op->hierarchy_information == HIERARCHY_AUTO || - op->hierarchy_information == HIERARCHY_NONE) - break; - default: - return -EINVAL; - } - - switch (op->constellation) { - case QPSK: - break; - case QAM_AUTO: - case QAM_16: - tps |= (1 << 13); - break; - case QAM_64: - tps |= (2 << 13); - break; - default: - return -EINVAL; - } - - switch (op->transmission_mode) { - case TRANSMISSION_MODE_2K: - case TRANSMISSION_MODE_AUTO: - break; - case TRANSMISSION_MODE_8K: - tps |= (1 << 0); - break; - default: - return -EINVAL; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - break; - case GUARD_INTERVAL_1_16: - tps |= (1 << 2); - break; - case GUARD_INTERVAL_1_8: - tps |= (2 << 2); - break; - case GUARD_INTERVAL_1_4: - tps |= (3 << 2); - break; - default: - return -EINVAL; - } - - switch (op->hierarchy_information) { - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - break; - case HIERARCHY_1: - tps |= (1 << 10); - break; - case HIERARCHY_2: - tps |= (2 << 10); - break; - case HIERARCHY_4: - tps |= (3 << 10); - break; - default: - return -EINVAL; - } - - zl10353_single_write(fe, TPS_GIVEN_1, msb(tps)); - zl10353_single_write(fe, TPS_GIVEN_0, lsb(tps)); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - - /* - * If there is no tuner attached to the secondary I2C bus, we call - * set_params to program a potential tuner attached somewhere else. - * Otherwise, we update the PLL registers via calc_regs. - */ - if (state->config.no_tuner) { - if (fe->ops.tuner_ops.set_params) { - fe->ops.tuner_ops.set_params(fe, param); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } - } else if (fe->ops.tuner_ops.calc_regs) { - fe->ops.tuner_ops.calc_regs(fe, param, pllbuf + 1, 5); - pllbuf[1] <<= 1; - zl10353_write(fe, pllbuf, sizeof(pllbuf)); - } - - zl10353_single_write(fe, 0x5F, 0x13); - - /* If no attached tuner or invalid PLL registers, just start the FSM. */ - if (state->config.no_tuner || fe->ops.tuner_ops.calc_regs == NULL) - zl10353_single_write(fe, FSM_GO, 0x01); - else - zl10353_single_write(fe, TUNER_GO, 0x01); - - return 0; -} - -static int zl10353_get_parameters(struct dvb_frontend *fe, - struct dvb_frontend_parameters *param) -{ - struct zl10353_state *state = fe->demodulator_priv; - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - int s6, s9; - u16 tps; - static const u8 tps_fec_to_api[8] = { - FEC_1_2, - FEC_2_3, - FEC_3_4, - FEC_5_6, - FEC_7_8, - FEC_AUTO, - FEC_AUTO, - FEC_AUTO - }; - - s6 = zl10353_read_register(state, STATUS_6); - s9 = zl10353_read_register(state, STATUS_9); - if (s6 < 0 || s9 < 0) - return -EREMOTEIO; - if ((s6 & (1 << 5)) == 0 || (s9 & (1 << 4)) == 0) - return -EINVAL; /* no FE or TPS lock */ - - tps = zl10353_read_register(state, TPS_RECEIVED_1) << 8 | - zl10353_read_register(state, TPS_RECEIVED_0); - - op->code_rate_HP = tps_fec_to_api[(tps >> 7) & 7]; - op->code_rate_LP = tps_fec_to_api[(tps >> 4) & 7]; - - switch ((tps >> 13) & 3) { - case 0: - op->constellation = QPSK; - break; - case 1: - op->constellation = QAM_16; - break; - case 2: - op->constellation = QAM_64; - break; - default: - op->constellation = QAM_AUTO; - break; - } - - op->transmission_mode = (tps & 0x01) ? TRANSMISSION_MODE_8K : - TRANSMISSION_MODE_2K; - - switch ((tps >> 2) & 3) { - case 0: - op->guard_interval = GUARD_INTERVAL_1_32; - break; - case 1: - op->guard_interval = GUARD_INTERVAL_1_16; - break; - case 2: - op->guard_interval = GUARD_INTERVAL_1_8; - break; - case 3: - op->guard_interval = GUARD_INTERVAL_1_4; - break; - default: - op->guard_interval = GUARD_INTERVAL_AUTO; - break; - } - - switch ((tps >> 10) & 7) { - case 0: - op->hierarchy_information = HIERARCHY_NONE; - break; - case 1: - op->hierarchy_information = HIERARCHY_1; - break; - case 2: - op->hierarchy_information = HIERARCHY_2; - break; - case 3: - op->hierarchy_information = HIERARCHY_4; - break; - default: - op->hierarchy_information = HIERARCHY_AUTO; - break; - } - - param->frequency = 0; - op->bandwidth = state->bandwidth; - param->inversion = INVERSION_AUTO; - - return 0; -} - -static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct zl10353_state *state = fe->demodulator_priv; - int s6, s7, s8; - - if ((s6 = zl10353_read_register(state, STATUS_6)) < 0) - return -EREMOTEIO; - if ((s7 = zl10353_read_register(state, STATUS_7)) < 0) - return -EREMOTEIO; - if ((s8 = zl10353_read_register(state, STATUS_8)) < 0) - return -EREMOTEIO; - - *status = 0; - if (s6 & (1 << 2)) - *status |= FE_HAS_CARRIER; - if (s6 & (1 << 1)) - *status |= FE_HAS_VITERBI; - if (s6 & (1 << 5)) - *status |= FE_HAS_LOCK; - if (s7 & (1 << 4)) - *status |= FE_HAS_SYNC; - if (s8 & (1 << 6)) - *status |= FE_HAS_SIGNAL; - - if ((*status & (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) != - (FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)) - *status &= ~FE_HAS_LOCK; - - return 0; -} - -static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct zl10353_state *state = fe->demodulator_priv; - - *ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 | - zl10353_read_register(state, RS_ERR_CNT_1) << 8 | - zl10353_read_register(state, RS_ERR_CNT_0); - - return 0; -} - -static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct zl10353_state *state = fe->demodulator_priv; - - u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 | - zl10353_read_register(state, AGC_GAIN_0) << 2 | 3; - - *strength = ~signal; - - return 0; -} - -static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 _snr; - - if (debug_regs) - zl10353_dump_regs(fe); - - _snr = zl10353_read_register(state, SNR); - *snr = (_snr << 8) | _snr; - - return 0; -} - -static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct zl10353_state *state = fe->demodulator_priv; - - *ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 | - zl10353_read_register(state, RS_UBC_0); - - return 0; -} - -static int zl10353_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings - *fe_tune_settings) -{ - fe_tune_settings->min_delay_ms = 1000; - fe_tune_settings->step_size = 0; - fe_tune_settings->max_drift = 0; - - return 0; -} - -static int zl10353_init(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 zl10353_reset_attach[6] = { 0x50, 0x03, 0x64, 0x46, 0x15, 0x0F }; - int rc = 0; - - if (debug_regs) - zl10353_dump_regs(fe); - if (state->config.parallel_ts) - zl10353_reset_attach[2] &= ~0x20; - - /* Do a "hard" reset if not already done */ - if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] || - zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) { - rc = zl10353_write(fe, zl10353_reset_attach, - sizeof(zl10353_reset_attach)); - if (debug_regs) - zl10353_dump_regs(fe); - } - - return 0; -} - -static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct zl10353_state *state = fe->demodulator_priv; - u8 val = 0x0a; - - if (state->config.no_tuner) { - /* No tuner attached to the internal I2C bus */ - /* If set enable I2C bridge, the main I2C bus stopped hardly */ - return 0; - } - - if (enable) - val |= 0x10; - - return zl10353_single_write(fe, 0x62, val); -} - -static void zl10353_release(struct dvb_frontend *fe) -{ - struct zl10353_state *state = fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops zl10353_ops; - -struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c) -{ - struct zl10353_state *state = NULL; - - /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); - if (state == NULL) - goto error; - - /* setup the state */ - state->i2c = i2c; - memcpy(&state->config, config, sizeof(struct zl10353_config)); - - /* check if the demod is there */ - if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353) - goto error; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &zl10353_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - - return &state->frontend; -error: - kfree(state); - return NULL; -} - -static struct dvb_frontend_ops zl10353_ops = { - - .info = { - .name = "Zarlink ZL10353 DVB-T", - .type = FE_OFDM, - .frequency_min = 174000000, - .frequency_max = 862000000, - .frequency_stepsize = 166667, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - - .release = zl10353_release, - - .init = zl10353_init, - .sleep = zl10353_sleep, - .i2c_gate_ctrl = zl10353_i2c_gate_ctrl, - .write = zl10353_write, - - .set_frontend = zl10353_set_parameters, - .get_frontend = zl10353_get_parameters, - .get_tune_settings = zl10353_get_tune_settings, - - .read_status = zl10353_read_status, - .read_ber = zl10353_read_ber, - .read_signal_strength = zl10353_read_signal_strength, - .read_snr = zl10353_read_snr, - .read_ucblocks = zl10353_read_ucblocks, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -module_param(debug_regs, int, 0644); -MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); - -MODULE_DESCRIPTION("Zarlink ZL10353 DVB-T demodulator driver"); -MODULE_AUTHOR("Chris Pascoe"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(zl10353_attach); diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h deleted file mode 100644 index fdbb88ff75f..00000000000 --- a/drivers/media/dvb/frontends/zl10353.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef ZL10353_H -#define ZL10353_H - -#include <linux/dvb/frontend.h> - -struct zl10353_config -{ - /* demodulator's I2C address */ - u8 demod_address; - - /* frequencies in units of 0.1kHz */ - int adc_clock; /* default: 450560 (45.056 MHz) */ - int if2; /* default: 361667 (36.1667 MHz) */ - - /* set if no pll is connected to the secondary i2c bus */ - int no_tuner; - - /* set if parallel ts output is required */ - int parallel_ts; -}; - -#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE)) -extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_ZL10353 */ - -#endif /* ZL10353_H */ diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h deleted file mode 100644 index 055ff1f7e34..00000000000 --- a/drivers/media/dvb/frontends/zl10353_priv.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Driver for Zarlink DVB-T ZL10353 demodulator - * - * Copyright (C) 2006, 2007 Christopher Pascoe <c.pascoe@itee.uq.edu.au> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ZL10353_PRIV_ -#define _ZL10353_PRIV_ - -#define ID_ZL10353 0x14 - -#define msb(x) (((x) >> 8) & 0xff) -#define lsb(x) ((x) & 0xff) - -enum zl10353_reg_addr { - INTERRUPT_0 = 0x00, - INTERRUPT_1 = 0x01, - INTERRUPT_2 = 0x02, - INTERRUPT_3 = 0x03, - INTERRUPT_4 = 0x04, - INTERRUPT_5 = 0x05, - STATUS_6 = 0x06, - STATUS_7 = 0x07, - STATUS_8 = 0x08, - STATUS_9 = 0x09, - AGC_GAIN_1 = 0x0A, - AGC_GAIN_0 = 0x0B, - SNR = 0x10, - RS_ERR_CNT_2 = 0x11, - RS_ERR_CNT_1 = 0x12, - RS_ERR_CNT_0 = 0x13, - RS_UBC_1 = 0x14, - RS_UBC_0 = 0x15, - TPS_RECEIVED_1 = 0x1D, - TPS_RECEIVED_0 = 0x1E, - TPS_CURRENT_1 = 0x1F, - TPS_CURRENT_0 = 0x20, - RESET = 0x55, - AGC_TARGET = 0x56, - MCLK_RATIO = 0x5C, - ACQ_CTL = 0x5E, - TRL_NOMINAL_RATE_1 = 0x65, - TRL_NOMINAL_RATE_0 = 0x66, - INPUT_FREQ_1 = 0x6C, - INPUT_FREQ_0 = 0x6D, - TPS_GIVEN_1 = 0x6E, - TPS_GIVEN_0 = 0x6F, - TUNER_GO = 0x70, - FSM_GO = 0x71, - CHIP_ID = 0x7F, - CHAN_STEP_1 = 0xE4, - CHAN_STEP_0 = 0xE5, - OFDM_LOCK_TIME = 0xE7, - FEC_LOCK_TIME = 0xE8, - ACQ_DELAY = 0xE9, -}; - -#endif /* _ZL10353_PRIV_ */ diff --git a/drivers/media/dvb/pluto2/Kconfig b/drivers/media/dvb/pluto2/Kconfig deleted file mode 100644 index 7d8e6e87bdb..00000000000 --- a/drivers/media/dvb/pluto2/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config DVB_PLUTO2 - tristate "Pluto2 cards" - depends on DVB_CORE && PCI && I2C - select I2C_ALGOBIT - select DVB_TDA1004X - help - Support for PCI cards based on the Pluto2 FPGA like the Satelco - Easywatch Mobile Terrestrial DVB-T Receiver. - - Since these cards have no MPEG decoder onboard, they transmit - only compressed MPEG data over the PCI bus, so you need - an external software decoder to watch TV on your computer. - - Say Y or M if you own such a device and want to use it. - diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile deleted file mode 100644 index 7ac128724df..00000000000 --- a/drivers/media/dvb/pluto2/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_DVB_PLUTO2) += pluto2.o - -EXTRA_CFLAGS += -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 deleted file mode 100644 index d101b304e9b..00000000000 --- a/drivers/media/dvb/pluto2/pluto2.c +++ /dev/null @@ -1,819 +0,0 @@ -/* - * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T] - * - * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org> - * - * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/ - * by Dany Salman <salmandany@yahoo.fr> - * Copyright (c) 2004 TDF - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/dma-mapping.h> - -#include "demux.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dvb_net.h" -#include "dvbdev.h" -#include "tda1004x.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define DRIVER_NAME "pluto2" - -#define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */ -#define REG_PCAR 0x0020 /* PC address register */ -#define REG_TSCR 0x0024 /* TS ctrl & status */ -#define REG_MISC 0x0028 /* miscellaneous */ -#define REG_MMAC 0x002c /* MSB MAC address */ -#define REG_IMAC 0x0030 /* ISB MAC address */ -#define REG_LMAC 0x0034 /* LSB MAC address */ -#define REG_SPID 0x0038 /* SPI data */ -#define REG_SLCS 0x003c /* serial links ctrl/status */ - -#define PID0_NOFIL (0x0001 << 16) -#define PIDn_ENP (0x0001 << 15) -#define PID0_END (0x0001 << 14) -#define PID0_AFIL (0x0001 << 13) -#define PIDn_PID (0x1fff << 0) - -#define TSCR_NBPACKETS (0x00ff << 24) -#define TSCR_DEM (0x0001 << 17) -#define TSCR_DE (0x0001 << 16) -#define TSCR_RSTN (0x0001 << 15) -#define TSCR_MSKO (0x0001 << 14) -#define TSCR_MSKA (0x0001 << 13) -#define TSCR_MSKL (0x0001 << 12) -#define TSCR_OVR (0x0001 << 11) -#define TSCR_AFUL (0x0001 << 10) -#define TSCR_LOCK (0x0001 << 9) -#define TSCR_IACK (0x0001 << 8) -#define TSCR_ADEF (0x007f << 0) - -#define MISC_DVR (0x0fff << 4) -#define MISC_ALED (0x0001 << 3) -#define MISC_FRST (0x0001 << 2) -#define MISC_LED1 (0x0001 << 1) -#define MISC_LED0 (0x0001 << 0) - -#define SPID_SPIDR (0x00ff << 0) - -#define SLCS_SCL (0x0001 << 7) -#define SLCS_SDA (0x0001 << 6) -#define SLCS_CSN (0x0001 << 2) -#define SLCS_OVR (0x0001 << 1) -#define SLCS_SWC (0x0001 << 0) - -#define TS_DMA_PACKETS (8) -#define TS_DMA_BYTES (188 * TS_DMA_PACKETS) - -#define I2C_ADDR_TDA10046 0x10 -#define I2C_ADDR_TUA6034 0xc2 -#define NHWFILTERS 8 - -struct pluto { - /* pci */ - struct pci_dev *pdev; - u8 __iomem *io_mem; - - /* dvb */ - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - struct dmxdev dmxdev; - struct dvb_adapter dvb_adapter; - struct dvb_demux demux; - struct dvb_frontend *fe; - struct dvb_net dvbnet; - unsigned int full_ts_users; - unsigned int users; - - /* i2c */ - struct i2c_algo_bit_data i2c_bit; - struct i2c_adapter i2c_adap; - unsigned int i2cbug; - - /* irq */ - unsigned int overflow; - - /* dma */ - dma_addr_t dma_addr; - u8 dma_buf[TS_DMA_BYTES]; - u8 dummy[4096]; -}; - -static inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed) -{ - return container_of(feed->demux, struct pluto, demux); -} - -static inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe) -{ - return container_of(fe->dvb, struct pluto, dvb_adapter); -} - -static inline u32 pluto_readreg(struct pluto *pluto, u32 reg) -{ - return readl(&pluto->io_mem[reg]); -} - -static inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val) -{ - writel(val, &pluto->io_mem[reg]); -} - -static inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits) -{ - u32 val = readl(&pluto->io_mem[reg]); - val &= ~mask; - val |= bits; - writel(val, &pluto->io_mem[reg]); -} - -static void pluto_write_tscr(struct pluto *pluto, u32 val) -{ - /* set the number of packets */ - val &= ~TSCR_ADEF; - val |= TS_DMA_PACKETS / 2; - - pluto_writereg(pluto, REG_TSCR, val); -} - -static void pluto_setsda(void *data, int state) -{ - struct pluto *pluto = data; - - if (state) - pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA); - else - pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0); -} - -static void pluto_setscl(void *data, int state) -{ - struct pluto *pluto = data; - - if (state) - pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL); - else - pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0); - - /* try to detect i2c_inb() to workaround hardware bug: - * reset SDA to high after SCL has been set to low */ - if ((state) && (pluto->i2cbug == 0)) { - pluto->i2cbug = 1; - } else { - if ((!state) && (pluto->i2cbug == 1)) - pluto_setsda(pluto, 1); - pluto->i2cbug = 0; - } -} - -static int pluto_getsda(void *data) -{ - struct pluto *pluto = data; - - return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA; -} - -static int pluto_getscl(void *data) -{ - struct pluto *pluto = data; - - return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL; -} - -static void pluto_reset_frontend(struct pluto *pluto, int reenable) -{ - u32 val = pluto_readreg(pluto, REG_MISC); - - if (val & MISC_FRST) { - val &= ~MISC_FRST; - pluto_writereg(pluto, REG_MISC, val); - } - if (reenable) { - val |= MISC_FRST; - pluto_writereg(pluto, REG_MISC, val); - } -} - -static void pluto_reset_ts(struct pluto *pluto, int reenable) -{ - u32 val = pluto_readreg(pluto, REG_TSCR); - - if (val & TSCR_RSTN) { - val &= ~TSCR_RSTN; - pluto_write_tscr(pluto, val); - } - if (reenable) { - val |= TSCR_RSTN; - pluto_write_tscr(pluto, val); - } -} - -static void pluto_set_dma_addr(struct pluto *pluto) -{ - pluto_writereg(pluto, REG_PCAR, pluto->dma_addr); -} - -static int __devinit pluto_dma_map(struct pluto *pluto) -{ - pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, - TS_DMA_BYTES, PCI_DMA_FROMDEVICE); - - return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); -} - -static void pluto_dma_unmap(struct pluto *pluto) -{ - pci_unmap_single(pluto->pdev, pluto->dma_addr, - TS_DMA_BYTES, PCI_DMA_FROMDEVICE); -} - -static int pluto_start_feed(struct dvb_demux_feed *f) -{ - struct pluto *pluto = feed_to_pluto(f); - - /* enable PID filtering */ - if (pluto->users++ == 0) - pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0); - - if ((f->pid < 0x2000) && (f->index < NHWFILTERS)) - pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid); - else if (pluto->full_ts_users++ == 0) - pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL); - - return 0; -} - -static int pluto_stop_feed(struct dvb_demux_feed *f) -{ - struct pluto *pluto = feed_to_pluto(f); - - /* disable PID filtering */ - if (--pluto->users == 0) - pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL); - - if ((f->pid < 0x2000) && (f->index < NHWFILTERS)) - pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff); - else if (--pluto->full_ts_users == 0) - pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0); - - return 0; -} - -static void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) -{ - /* synchronize the DMA transfer with the CPU - * first so that we see updated contents. */ - pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr, - TS_DMA_BYTES, PCI_DMA_FROMDEVICE); - - /* Workaround for broken hardware: - * [1] On startup NBPACKETS seems to contain an uninitialized value, - * but no packets have been transfered. - * [2] Sometimes (actually very often) NBPACKETS stays at zero - * although one packet has been transfered. - * [3] Sometimes (actually rarely), the card gets into an erroneous - * mode where it continuously generates interrupts, claiming it - * has recieved nbpackets>TS_DMA_PACKETS packets, but no packet - * has been transfered. Only a reset seems to solve this - */ - if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { - unsigned int i = 0; - while (pluto->dma_buf[i] == 0x47) - i += 188; - nbpackets = i / 188; - if (i == 0) { - pluto_reset_ts(pluto, 1); - dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n"); - } - } - - dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); - - /* clear the dma buffer. this is needed to be able to identify - * new valid ts packets above */ - memset(pluto->dma_buf, 0, nbpackets * 188); - - /* reset the dma address */ - pluto_set_dma_addr(pluto); - - /* sync the buffer and give it back to the card */ - pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr, - TS_DMA_BYTES, PCI_DMA_FROMDEVICE); -} - -static irqreturn_t pluto_irq(int irq, void *dev_id) -{ - struct pluto *pluto = dev_id; - u32 tscr; - - /* check whether an interrupt occured on this device */ - tscr = pluto_readreg(pluto, REG_TSCR); - if (!(tscr & (TSCR_DE | TSCR_OVR))) - return IRQ_NONE; - - if (tscr == 0xffffffff) { - // FIXME: maybe recover somehow - dev_err(&pluto->pdev->dev, "card hung up :(\n"); - return IRQ_HANDLED; - } - - /* dma end interrupt */ - if (tscr & TSCR_DE) { - pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24); - /* overflow interrupt */ - if (tscr & TSCR_OVR) - pluto->overflow++; - if (pluto->overflow) { - dev_err(&pluto->pdev->dev, "overflow irq (%d)\n", - pluto->overflow); - pluto_reset_ts(pluto, 1); - pluto->overflow = 0; - } - } else if (tscr & TSCR_OVR) { - pluto->overflow++; - } - - /* ACK the interrupt */ - pluto_write_tscr(pluto, tscr | TSCR_IACK); - - return IRQ_HANDLED; -} - -static void __devinit pluto_enable_irqs(struct pluto *pluto) -{ - u32 val = pluto_readreg(pluto, REG_TSCR); - - /* disable AFUL and LOCK interrupts */ - val |= (TSCR_MSKA | TSCR_MSKL); - /* enable DMA and OVERFLOW interrupts */ - val &= ~(TSCR_DEM | TSCR_MSKO); - /* clear pending interrupts */ - val |= TSCR_IACK; - - pluto_write_tscr(pluto, val); -} - -static void pluto_disable_irqs(struct pluto *pluto) -{ - u32 val = pluto_readreg(pluto, REG_TSCR); - - /* disable all interrupts */ - val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL); - /* clear pending interrupts */ - val |= TSCR_IACK; - - pluto_write_tscr(pluto, val); -} - -static int __devinit pluto_hw_init(struct pluto *pluto) -{ - pluto_reset_frontend(pluto, 1); - - /* set automatic LED control by FPGA */ - pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED); - - /* set data endianess */ -#ifdef __LITTLE_ENDIAN - pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END); -#else - pluto_rw(pluto, REG_PIDn(0), PID0_END, 0); -#endif - /* map DMA and set address */ - pluto_dma_map(pluto); - pluto_set_dma_addr(pluto); - - /* enable interrupts */ - pluto_enable_irqs(pluto); - - /* reset TS logic */ - pluto_reset_ts(pluto, 1); - - return 0; -} - -static void pluto_hw_exit(struct pluto *pluto) -{ - /* disable interrupts */ - pluto_disable_irqs(pluto); - - pluto_reset_ts(pluto, 0); - - /* LED: disable automatic control, enable yellow, disable green */ - pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1); - - /* unmap DMA */ - pluto_dma_unmap(pluto); - - pluto_reset_frontend(pluto, 0); -} - -static inline u32 divide(u32 numerator, u32 denominator) -{ - if (denominator == 0) - return ~0; - - return (numerator + denominator / 2) / denominator; -} - -/* LG Innotek TDTE-E001P (Infineon TUA6034) */ -static int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *p) -{ - struct pluto *pluto = frontend_to_pluto(fe); - struct i2c_msg msg; - int ret; - u8 buf[4]; - u32 div; - - // Fref = 166.667 Hz - // Fref * 3 = 500.000 Hz - // IF = 36166667 - // IF / Fref = 217 - //div = divide(p->frequency + 36166667, 166667); - div = divide(p->frequency * 3, 500000) + 217; - buf[0] = (div >> 8) & 0x7f; - buf[1] = (div >> 0) & 0xff; - - if (p->frequency < 611000000) - buf[2] = 0xb4; - else if (p->frequency < 811000000) - buf[2] = 0xbc; - else - buf[2] = 0xf4; - - // VHF: 174-230 MHz - // center: 350 MHz - // UHF: 470-862 MHz - if (p->frequency < 350000000) - buf[3] = 0x02; - else - buf[3] = 0x04; - - if (p->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) - buf[3] |= 0x08; - - if (sizeof(buf) == 6) { - buf[4] = buf[2]; - buf[4] &= ~0x1c; - buf[4] |= 0x18; - - buf[5] = (0 << 7) | (2 << 4); - } - - msg.addr = I2C_ADDR_TUA6034 >> 1; - msg.flags = 0; - msg.buf = buf; - msg.len = sizeof(buf); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); - if (ret < 0) - return ret; - else if (ret == 0) - return -EREMOTEIO; - - return 0; -} - -static int pluto2_request_firmware(struct dvb_frontend *fe, - const struct firmware **fw, char *name) -{ - struct pluto *pluto = frontend_to_pluto(fe); - - return request_firmware(fw, name, &pluto->pdev->dev); -} - -static struct tda1004x_config pluto2_fe_config __devinitdata = { - .demod_address = I2C_ADDR_TDA10046 >> 1, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = pluto2_request_firmware, -}; - -static int __devinit frontend_init(struct pluto *pluto) -{ - int ret; - - pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap); - if (!pluto->fe) { - dev_err(&pluto->pdev->dev, "could not attach frontend\n"); - return -ENODEV; - } - pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params; - - ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); - if (ret < 0) { - if (pluto->fe->ops.release) - pluto->fe->ops.release(pluto->fe); - return ret; - } - - return 0; -} - -static void __devinit pluto_read_rev(struct pluto *pluto) -{ - u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR; - dev_info(&pluto->pdev->dev, "board revision %d.%d\n", - (val >> 12) & 0x0f, (val >> 4) & 0xff); -} - -static void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac) -{ - u32 val = pluto_readreg(pluto, REG_MMAC); - mac[0] = (val >> 8) & 0xff; - mac[1] = (val >> 0) & 0xff; - - val = pluto_readreg(pluto, REG_IMAC); - mac[2] = (val >> 8) & 0xff; - mac[3] = (val >> 0) & 0xff; - - val = pluto_readreg(pluto, REG_LMAC); - mac[4] = (val >> 8) & 0xff; - mac[5] = (val >> 0) & 0xff; - - dev_info(&pluto->pdev->dev, "MAC %pM\n", mac); -} - -static int __devinit pluto_read_serial(struct pluto *pluto) -{ - struct pci_dev *pdev = pluto->pdev; - unsigned int i, j; - u8 __iomem *cis; - - cis = pci_iomap(pdev, 1, 0); - if (!cis) - return -EIO; - - dev_info(&pdev->dev, "S/N "); - - for (i = 0xe0; i < 0x100; i += 4) { - u32 val = readl(&cis[i]); - for (j = 0; j < 32; j += 8) { - if ((val & 0xff) == 0xff) - goto out; - printk("%c", val & 0xff); - val >>= 8; - } - } -out: - printk("\n"); - pci_iounmap(pdev, cis); - - return 0; -} - -static int __devinit pluto2_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct pluto *pluto; - struct dvb_adapter *dvb_adapter; - struct dvb_demux *dvbdemux; - struct dmx_demux *dmx; - int ret = -ENOMEM; - - pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL); - if (!pluto) - goto out; - - pluto->pdev = pdev; - - ret = pci_enable_device(pdev); - if (ret < 0) - goto err_kfree; - - /* enable interrupts */ - pci_write_config_dword(pdev, 0x6c, 0x8000); - - ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (ret < 0) - goto err_pci_disable_device; - - pci_set_master(pdev); - - ret = pci_request_regions(pdev, DRIVER_NAME); - if (ret < 0) - goto err_pci_disable_device; - - pluto->io_mem = pci_iomap(pdev, 0, 0x40); - if (!pluto->io_mem) { - ret = -EIO; - goto err_pci_release_regions; - } - - pci_set_drvdata(pdev, pluto); - - ret = request_irq(pdev->irq, pluto_irq, IRQF_SHARED, DRIVER_NAME, pluto); - if (ret < 0) - goto err_pci_iounmap; - - ret = pluto_hw_init(pluto); - if (ret < 0) - goto err_free_irq; - - /* i2c */ - i2c_set_adapdata(&pluto->i2c_adap, pluto); - strcpy(pluto->i2c_adap.name, DRIVER_NAME); - pluto->i2c_adap.owner = THIS_MODULE; - pluto->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - pluto->i2c_adap.dev.parent = &pdev->dev; - pluto->i2c_adap.algo_data = &pluto->i2c_bit; - pluto->i2c_bit.data = pluto; - pluto->i2c_bit.setsda = pluto_setsda; - pluto->i2c_bit.setscl = pluto_setscl; - pluto->i2c_bit.getsda = pluto_getsda; - pluto->i2c_bit.getscl = pluto_getscl; - pluto->i2c_bit.udelay = 10; - pluto->i2c_bit.timeout = 10; - - /* Raise SCL and SDA */ - pluto_setsda(pluto, 1); - pluto_setscl(pluto, 1); - - ret = i2c_bit_add_bus(&pluto->i2c_adap); - if (ret < 0) - goto err_pluto_hw_exit; - - /* dvb */ - ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, - THIS_MODULE, &pdev->dev, adapter_nr); - if (ret < 0) - goto err_i2c_del_adapter; - - dvb_adapter = &pluto->dvb_adapter; - - pluto_read_rev(pluto); - pluto_read_serial(pluto); - pluto_read_mac(pluto, dvb_adapter->proposed_mac); - - dvbdemux = &pluto->demux; - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = pluto_start_feed; - dvbdemux->stop_feed = pluto_stop_feed; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); - ret = dvb_dmx_init(dvbdemux); - if (ret < 0) - goto err_dvb_unregister_adapter; - - dmx = &dvbdemux->dmx; - - pluto->hw_frontend.source = DMX_FRONTEND_0; - pluto->mem_frontend.source = DMX_MEMORY_FE; - pluto->dmxdev.filternum = NHWFILTERS; - pluto->dmxdev.demux = dmx; - - ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter); - if (ret < 0) - goto err_dvb_dmx_release; - - ret = dmx->add_frontend(dmx, &pluto->hw_frontend); - if (ret < 0) - goto err_dvb_dmxdev_release; - - ret = dmx->add_frontend(dmx, &pluto->mem_frontend); - if (ret < 0) - goto err_remove_hw_frontend; - - ret = dmx->connect_frontend(dmx, &pluto->hw_frontend); - if (ret < 0) - goto err_remove_mem_frontend; - - ret = frontend_init(pluto); - if (ret < 0) - goto err_disconnect_frontend; - - dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx); -out: - return ret; - -err_disconnect_frontend: - dmx->disconnect_frontend(dmx); -err_remove_mem_frontend: - dmx->remove_frontend(dmx, &pluto->mem_frontend); -err_remove_hw_frontend: - dmx->remove_frontend(dmx, &pluto->hw_frontend); -err_dvb_dmxdev_release: - dvb_dmxdev_release(&pluto->dmxdev); -err_dvb_dmx_release: - dvb_dmx_release(dvbdemux); -err_dvb_unregister_adapter: - dvb_unregister_adapter(dvb_adapter); -err_i2c_del_adapter: - i2c_del_adapter(&pluto->i2c_adap); -err_pluto_hw_exit: - pluto_hw_exit(pluto); -err_free_irq: - free_irq(pdev->irq, pluto); -err_pci_iounmap: - pci_iounmap(pdev, pluto->io_mem); -err_pci_release_regions: - pci_release_regions(pdev); -err_pci_disable_device: - pci_disable_device(pdev); -err_kfree: - pci_set_drvdata(pdev, NULL); - kfree(pluto); - goto out; -} - -static void __devexit pluto2_remove(struct pci_dev *pdev) -{ - struct pluto *pluto = pci_get_drvdata(pdev); - struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter; - struct dvb_demux *dvbdemux = &pluto->demux; - struct dmx_demux *dmx = &dvbdemux->dmx; - - dmx->close(dmx); - dvb_net_release(&pluto->dvbnet); - if (pluto->fe) - dvb_unregister_frontend(pluto->fe); - - dmx->disconnect_frontend(dmx); - dmx->remove_frontend(dmx, &pluto->mem_frontend); - dmx->remove_frontend(dmx, &pluto->hw_frontend); - dvb_dmxdev_release(&pluto->dmxdev); - dvb_dmx_release(dvbdemux); - dvb_unregister_adapter(dvb_adapter); - i2c_del_adapter(&pluto->i2c_adap); - pluto_hw_exit(pluto); - free_irq(pdev->irq, pluto); - pci_iounmap(pdev, pluto->io_mem); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); - kfree(pluto); -} - -#ifndef PCI_VENDOR_ID_SCM -#define PCI_VENDOR_ID_SCM 0x0432 -#endif -#ifndef PCI_DEVICE_ID_PLUTO2 -#define PCI_DEVICE_ID_PLUTO2 0x0001 -#endif - -static struct pci_device_id pluto2_id_table[] __devinitdata = { - { - .vendor = PCI_VENDOR_ID_SCM, - .device = PCI_DEVICE_ID_PLUTO2, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { - /* empty */ - }, -}; - -MODULE_DEVICE_TABLE(pci, pluto2_id_table); - -static struct pci_driver pluto2_driver = { - .name = DRIVER_NAME, - .id_table = pluto2_id_table, - .probe = pluto2_probe, - .remove = __devexit_p(pluto2_remove), -}; - -static int __init pluto2_init(void) -{ - return pci_register_driver(&pluto2_driver); -} - -static void __exit pluto2_exit(void) -{ - pci_unregister_driver(&pluto2_driver); -} - -module_init(pluto2_init); -module_exit(pluto2_exit); - -MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); -MODULE_DESCRIPTION("Pluto2 driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig deleted file mode 100644 index dd863f26167..00000000000 --- a/drivers/media/dvb/siano/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -# -# Siano Mobile Silicon Digital TV device configuration -# - -config DVB_SIANO_SMS1XXX - tristate "Siano SMS1XXX USB dongle support" - depends on DVB_CORE && USB - ---help--- - Choose Y here if you have a USB dongle with a SMS1XXX chipset. - - To compile this driver as a module, choose M here: the - module will be called sms1xxx. - -config DVB_SIANO_SMS1XXX_SMS_IDS - bool "Enable support for Siano Mobile Silicon default USB IDs" - depends on DVB_SIANO_SMS1XXX - default y - ---help--- - Choose Y here if you have a USB dongle with a SMS1XXX chipset - that uses Siano Mobile Silicon's default usb vid:pid. - - Choose N here if you would prefer to use Siano's external driver. - - Further documentation on this driver can be found on the WWW at - <http://www.siano-ms.com/>. - diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile deleted file mode 100644 index ee0737af98c..00000000000 --- a/drivers/media/dvb/siano/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o - -obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core - -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) - diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c deleted file mode 100644 index 4307e4e8aa3..00000000000 --- a/drivers/media/dvb/siano/sms-cards.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Card-specific functions for the Siano SMS1xxx USB dongle - * - * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "sms-cards.h" - -struct usb_device_id smsusb_id_table[] = { -#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS - { USB_DEVICE(0x187f, 0x0010), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0100), - .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, - { USB_DEVICE(0x187f, 0x0200), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A }, - { USB_DEVICE(0x187f, 0x0201), - .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, - { USB_DEVICE(0x187f, 0x0300), - .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, -#endif - { USB_DEVICE(0x2040, 0x1700), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, - { USB_DEVICE(0x2040, 0x1800), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A }, - { USB_DEVICE(0x2040, 0x1801), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B }, - { USB_DEVICE(0x2040, 0x2000), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2009), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 }, - { USB_DEVICE(0x2040, 0x200a), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2010), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x2019), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD }, - { USB_DEVICE(0x2040, 0x5500), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5510), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5520), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5530), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5580), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { USB_DEVICE(0x2040, 0x5590), - .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, smsusb_id_table); - -static struct sms_board sms_boards[] = { - [SMS_BOARD_UNKNOWN] = { - .name = "Unknown board", - }, - [SMS1XXX_BOARD_SIANO_STELLAR] = { - .name = "Siano Stellar Digital Receiver", - .type = SMS_STELLAR, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", - }, - [SMS1XXX_BOARD_SIANO_NOVA_A] = { - .name = "Siano Nova A Digital Receiver", - .type = SMS_NOVA_A0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", - }, - [SMS1XXX_BOARD_SIANO_NOVA_B] = { - .name = "Siano Nova B Digital Receiver", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", - }, - [SMS1XXX_BOARD_SIANO_VEGA] = { - .name = "Siano Vega Digital Receiver", - .type = SMS_VEGA, - }, - [SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = { - .name = "Hauppauge Catamount", - .type = SMS_STELLAR, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw", - }, - [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = { - .name = "Hauppauge Okemo-A", - .type = SMS_NOVA_A0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw", - }, - [SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = { - .name = "Hauppauge Okemo-B", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw", - }, - [SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = { - .name = "Hauppauge WinTV MiniStick", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .led_power = 26, - .led_lo = 27, - .led_hi = 28, - }, - [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = { - .name = "Hauppauge WinTV MiniCard", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .lna_ctrl = 29, - }, - [SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = { - .name = "Hauppauge WinTV MiniCard", - .type = SMS_NOVA_B0, - .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", - .lna_ctrl = -1, - }, -}; - -struct sms_board *sms_get_board(int id) -{ - BUG_ON(id >= ARRAY_SIZE(sms_boards)); - - return &sms_boards[id]; -} - -static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) -{ - int lvl, ret; - u32 gpio; - struct smscore_gpio_config gpioconfig = { - .direction = SMS_GPIO_DIRECTION_OUTPUT, - .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, - .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, - .outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST, - .outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA, - }; - - if (pin == 0) - return -EINVAL; - - if (pin < 0) { - /* inverted gpio */ - gpio = pin * -1; - lvl = enable ? 0 : 1; - } else { - gpio = pin; - lvl = enable ? 1 : 0; - } - - ret = smscore_configure_gpio(coredev, gpio, &gpioconfig); - if (ret < 0) - return ret; - - return smscore_set_gpio(coredev, gpio, lvl); -} - -int sms_board_setup(struct smscore_device_t *coredev) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - /* turn off all LEDs */ - sms_set_gpio(coredev, board->led_power, 0); - sms_set_gpio(coredev, board->led_hi, 0); - sms_set_gpio(coredev, board->led_lo, 0); - break; - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - /* turn off LNA */ - sms_set_gpio(coredev, board->lna_ctrl, 0); - break; - } - return 0; -} - -int sms_board_power(struct smscore_device_t *coredev, int onoff) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - /* power LED */ - sms_set_gpio(coredev, - board->led_power, onoff ? 1 : 0); - break; - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: - case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: - /* LNA */ - sms_set_gpio(coredev, - board->lna_ctrl, onoff ? 1 : 0); - break; - } - return 0; -} - -int sms_board_led_feedback(struct smscore_device_t *coredev, int led) -{ - int board_id = smscore_get_board_id(coredev); - struct sms_board *board = sms_get_board(board_id); - - /* dont touch GPIO if LEDs are already set */ - if (smscore_led_state(coredev, -1) == led) - return 0; - - switch (board_id) { - case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: - sms_set_gpio(coredev, - board->led_lo, (led & SMS_LED_LO) ? 1 : 0); - sms_set_gpio(coredev, - board->led_hi, (led & SMS_LED_HI) ? 1 : 0); - - smscore_led_state(coredev, led); - break; - } - return 0; -} diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h deleted file mode 100644 index 8e0fe9fd261..00000000000 --- a/drivers/media/dvb/siano/sms-cards.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Card-specific functions for the Siano SMS1xxx USB dongle - * - * Copyright (c) 2008 Michael Krufky <mkrufky@linuxtv.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __SMS_CARDS_H__ -#define __SMS_CARDS_H__ - -#include <linux/usb.h> -#include "smscoreapi.h" - -#define SMS_BOARD_UNKNOWN 0 -#define SMS1XXX_BOARD_SIANO_STELLAR 1 -#define SMS1XXX_BOARD_SIANO_NOVA_A 2 -#define SMS1XXX_BOARD_SIANO_NOVA_B 3 -#define SMS1XXX_BOARD_SIANO_VEGA 4 -#define SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT 5 -#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A 6 -#define SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B 7 -#define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 -#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 -#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 - -struct sms_board { - enum sms_device_type_st type; - char *name, *fw[DEVICE_MODE_MAX]; - - /* gpios */ - int led_power, led_hi, led_lo, lna_ctrl; -}; - -struct sms_board *sms_get_board(int id); - -int sms_board_setup(struct smscore_device_t *coredev); - -#define SMS_LED_OFF 0 -#define SMS_LED_LO 1 -#define SMS_LED_HI 2 -int sms_board_led_feedback(struct smscore_device_t *coredev, int led); -int sms_board_power(struct smscore_device_t *coredev, int onoff); - -extern struct usb_device_id smsusb_id_table[]; - -#endif /* __SMS_CARDS_H__ */ diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c deleted file mode 100644 index cf613f22fb8..00000000000 --- a/drivers/media/dvb/siano/smscoreapi.c +++ /dev/null @@ -1,1329 +0,0 @@ -/* - * Siano core API module - * - * This file contains implementation for the interface to sms core component - * - * author: Anatoly Greenblat - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/dma-mapping.h> -#include <linux/delay.h> -#include <linux/io.h> - -#include <linux/firmware.h> - -#include "smscoreapi.h" -#include "sms-cards.h" - -int sms_debug; -module_param_named(debug, sms_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); - -struct smscore_device_notifyee_t { - struct list_head entry; - hotplug_t hotplug; -}; - -struct smscore_idlist_t { - struct list_head entry; - int id; - int data_type; -}; - -struct smscore_client_t { - struct list_head entry; - struct smscore_device_t *coredev; - void *context; - struct list_head idlist; - onresponse_t onresponse_handler; - onremove_t onremove_handler; -}; - -struct smscore_device_t { - struct list_head entry; - - struct list_head clients; - struct list_head subclients; - spinlock_t clientslock; - - struct list_head buffers; - spinlock_t bufferslock; - int num_buffers; - - void *common_buffer; - int common_buffer_size; - dma_addr_t common_buffer_phys; - - void *context; - struct device *device; - - char devpath[32]; - unsigned long device_flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - int mode, modes_supported; - - struct completion version_ex_done, data_download_done, trigger_done; - struct completion init_device_done, reload_start_done, resume_done; - - int board_id; - int led_state; -}; - -void smscore_set_board_id(struct smscore_device_t *core, int id) -{ - core->board_id = id; -} - -int smscore_led_state(struct smscore_device_t *core, int led) -{ - if (led >= 0) - core->led_state = led; - return core->led_state; -} - -int smscore_get_board_id(struct smscore_device_t *core) -{ - return core->board_id; -} - -struct smscore_registry_entry_t { - struct list_head entry; - char devpath[32]; - int mode; - enum sms_device_type_st type; -}; - -static struct list_head g_smscore_notifyees; -static struct list_head g_smscore_devices; -static struct mutex g_smscore_deviceslock; - -static struct list_head g_smscore_registry; -static struct mutex g_smscore_registrylock; - -static int default_mode = 4; - -module_param(default_mode, int, 0644); -MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); - -static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) -{ - struct smscore_registry_entry_t *entry; - struct list_head *next; - - kmutex_lock(&g_smscore_registrylock); - for (next = g_smscore_registry.next; - next != &g_smscore_registry; - next = next->next) { - entry = (struct smscore_registry_entry_t *) next; - if (!strcmp(entry->devpath, devpath)) { - kmutex_unlock(&g_smscore_registrylock); - return entry; - } - } - entry = (struct smscore_registry_entry_t *) - kmalloc(sizeof(struct smscore_registry_entry_t), - GFP_KERNEL); - if (entry) { - entry->mode = default_mode; - strcpy(entry->devpath, devpath); - list_add(&entry->entry, &g_smscore_registry); - } else - sms_err("failed to create smscore_registry."); - kmutex_unlock(&g_smscore_registrylock); - return entry; -} - -int smscore_registry_getmode(char *devpath) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - return entry->mode; - else - sms_err("No registry found."); - - return default_mode; -} - -static enum sms_device_type_st smscore_registry_gettype(char *devpath) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - return entry->type; - else - sms_err("No registry found."); - - return -1; -} - -void smscore_registry_setmode(char *devpath, int mode) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - entry->mode = mode; - else - sms_err("No registry found."); -} - -static void smscore_registry_settype(char *devpath, - enum sms_device_type_st type) -{ - struct smscore_registry_entry_t *entry; - - entry = smscore_find_registry(devpath); - if (entry) - entry->type = type; - else - sms_err("No registry found."); -} - - -static void list_add_locked(struct list_head *new, struct list_head *head, - spinlock_t *lock) -{ - unsigned long flags; - - spin_lock_irqsave(lock, flags); - - list_add(new, head); - - spin_unlock_irqrestore(lock, flags); -} - -/** - * register a client callback that called when device plugged in/unplugged - * NOTE: if devices exist callback is called immediately for each device - * - * @param hotplug callback - * - * @return 0 on success, <0 on error. - */ -int smscore_register_hotplug(hotplug_t hotplug) -{ - struct smscore_device_notifyee_t *notifyee; - struct list_head *next, *first; - int rc = 0; - - kmutex_lock(&g_smscore_deviceslock); - - notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t), - GFP_KERNEL); - if (notifyee) { - /* now notify callback about existing devices */ - first = &g_smscore_devices; - for (next = first->next; - next != first && !rc; - next = next->next) { - struct smscore_device_t *coredev = - (struct smscore_device_t *) next; - rc = hotplug(coredev, coredev->device, 1); - } - - if (rc >= 0) { - notifyee->hotplug = hotplug; - list_add(¬ifyee->entry, &g_smscore_notifyees); - } else - kfree(notifyee); - } else - rc = -ENOMEM; - - kmutex_unlock(&g_smscore_deviceslock); - - return rc; -} - -/** - * unregister a client callback that called when device plugged in/unplugged - * - * @param hotplug callback - * - */ -void smscore_unregister_hotplug(hotplug_t hotplug) -{ - struct list_head *next, *first; - - kmutex_lock(&g_smscore_deviceslock); - - first = &g_smscore_notifyees; - - for (next = first->next; next != first;) { - struct smscore_device_notifyee_t *notifyee = - (struct smscore_device_notifyee_t *) next; - next = next->next; - - if (notifyee->hotplug == hotplug) { - list_del(¬ifyee->entry); - kfree(notifyee); - } - } - - kmutex_unlock(&g_smscore_deviceslock); -} - -static void smscore_notify_clients(struct smscore_device_t *coredev) -{ - struct smscore_client_t *client; - - /* the client must call smscore_unregister_client from remove handler */ - while (!list_empty(&coredev->clients)) { - client = (struct smscore_client_t *) coredev->clients.next; - client->onremove_handler(client->context); - } -} - -static int smscore_notify_callbacks(struct smscore_device_t *coredev, - struct device *device, int arrival) -{ - struct list_head *next, *first; - int rc = 0; - - /* note: must be called under g_deviceslock */ - - first = &g_smscore_notifyees; - - for (next = first->next; next != first; next = next->next) { - rc = ((struct smscore_device_notifyee_t *) next)-> - hotplug(coredev, device, arrival); - if (rc < 0) - break; - } - - return rc; -} - -static struct -smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, - dma_addr_t common_buffer_phys) -{ - struct smscore_buffer_t *cb = - kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); - if (!cb) { - sms_info("kmalloc(...) failed"); - return NULL; - } - - cb->p = buffer; - cb->offset_in_common = buffer - (u8 *) common_buffer; - cb->phys = common_buffer_phys + cb->offset_in_common; - - return cb; -} - -/** - * creates coredev object for a device, prepares buffers, - * creates buffer mappings, notifies registered hotplugs about new device. - * - * @param params device pointer to struct with device specific parameters - * and handlers - * @param coredev pointer to a value that receives created coredev object - * - * @return 0 on success, <0 on error. - */ -int smscore_register_device(struct smsdevice_params_t *params, - struct smscore_device_t **coredev) -{ - struct smscore_device_t *dev; - u8 *buffer; - - dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); - if (!dev) { - sms_info("kzalloc(...) failed"); - return -ENOMEM; - } - - /* init list entry so it could be safe in smscore_unregister_device */ - INIT_LIST_HEAD(&dev->entry); - - /* init queues */ - INIT_LIST_HEAD(&dev->clients); - INIT_LIST_HEAD(&dev->buffers); - - /* init locks */ - spin_lock_init(&dev->clientslock); - spin_lock_init(&dev->bufferslock); - - /* init completion events */ - init_completion(&dev->version_ex_done); - init_completion(&dev->data_download_done); - init_completion(&dev->trigger_done); - init_completion(&dev->init_device_done); - init_completion(&dev->reload_start_done); - init_completion(&dev->resume_done); - - /* alloc common buffer */ - dev->common_buffer_size = params->buffer_size * params->num_buffers; - dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, - &dev->common_buffer_phys, - GFP_KERNEL | GFP_DMA); - if (!dev->common_buffer) { - smscore_unregister_device(dev); - return -ENOMEM; - } - - /* prepare dma buffers */ - for (buffer = dev->common_buffer; - dev->num_buffers < params->num_buffers; - dev->num_buffers++, buffer += params->buffer_size) { - struct smscore_buffer_t *cb = - smscore_createbuffer(buffer, dev->common_buffer, - dev->common_buffer_phys); - if (!cb) { - smscore_unregister_device(dev); - return -ENOMEM; - } - - smscore_putbuffer(dev, cb); - } - - sms_info("allocated %d buffers", dev->num_buffers); - - dev->mode = DEVICE_MODE_NONE; - dev->context = params->context; - dev->device = params->device; - dev->setmode_handler = params->setmode_handler; - dev->detectmode_handler = params->detectmode_handler; - dev->sendrequest_handler = params->sendrequest_handler; - dev->preload_handler = params->preload_handler; - dev->postload_handler = params->postload_handler; - - dev->device_flags = params->flags; - strcpy(dev->devpath, params->devpath); - - smscore_registry_settype(dev->devpath, params->device_type); - - /* add device to devices list */ - kmutex_lock(&g_smscore_deviceslock); - list_add(&dev->entry, &g_smscore_devices); - kmutex_unlock(&g_smscore_deviceslock); - - *coredev = dev; - - sms_info("device %p created", dev); - - return 0; -} - -/** - * sets initial device mode and notifies client hotplugs that device is ready - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return 0 on success, <0 on error. - */ -int smscore_start_device(struct smscore_device_t *coredev) -{ - int rc = smscore_set_device_mode( - coredev, smscore_registry_getmode(coredev->devpath)); - if (rc < 0) { - sms_info("set device mode faile , rc %d", rc); - return rc; - } - - kmutex_lock(&g_smscore_deviceslock); - - rc = smscore_notify_callbacks(coredev, coredev->device, 1); - - sms_info("device %p started, rc %d", coredev, rc); - - kmutex_unlock(&g_smscore_deviceslock); - - return rc; -} - -static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, - void *buffer, size_t size, - struct completion *completion) -{ - int rc = coredev->sendrequest_handler(coredev->context, buffer, size); - if (rc < 0) { - sms_info("sendrequest returned error %d", rc); - return rc; - } - - return wait_for_completion_timeout(completion, - msecs_to_jiffies(10000)) ? - 0 : -ETIME; -} - -static int smscore_load_firmware_family2(struct smscore_device_t *coredev, - void *buffer, size_t size) -{ - struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; - struct SmsMsgHdr_ST *msg; - u32 mem_address = firmware->StartAddress; - u8 *payload = firmware->Payload; - int rc = 0; - - sms_info("loading FW to addr 0x%x size %d", - mem_address, firmware->Length); - if (coredev->preload_handler) { - rc = coredev->preload_handler(coredev->context); - if (rc < 0) - return rc; - } - - /* PAGE_SIZE buffer shall be enough and dma aligned */ - msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); - if (!msg) - return -ENOMEM; - - if (coredev->mode != DEVICE_MODE_NONE) { - sms_debug("sending reload command."); - SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, - sizeof(struct SmsMsgHdr_ST)); - rc = smscore_sendrequest_and_wait(coredev, msg, - msg->msgLength, - &coredev->reload_start_done); - mem_address = *(u32 *) &payload[20]; - } - - while (size && rc >= 0) { - struct SmsDataDownload_ST *DataMsg = - (struct SmsDataDownload_ST *) msg; - int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); - - SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, - (u16)(sizeof(struct SmsMsgHdr_ST) + - sizeof(u32) + payload_size)); - - DataMsg->MemAddr = mem_address; - memcpy(DataMsg->Payload, payload, payload_size); - - if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && - (coredev->mode == DEVICE_MODE_NONE)) - rc = coredev->sendrequest_handler( - coredev->context, DataMsg, - DataMsg->xMsgHeader.msgLength); - else - rc = smscore_sendrequest_and_wait( - coredev, DataMsg, - DataMsg->xMsgHeader.msgLength, - &coredev->data_download_done); - - payload += payload_size; - size -= payload_size; - mem_address += payload_size; - } - - if (rc >= 0) { - if (coredev->mode == DEVICE_MODE_NONE) { - struct SmsMsgData_ST *TriggerMsg = - (struct SmsMsgData_ST *) msg; - - SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, - sizeof(struct SmsMsgHdr_ST) + - sizeof(u32) * 5); - - TriggerMsg->msgData[0] = firmware->StartAddress; - /* Entry point */ - TriggerMsg->msgData[1] = 5; /* Priority */ - TriggerMsg->msgData[2] = 0x200; /* Stack size */ - TriggerMsg->msgData[3] = 0; /* Parameter */ - TriggerMsg->msgData[4] = 4; /* Task ID */ - - if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { - rc = coredev->sendrequest_handler( - coredev->context, TriggerMsg, - TriggerMsg->xMsgHeader.msgLength); - msleep(100); - } else - rc = smscore_sendrequest_and_wait( - coredev, TriggerMsg, - TriggerMsg->xMsgHeader.msgLength, - &coredev->trigger_done); - } else { - SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, - sizeof(struct SmsMsgHdr_ST)); - - rc = coredev->sendrequest_handler(coredev->context, - msg, msg->msgLength); - } - msleep(500); - } - - sms_debug("rc=%d, postload=%p ", rc, - coredev->postload_handler); - - kfree(msg); - - return ((rc >= 0) && coredev->postload_handler) ? - coredev->postload_handler(coredev->context) : - rc; -} - -/** - * loads specified firmware into a buffer and calls device loadfirmware_handler - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param filename null-terminated string specifies firmware file name - * @param loadfirmware_handler device handler that loads firmware - * - * @return 0 on success, <0 on error. - */ -static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, - char *filename, - loadfirmware_t loadfirmware_handler) -{ - int rc = -ENOENT; - const struct firmware *fw; - u8 *fw_buffer; - - if (loadfirmware_handler == NULL && !(coredev->device_flags & - SMS_DEVICE_FAMILY2)) - return -EINVAL; - - rc = request_firmware(&fw, filename, coredev->device); - if (rc < 0) { - sms_info("failed to open \"%s\"", filename); - return rc; - } - sms_info("read FW %s, size=%zd", filename, fw->size); - fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), - GFP_KERNEL | GFP_DMA); - if (fw_buffer) { - memcpy(fw_buffer, fw->data, fw->size); - - rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? - smscore_load_firmware_family2(coredev, - fw_buffer, - fw->size) : - loadfirmware_handler(coredev->context, - fw_buffer, fw->size); - - kfree(fw_buffer); - } else { - sms_info("failed to allocate firmware buffer"); - rc = -ENOMEM; - } - - release_firmware(fw); - - return rc; -} - -/** - * notifies all clients registered with the device, notifies hotplugs, - * frees all buffers and coredev object - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return 0 on success, <0 on error. - */ -void smscore_unregister_device(struct smscore_device_t *coredev) -{ - struct smscore_buffer_t *cb; - int num_buffers = 0; - int retry = 0; - - kmutex_lock(&g_smscore_deviceslock); - - smscore_notify_clients(coredev); - smscore_notify_callbacks(coredev, NULL, 0); - - /* at this point all buffers should be back - * onresponse must no longer be called */ - - while (1) { - while ((cb = smscore_getbuffer(coredev))) { - kfree(cb); - num_buffers++; - } - if (num_buffers == coredev->num_buffers) - break; - if (++retry > 10) { - sms_info("exiting although " - "not all buffers released."); - break; - } - - sms_info("waiting for %d buffer(s)", - coredev->num_buffers - num_buffers); - msleep(100); - } - - sms_info("freed %d buffers", num_buffers); - - if (coredev->common_buffer) - dma_free_coherent(NULL, coredev->common_buffer_size, - coredev->common_buffer, - coredev->common_buffer_phys); - - list_del(&coredev->entry); - kfree(coredev); - - kmutex_unlock(&g_smscore_deviceslock); - - sms_info("device %p destroyed", coredev); -} - -static int smscore_detect_mode(struct smscore_device_t *coredev) -{ - void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, - GFP_KERNEL | GFP_DMA); - struct SmsMsgHdr_ST *msg = - (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); - int rc; - - if (!buffer) - return -ENOMEM; - - SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, - sizeof(struct SmsMsgHdr_ST)); - - rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, - &coredev->version_ex_done); - if (rc == -ETIME) { - sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try"); - - if (wait_for_completion_timeout(&coredev->resume_done, - msecs_to_jiffies(5000))) { - rc = smscore_sendrequest_and_wait( - coredev, msg, msg->msgLength, - &coredev->version_ex_done); - if (rc < 0) - sms_err("MSG_SMS_GET_VERSION_EX_REQ failed " - "second try, rc %d", rc); - } else - rc = -ETIME; - } - - kfree(buffer); - - return rc; -} - -static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { - /*Stellar NOVA A0 Nova B0 VEGA*/ - /*DVBT*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*DVBH*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*TDMB*/ - {"none", "tdmb_nova_12mhz.inp", "none", "none"}, - /*DABIP*/ - {"none", "none", "none", "none"}, - /*BDA*/ - {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, - /*ISDBT*/ - {"none", "isdbt_nova_12mhz.inp", "dvb_nova_12mhz.inp", "none"}, - /*ISDBTBDA*/ - {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, - /*CMMB*/ - {"none", "none", "none", "cmmb_vega_12mhz.inp"} -}; - -static inline char *sms_get_fw_name(struct smscore_device_t *coredev, - int mode, enum sms_device_type_st type) -{ - char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; - return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; -} - -/** - * calls device handler to change mode of operation - * NOTE: stellar/usb may disconnect when changing mode - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param mode requested mode of operation - * - * @return 0 on success, <0 on error. - */ -int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) -{ - void *buffer; - int rc = 0; - enum sms_device_type_st type; - - sms_debug("set device mode to %d", mode); - if (coredev->device_flags & SMS_DEVICE_FAMILY2) { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) { - sms_err("invalid mode specified %d", mode); - return -EINVAL; - } - - smscore_registry_setmode(coredev->devpath, mode); - - if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { - rc = smscore_detect_mode(coredev); - if (rc < 0) { - sms_err("mode detect failed %d", rc); - return rc; - } - } - - if (coredev->mode == mode) { - sms_info("device mode %d already set", mode); - return 0; - } - - if (!(coredev->modes_supported & (1 << mode))) { - char *fw_filename; - - type = smscore_registry_gettype(coredev->devpath); - fw_filename = sms_get_fw_name(coredev, mode, type); - - rc = smscore_load_firmware_from_file(coredev, - fw_filename, NULL); - if (rc < 0) { - sms_warn("error %d loading firmware: %s, " - "trying again with default firmware", - rc, fw_filename); - - /* try again with the default firmware */ - fw_filename = smscore_fw_lkup[mode][type]; - rc = smscore_load_firmware_from_file(coredev, - fw_filename, NULL); - - if (rc < 0) { - sms_warn("error %d loading " - "firmware: %s", rc, - fw_filename); - return rc; - } - } - sms_log("firmware download success: %s", fw_filename); - } else - sms_info("mode %d supported by running " - "firmware", mode); - - buffer = kmalloc(sizeof(struct SmsMsgData_ST) + - SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); - if (buffer) { - struct SmsMsgData_ST *msg = - (struct SmsMsgData_ST *) - SMS_ALIGN_ADDRESS(buffer); - - SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, - sizeof(struct SmsMsgData_ST)); - msg->msgData[0] = mode; - - rc = smscore_sendrequest_and_wait( - coredev, msg, msg->xMsgHeader.msgLength, - &coredev->init_device_done); - - kfree(buffer); - } else { - sms_err("Could not allocate buffer for " - "init device message."); - rc = -ENOMEM; - } - } else { - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_err("invalid mode specified %d", mode); - return -EINVAL; - } - - smscore_registry_setmode(coredev->devpath, mode); - - if (coredev->detectmode_handler) - coredev->detectmode_handler(coredev->context, - &coredev->mode); - - if (coredev->mode != mode && coredev->setmode_handler) - rc = coredev->setmode_handler(coredev->context, mode); - } - - if (rc >= 0) { - coredev->mode = mode; - coredev->device_flags &= ~SMS_DEVICE_NOT_READY; - } - - if (rc != 0) - sms_err("return error code %d.", rc); - return rc; -} - -/** - * calls device handler to get current mode of operation - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return current mode - */ -int smscore_get_device_mode(struct smscore_device_t *coredev) -{ - return coredev->mode; -} - -/** - * find client by response id & type within the clients list. - * return client handle or NULL. - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param data_type client data type (SMS_DONT_CARE for all types) - * @param id client id (SMS_DONT_CARE for all id) - * - */ -static struct -smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, - int data_type, int id) -{ - struct smscore_client_t *client = NULL; - struct list_head *next, *first; - unsigned long flags; - struct list_head *firstid, *nextid; - - - spin_lock_irqsave(&coredev->clientslock, flags); - first = &coredev->clients; - for (next = first->next; - (next != first) && !client; - next = next->next) { - firstid = &((struct smscore_client_t *)next)->idlist; - for (nextid = firstid->next; - nextid != firstid; - nextid = nextid->next) { - if ((((struct smscore_idlist_t *)nextid)->id == id) && - (((struct smscore_idlist_t *)nextid)->data_type == data_type || - (((struct smscore_idlist_t *)nextid)->data_type == 0))) { - client = (struct smscore_client_t *) next; - break; - } - } - } - spin_unlock_irqrestore(&coredev->clientslock, flags); - return client; -} - -/** - * find client by response id/type, call clients onresponse handler - * return buffer to pool on error - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param cb pointer to response buffer descriptor - * - */ -void smscore_onresponse(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) -{ - struct SmsMsgHdr_ST *phdr = - (struct SmsMsgHdr_ST *)((u8 *) cb->p + cb->offset); - struct smscore_client_t *client = - smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); - int rc = -EBUSY; - - static unsigned long last_sample_time; /* = 0; */ - static int data_total; /* = 0; */ - unsigned long time_now = jiffies_to_msecs(jiffies); - - if (!last_sample_time) - last_sample_time = time_now; - - if (time_now - last_sample_time > 10000) { - sms_debug("\ndata rate %d bytes/secs", - (int)((data_total * 1000) / - (time_now - last_sample_time))); - - last_sample_time = time_now; - data_total = 0; - } - - data_total += cb->size; - /* If no client registered for type & id, - * check for control client where type is not registered */ - if (client) - rc = client->onresponse_handler(client->context, cb); - - if (rc < 0) { - switch (phdr->msgType) { - case MSG_SMS_GET_VERSION_EX_RES: - { - struct SmsVersionRes_ST *ver = - (struct SmsVersionRes_ST *) phdr; - sms_debug("MSG_SMS_GET_VERSION_EX_RES " - "id %d prots 0x%x ver %d.%d", - ver->FirmwareId, ver->SupportedProtocols, - ver->RomVersionMajor, ver->RomVersionMinor); - - coredev->mode = ver->FirmwareId == 255 ? - DEVICE_MODE_NONE : ver->FirmwareId; - coredev->modes_supported = ver->SupportedProtocols; - - complete(&coredev->version_ex_done); - break; - } - case MSG_SMS_INIT_DEVICE_RES: - sms_debug("MSG_SMS_INIT_DEVICE_RES"); - complete(&coredev->init_device_done); - break; - case MSG_SW_RELOAD_START_RES: - sms_debug("MSG_SW_RELOAD_START_RES"); - complete(&coredev->reload_start_done); - break; - case MSG_SMS_DATA_DOWNLOAD_RES: - complete(&coredev->data_download_done); - break; - case MSG_SW_RELOAD_EXEC_RES: - sms_debug("MSG_SW_RELOAD_EXEC_RES"); - break; - case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: - sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES"); - complete(&coredev->trigger_done); - break; - case MSG_SMS_SLEEP_RESUME_COMP_IND: - complete(&coredev->resume_done); - break; - default: - break; - } - smscore_putbuffer(coredev, cb); - } -} - -/** - * return pointer to next free buffer descriptor from core pool - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * - * @return pointer to descriptor on success, NULL on error. - */ -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) -{ - struct smscore_buffer_t *cb = NULL; - unsigned long flags; - - spin_lock_irqsave(&coredev->bufferslock, flags); - - if (!list_empty(&coredev->buffers)) { - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); - } - - spin_unlock_irqrestore(&coredev->bufferslock, flags); - - return cb; -} - -/** - * return buffer descriptor to a pool - * - * @param coredev pointer to a coredev object returned by - * smscore_register_device - * @param cb pointer buffer descriptor - * - */ -void smscore_putbuffer(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) -{ - list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); -} - -static int smscore_validate_client(struct smscore_device_t *coredev, - struct smscore_client_t *client, - int data_type, int id) -{ - struct smscore_idlist_t *listentry; - struct smscore_client_t *registered_client; - - if (!client) { - sms_err("bad parameter."); - return -EFAULT; - } - registered_client = smscore_find_client(coredev, data_type, id); - if (registered_client == client) - return 0; - - if (registered_client) { - sms_err("The msg ID already registered to another client."); - return -EEXIST; - } - listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); - if (!listentry) { - sms_err("Can't allocate memory for client id."); - return -ENOMEM; - } - listentry->id = id; - listentry->data_type = data_type; - list_add_locked(&listentry->entry, &client->idlist, - &coredev->clientslock); - return 0; -} - -/** - * creates smsclient object, check that id is taken by another client - * - * @param coredev pointer to a coredev object from clients hotplug - * @param initial_id all messages with this id would be sent to this client - * @param data_type all messages of this type would be sent to this client - * @param onresponse_handler client handler that is called to - * process incoming messages - * @param onremove_handler client handler that is called when device is removed - * @param context client-specific context - * @param client pointer to a value that receives created smsclient object - * - * @return 0 on success, <0 on error. - */ -int smscore_register_client(struct smscore_device_t *coredev, - struct smsclient_params_t *params, - struct smscore_client_t **client) -{ - struct smscore_client_t *newclient; - /* check that no other channel with same parameters exists */ - if (smscore_find_client(coredev, params->data_type, - params->initial_id)) { - sms_err("Client already exist."); - return -EEXIST; - } - - newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); - if (!newclient) { - sms_err("Failed to allocate memory for client."); - return -ENOMEM; - } - - INIT_LIST_HEAD(&newclient->idlist); - newclient->coredev = coredev; - newclient->onresponse_handler = params->onresponse_handler; - newclient->onremove_handler = params->onremove_handler; - newclient->context = params->context; - list_add_locked(&newclient->entry, &coredev->clients, - &coredev->clientslock); - smscore_validate_client(coredev, newclient, params->data_type, - params->initial_id); - *client = newclient; - sms_debug("%p %d %d", params->context, params->data_type, - params->initial_id); - - return 0; -} - -/** - * frees smsclient object and all subclients associated with it - * - * @param client pointer to smsclient object returned by - * smscore_register_client - * - */ -void smscore_unregister_client(struct smscore_client_t *client) -{ - struct smscore_device_t *coredev = client->coredev; - unsigned long flags; - - spin_lock_irqsave(&coredev->clientslock, flags); - - - while (!list_empty(&client->idlist)) { - struct smscore_idlist_t *identry = - (struct smscore_idlist_t *) client->idlist.next; - list_del(&identry->entry); - kfree(identry); - } - - sms_info("%p", client->context); - - list_del(&client->entry); - kfree(client); - - spin_unlock_irqrestore(&coredev->clientslock, flags); -} - -/** - * verifies that source id is not taken by another client, - * calls device handler to send requests to the device - * - * @param client pointer to smsclient object returned by - * smscore_register_client - * @param buffer pointer to a request buffer - * @param size size (in bytes) of request buffer - * - * @return 0 on success, <0 on error. - */ -int smsclient_sendrequest(struct smscore_client_t *client, - void *buffer, size_t size) -{ - struct smscore_device_t *coredev; - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; - int rc; - - if (client == NULL) { - sms_err("Got NULL client"); - return -EINVAL; - } - - coredev = client->coredev; - - /* check that no other channel with same id exists */ - if (coredev == NULL) { - sms_err("Got NULL coredev"); - return -EINVAL; - } - - rc = smscore_validate_client(client->coredev, client, 0, - phdr->msgSrcId); - if (rc < 0) - return rc; - - return coredev->sendrequest_handler(coredev->context, buffer, size); -} - - -int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_gpio_config *pinconfig) -{ - struct { - struct SmsMsgHdr_ST hdr; - u32 data[6]; - } msg; - - if (coredev->device_flags & SMS_DEVICE_FAMILY2) { - msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - msg.hdr.msgDstId = HIF_TASK; - msg.hdr.msgFlags = 0; - msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; - msg.hdr.msgLength = sizeof(msg); - - msg.data[0] = pin; - msg.data[1] = pinconfig->pullupdown; - - /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */ - msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0; - - switch (pinconfig->outputdriving) { - case SMS_GPIO_OUTPUTDRIVING_16mA: - msg.data[3] = 7; /* Nova - 16mA */ - break; - case SMS_GPIO_OUTPUTDRIVING_12mA: - msg.data[3] = 5; /* Nova - 11mA */ - break; - case SMS_GPIO_OUTPUTDRIVING_8mA: - msg.data[3] = 3; /* Nova - 7mA */ - break; - case SMS_GPIO_OUTPUTDRIVING_4mA: - default: - msg.data[3] = 2; /* Nova - 4mA */ - break; - } - - msg.data[4] = pinconfig->direction; - msg.data[5] = 0; - } else /* TODO: SMS_DEVICE_FAMILY1 */ - return -EINVAL; - - return coredev->sendrequest_handler(coredev->context, - &msg, sizeof(msg)); -} - -int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) -{ - struct { - struct SmsMsgHdr_ST hdr; - u32 data[3]; - } msg; - - if (pin > MAX_GPIO_PIN_NUMBER) - return -EINVAL; - - msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - msg.hdr.msgDstId = HIF_TASK; - msg.hdr.msgFlags = 0; - msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; - msg.hdr.msgLength = sizeof(msg); - - msg.data[0] = pin; - msg.data[1] = level ? 1 : 0; - msg.data[2] = 0; - - return coredev->sendrequest_handler(coredev->context, - &msg, sizeof(msg)); -} - -static int __init smscore_module_init(void) -{ - int rc = 0; - - INIT_LIST_HEAD(&g_smscore_notifyees); - INIT_LIST_HEAD(&g_smscore_devices); - kmutex_init(&g_smscore_deviceslock); - - INIT_LIST_HEAD(&g_smscore_registry); - kmutex_init(&g_smscore_registrylock); - - /* USB Register */ - rc = smsusb_register(); - - /* DVB Register */ - rc = smsdvb_register(); - - sms_debug("rc %d", rc); - - return rc; -} - -static void __exit smscore_module_exit(void) -{ - - kmutex_lock(&g_smscore_deviceslock); - while (!list_empty(&g_smscore_notifyees)) { - struct smscore_device_notifyee_t *notifyee = - (struct smscore_device_notifyee_t *) - g_smscore_notifyees.next; - - list_del(¬ifyee->entry); - kfree(notifyee); - } - kmutex_unlock(&g_smscore_deviceslock); - - kmutex_lock(&g_smscore_registrylock); - while (!list_empty(&g_smscore_registry)) { - struct smscore_registry_entry_t *entry = - (struct smscore_registry_entry_t *) - g_smscore_registry.next; - - list_del(&entry->entry); - kfree(entry); - } - kmutex_unlock(&g_smscore_registrylock); - - /* DVB UnRegister */ - smsdvb_unregister(); - - /* Unregister USB */ - smsusb_unregister(); - - sms_debug(""); -} - -module_init(smscore_module_init); -module_exit(smscore_module_exit); - -MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle"); -MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h deleted file mode 100644 index 760e233fcbc..00000000000 --- a/drivers/media/dvb/siano/smscoreapi.h +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * author: Anatoly Greenblat - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __smscoreapi_h__ -#define __smscoreapi_h__ - -#include <linux/version.h> -#include <linux/device.h> -#include <linux/list.h> -#include <linux/mm.h> -#include <linux/scatterlist.h> -#include <linux/types.h> -#include <asm/page.h> - -#include "dmxdev.h" -#include "dvbdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" - -#include <linux/mutex.h> - -#define kmutex_init(_p_) mutex_init(_p_) -#define kmutex_lock(_p_) mutex_lock(_p_) -#define kmutex_trylock(_p_) mutex_trylock(_p_) -#define kmutex_unlock(_p_) mutex_unlock(_p_) - -#ifndef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#endif - -#define SMS_ALLOC_ALIGNMENT 128 -#define SMS_DMA_ALIGNMENT 16 -#define SMS_ALIGN_ADDRESS(addr) \ - ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) - -#define SMS_DEVICE_FAMILY2 1 -#define SMS_ROM_NO_RESPONSE 2 -#define SMS_DEVICE_NOT_READY 0x8000000 - -enum sms_device_type_st { - SMS_STELLAR = 0, - SMS_NOVA_A0, - SMS_NOVA_B0, - SMS_VEGA, - SMS_NUM_OF_DEVICE_TYPES -}; - -struct smscore_device_t; -struct smscore_client_t; -struct smscore_buffer_t; - -typedef int (*hotplug_t)(struct smscore_device_t *coredev, - struct device *device, int arrival); - -typedef int (*setmode_t)(void *context, int mode); -typedef void (*detectmode_t)(void *context, int *mode); -typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); -typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); -typedef int (*preload_t)(void *context); -typedef int (*postload_t)(void *context); - -typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb); -typedef void (*onremove_t)(void *context); - -struct smscore_buffer_t { - /* public members, once passed to clients can be changed freely */ - struct list_head entry; - int size; - int offset; - - /* private members, read-only for clients */ - void *p; - dma_addr_t phys; - unsigned long offset_in_common; -}; - -struct smsdevice_params_t { - struct device *device; - - int buffer_size; - int num_buffers; - - char devpath[32]; - unsigned long flags; - - setmode_t setmode_handler; - detectmode_t detectmode_handler; - sendrequest_t sendrequest_handler; - preload_t preload_handler; - postload_t postload_handler; - - void *context; - enum sms_device_type_st device_type; -}; - -struct smsclient_params_t { - int initial_id; - int data_type; - onresponse_t onresponse_handler; - onremove_t onremove_handler; - - void *context; -}; - -/* GPIO definitions for antenna frequency domain control (SMS8021) */ -#define SMS_ANTENNA_GPIO_0 1 -#define SMS_ANTENNA_GPIO_1 0 - -#define BW_8_MHZ 0 -#define BW_7_MHZ 1 -#define BW_6_MHZ 2 -#define BW_5_MHZ 3 -#define BW_ISDBT_1SEG 4 -#define BW_ISDBT_3SEG 5 - -#define MSG_HDR_FLAG_SPLIT_MSG 4 - -#define MAX_GPIO_PIN_NUMBER 31 - -#define HIF_TASK 11 -#define SMS_HOST_LIB 150 -#define DVBT_BDA_CONTROL_MSG_ID 201 - -#define SMS_MAX_PAYLOAD_SIZE 240 -#define SMS_TUNE_TIMEOUT 500 - -#define MSG_SMS_GPIO_CONFIG_REQ 507 -#define MSG_SMS_GPIO_CONFIG_RES 508 -#define MSG_SMS_GPIO_SET_LEVEL_REQ 509 -#define MSG_SMS_GPIO_SET_LEVEL_RES 510 -#define MSG_SMS_GPIO_GET_LEVEL_REQ 511 -#define MSG_SMS_GPIO_GET_LEVEL_RES 512 -#define MSG_SMS_RF_TUNE_REQ 561 -#define MSG_SMS_RF_TUNE_RES 562 -#define MSG_SMS_INIT_DEVICE_REQ 578 -#define MSG_SMS_INIT_DEVICE_RES 579 -#define MSG_SMS_ADD_PID_FILTER_REQ 601 -#define MSG_SMS_ADD_PID_FILTER_RES 602 -#define MSG_SMS_REMOVE_PID_FILTER_REQ 603 -#define MSG_SMS_REMOVE_PID_FILTER_RES 604 -#define MSG_SMS_DAB_CHANNEL 607 -#define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 -#define MSG_SMS_GET_PID_FILTER_LIST_RES 609 -#define MSG_SMS_GET_STATISTICS_REQ 615 -#define MSG_SMS_GET_STATISTICS_RES 616 -#define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 -#define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 -#define MSG_SMS_GET_STATISTICS_EX_REQ 653 -#define MSG_SMS_GET_STATISTICS_EX_RES 654 -#define MSG_SMS_SLEEP_RESUME_COMP_IND 655 -#define MSG_SMS_DATA_DOWNLOAD_REQ 660 -#define MSG_SMS_DATA_DOWNLOAD_RES 661 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 -#define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 -#define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 -#define MSG_SMS_GET_VERSION_EX_REQ 668 -#define MSG_SMS_GET_VERSION_EX_RES 669 -#define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 -#define MSG_SMS_I2C_SET_FREQ_REQ 685 -#define MSG_SMS_GENERIC_I2C_REQ 687 -#define MSG_SMS_GENERIC_I2C_RES 688 -#define MSG_SMS_DVBT_BDA_DATA 693 -#define MSG_SW_RELOAD_REQ 697 -#define MSG_SMS_DATA_MSG 699 -#define MSG_SW_RELOAD_START_REQ 702 -#define MSG_SW_RELOAD_START_RES 703 -#define MSG_SW_RELOAD_EXEC_REQ 704 -#define MSG_SW_RELOAD_EXEC_RES 705 -#define MSG_SMS_SPI_INT_LINE_SET_REQ 710 -#define MSG_SMS_GPIO_CONFIG_EX_REQ 712 -#define MSG_SMS_GPIO_CONFIG_EX_RES 713 -#define MSG_SMS_ISDBT_TUNE_REQ 776 -#define MSG_SMS_ISDBT_TUNE_RES 777 - -#define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ - (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ - (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ -} while (0) -#define SMS_INIT_MSG(ptr, type, len) \ - SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) - -enum SMS_DEVICE_MODE { - DEVICE_MODE_NONE = -1, - DEVICE_MODE_DVBT = 0, - DEVICE_MODE_DVBH, - DEVICE_MODE_DAB_TDMB, - DEVICE_MODE_DAB_TDMB_DABIP, - DEVICE_MODE_DVBT_BDA, - DEVICE_MODE_ISDBT, - DEVICE_MODE_ISDBT_BDA, - DEVICE_MODE_CMMB, - DEVICE_MODE_RAW_TUNER, - DEVICE_MODE_MAX, -}; - -struct SmsMsgHdr_ST { - u16 msgType; - u8 msgSrcId; - u8 msgDstId; - u16 msgLength; /* Length of entire message, including header */ - u16 msgFlags; -}; - -struct SmsMsgData_ST { - struct SmsMsgHdr_ST xMsgHeader; - u32 msgData[1]; -}; - -struct SmsDataDownload_ST { - struct SmsMsgHdr_ST xMsgHeader; - u32 MemAddr; - u8 Payload[SMS_MAX_PAYLOAD_SIZE]; -}; - -struct SmsVersionRes_ST { - struct SmsMsgHdr_ST xMsgHeader; - - u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ - u8 Step; /* 0 - Step A */ - u8 MetalFix; /* 0 - Metal 0 */ - - u8 FirmwareId; /* 0xFF � ROM, otherwise the - * value indicated by - * SMSHOSTLIB_DEVICE_MODES_E */ - u8 SupportedProtocols; /* Bitwise OR combination of - * supported protocols */ - - u8 VersionMajor; - u8 VersionMinor; - u8 VersionPatch; - u8 VersionFieldPatch; - - u8 RomVersionMajor; - u8 RomVersionMinor; - u8 RomVersionPatch; - u8 RomVersionFieldPatch; - - u8 TextLabel[34]; -}; - -struct SmsFirmware_ST { - u32 CheckSum; - u32 Length; - u32 StartAddress; - u8 Payload[1]; -}; - -struct SMSHOSTLIB_STATISTICS_ST { - u32 Reserved; /* Reserved */ - - /* Common parameters */ - u32 IsRfLocked; /* 0 - not locked, 1 - locked */ - u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ - u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ - - /* Reception quality */ - s32 SNR; /* dB */ - u32 BER; /* Post Viterbi BER [1E-5] */ - u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ - u32 TS_PER; /* Transport stream PER, 0xFFFFFFFF indicate N/A, - * valid only for DVB-T/H */ - u32 MFER; /* DVB-H frame error rate in percentage, - * 0xFFFFFFFF indicate N/A, valid only for DVB-H */ - s32 RSSI; /* dBm */ - s32 InBandPwr; /* In band power in dBM */ - s32 CarrierOffset; /* Carrier Offset in bin/1024 */ - - /* Transmission parameters, valid only for DVB-T/H */ - u32 Frequency; /* Frequency in Hz */ - u32 Bandwidth; /* Bandwidth in MHz */ - u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, - * for DVB-T/H FFT mode carriers in Kilos */ - u32 ModemState; /* from SMS_DvbModemState_ET */ - u32 GuardInterval; /* Guard Interval, 1 divided by value */ - u32 CodeRate; /* Code Rate from SMS_DvbModemState_ET */ - u32 LPCodeRate; /* Low Priority Code Rate from SMS_DvbModemState_ET */ - u32 Hierarchy; /* Hierarchy from SMS_Hierarchy_ET */ - u32 Constellation; /* Constellation from SMS_Constellation_ET */ - - /* Burst parameters, valid only for DVB-H */ - u32 BurstSize; /* Current burst size in bytes */ - u32 BurstDuration; /* Current burst duration in mSec */ - u32 BurstCycleTime; /* Current burst cycle time in mSec */ - u32 CalculatedBurstCycleTime; /* Current burst cycle time in mSec, - * as calculated by demodulator */ - u32 NumOfRows; /* Number of rows in MPE table */ - u32 NumOfPaddCols; /* Number of padding columns in MPE table */ - u32 NumOfPunctCols; /* Number of puncturing columns in MPE table */ - /* Burst parameters */ - u32 ErrorTSPackets; /* Number of erroneous transport-stream packets */ - u32 TotalTSPackets; /* Total number of transport-stream packets */ - u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include - * errors after MPE RS decoding */ - u32 NumOfInvalidMpeTlbs; /* Number of MPE tables which include errors - * after MPE RS decoding */ - u32 NumOfCorrectedMpeTlbs; /* Number of MPE tables which were corrected - * by MPE RS decoding */ - - /* Common params */ - u32 BERErrorCount; /* Number of errornous SYNC bits. */ - u32 BERBitCount; /* Total number of SYNC bits. */ - - /* Interface information */ - u32 SmsToHostTxErrors; /* Total number of transmission errors. */ - - /* DAB/T-DMB */ - u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ - - /* DVB-H TPS parameters */ - u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; - * if set to 0xFFFFFFFF cell_id not yet recovered */ - -}; - -struct SmsMsgStatisticsInfo_ST { - u32 RequestResult; - - struct SMSHOSTLIB_STATISTICS_ST Stat; - - /* Split the calc of the SNR in DAB */ - u32 Signal; /* dB */ - u32 Noise; /* dB */ - -}; - - -struct smscore_gpio_config { -#define SMS_GPIO_DIRECTION_INPUT 0 -#define SMS_GPIO_DIRECTION_OUTPUT 1 - u8 direction; - -#define SMS_GPIO_PULLUPDOWN_NONE 0 -#define SMS_GPIO_PULLUPDOWN_PULLDOWN 1 -#define SMS_GPIO_PULLUPDOWN_PULLUP 2 -#define SMS_GPIO_PULLUPDOWN_KEEPER 3 - u8 pullupdown; - -#define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0 -#define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1 - u8 inputcharacteristics; - -#define SMS_GPIO_OUTPUTSLEWRATE_FAST 0 -#define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1 - u8 outputslewrate; - -#define SMS_GPIO_OUTPUTDRIVING_4mA 0 -#define SMS_GPIO_OUTPUTDRIVING_8mA 1 -#define SMS_GPIO_OUTPUTDRIVING_12mA 2 -#define SMS_GPIO_OUTPUTDRIVING_16mA 3 - u8 outputdriving; -}; - -struct smsdvb_client_t { - struct list_head entry; - - struct smscore_device_t *coredev; - struct smscore_client_t *smsclient; - - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dmxdev dmxdev; - struct dvb_frontend frontend; - - fe_status_t fe_status; - int fe_ber, fe_snr, fe_unc, fe_signal_strength; - - struct completion tune_done, stat_done; - - /* todo: save freq/band instead whole struct */ - struct dvb_frontend_parameters fe_params; - -}; - -extern void smscore_registry_setmode(char *devpath, int mode); -extern int smscore_registry_getmode(char *devpath); - -extern int smscore_register_hotplug(hotplug_t hotplug); -extern void smscore_unregister_hotplug(hotplug_t hotplug); - -extern int smscore_register_device(struct smsdevice_params_t *params, - struct smscore_device_t **coredev); -extern void smscore_unregister_device(struct smscore_device_t *coredev); - -extern int smscore_start_device(struct smscore_device_t *coredev); -extern int smscore_load_firmware(struct smscore_device_t *coredev, - char *filename, - loadfirmware_t loadfirmware_handler); - -extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode); -extern int smscore_get_device_mode(struct smscore_device_t *coredev); - -extern int smscore_register_client(struct smscore_device_t *coredev, - struct smsclient_params_t *params, - struct smscore_client_t **client); -extern void smscore_unregister_client(struct smscore_client_t *client); - -extern int smsclient_sendrequest(struct smscore_client_t *client, - void *buffer, size_t size); -extern void smscore_onresponse(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb); - - -extern -struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); -extern void smscore_putbuffer(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb); - -int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_gpio_config *pinconfig); -int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); - -void smscore_set_board_id(struct smscore_device_t *core, int id); -int smscore_get_board_id(struct smscore_device_t *core); - -int smscore_led_state(struct smscore_device_t *core, int led); - -/* smsdvb.c */ -int smsdvb_register(void); -void smsdvb_unregister(void); - -/* smsusb.c */ -int smsusb_register(void); -void smsusb_unregister(void); - -/* ------------------------------------------------------------------------ */ - -extern int sms_debug; - -#define DBG_INFO 1 -#define DBG_ADV 2 - -#define sms_printk(kern, fmt, arg...) \ - printk(kern "%s: " fmt "\n", __func__, ##arg) - -#define dprintk(kern, lvl, fmt, arg...) do {\ - if (sms_debug & lvl) \ - sms_printk(kern, fmt, ##arg); } while (0) - -#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) -#define sms_err(fmt, arg...) \ - sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg) -#define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg) -#define sms_info(fmt, arg...) \ - dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) -#define sms_debug(fmt, arg...) \ - dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) - - -#endif /* __smscoreapi_h__ */ diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c deleted file mode 100644 index 2da953a4f4f..00000000000 --- a/drivers/media/dvb/siano/smsdvb.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * author: Anatoly Greenblat - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/init.h> - -#include "smscoreapi.h" -#include "sms-cards.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static struct list_head g_smsdvb_clients; -static struct mutex g_smsdvb_clientslock; - -static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) -{ - struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; - struct SmsMsgHdr_ST *phdr = - (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); - - switch (phdr->msgType) { - case MSG_SMS_DVBT_BDA_DATA: - dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), - cb->size - sizeof(struct SmsMsgHdr_ST)); - break; - - case MSG_SMS_RF_TUNE_RES: - complete(&client->tune_done); - break; - - case MSG_SMS_GET_STATISTICS_RES: - { - struct SmsMsgStatisticsInfo_ST *p = - (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); - - if (p->Stat.IsDemodLocked) { - client->fe_status = FE_HAS_SIGNAL | - FE_HAS_CARRIER | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_LOCK; - - client->fe_snr = p->Stat.SNR; - client->fe_ber = p->Stat.BER; - client->fe_unc = p->Stat.BERErrorCount; - - if (p->Stat.InBandPwr < -95) - client->fe_signal_strength = 0; - else if (p->Stat.InBandPwr > -29) - client->fe_signal_strength = 100; - else - client->fe_signal_strength = - (p->Stat.InBandPwr + 95) * 3 / 2; - } else { - client->fe_status = 0; - client->fe_snr = - client->fe_ber = - client->fe_unc = - client->fe_signal_strength = 0; - } - - complete(&client->stat_done); - break; - } } - - smscore_putbuffer(client->coredev, cb); - - return 0; -} - -static void smsdvb_unregister_client(struct smsdvb_client_t *client) -{ - /* must be called under clientslock */ - - list_del(&client->entry); - - smscore_unregister_client(client->smsclient); - dvb_unregister_frontend(&client->frontend); - dvb_dmxdev_release(&client->dmxdev); - dvb_dmx_release(&client->demux); - dvb_unregister_adapter(&client->adapter); - kfree(client); -} - -static void smsdvb_onremove(void *context) -{ - kmutex_lock(&g_smsdvb_clientslock); - - smsdvb_unregister_client((struct smsdvb_client_t *) context); - - kmutex_unlock(&g_smsdvb_clientslock); -} - -static int smsdvb_start_feed(struct dvb_demux_feed *feed) -{ - struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); - struct SmsMsgData_ST PidMsg; - - sms_debug("add pid %d(%x)", - feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_ADD_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - return smsclient_sendrequest(client->smsclient, - &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_stop_feed(struct dvb_demux_feed *feed) -{ - struct smsdvb_client_t *client = - container_of(feed->demux, struct smsdvb_client_t, demux); - struct SmsMsgData_ST PidMsg; - - sms_debug("remove pid %d(%x)", - feed->pid, feed->pid); - - PidMsg.xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - PidMsg.xMsgHeader.msgDstId = HIF_TASK; - PidMsg.xMsgHeader.msgFlags = 0; - PidMsg.xMsgHeader.msgType = MSG_SMS_REMOVE_PID_FILTER_REQ; - PidMsg.xMsgHeader.msgLength = sizeof(PidMsg); - PidMsg.msgData[0] = feed->pid; - - return smsclient_sendrequest(client->smsclient, - &PidMsg, sizeof(PidMsg)); -} - -static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client, - void *buffer, size_t size, - struct completion *completion) -{ - int rc = smsclient_sendrequest(client->smsclient, buffer, size); - if (rc < 0) - return rc; - - return wait_for_completion_timeout(completion, - msecs_to_jiffies(2000)) ? - 0 : -ETIME; -} - -static int smsdvb_send_statistics_request(struct smsdvb_client_t *client) -{ - struct SmsMsgHdr_ST Msg = { MSG_SMS_GET_STATISTICS_REQ, - DVBT_BDA_CONTROL_MSG_ID, - HIF_TASK, sizeof(struct SmsMsgHdr_ST), 0 }; - int ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->stat_done); - if (ret < 0) - return ret; - - if (client->fe_status & FE_HAS_LOCK) - sms_board_led_feedback(client->coredev, - (client->fe_unc == 0) ? - SMS_LED_HI : SMS_LED_LO); - else - sms_board_led_feedback(client->coredev, SMS_LED_OFF); - return ret; -} - -static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *stat = client->fe_status; - - return rc; -} - -static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *ber = client->fe_ber; - - return rc; -} - -static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *strength = client->fe_signal_strength; - - return rc; -} - -static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *snr = client->fe_snr; - - return rc; -} - -static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - int rc = smsdvb_send_statistics_request(client); - - if (!rc) - *ucblocks = client->fe_unc; - - return rc; -} - -static int smsdvb_get_tune_settings(struct dvb_frontend *fe, - struct dvb_frontend_tune_settings *tune) -{ - sms_debug(""); - - tune->min_delay_ms = 400; - tune->step_size = 250000; - tune->max_drift = 0; - return 0; -} - -static int smsdvb_set_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - struct { - struct SmsMsgHdr_ST Msg; - u32 Data[3]; - } Msg; - - Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; - Msg.Msg.msgDstId = HIF_TASK; - Msg.Msg.msgFlags = 0; - Msg.Msg.msgType = MSG_SMS_RF_TUNE_REQ; - Msg.Msg.msgLength = sizeof(Msg); - Msg.Data[0] = fep->frequency; - Msg.Data[2] = 12000000; - - sms_debug("freq %d band %d", - fep->frequency, fep->u.ofdm.bandwidth); - - switch (fep->u.ofdm.bandwidth) { - case BANDWIDTH_8_MHZ: Msg.Data[1] = BW_8_MHZ; break; - case BANDWIDTH_7_MHZ: Msg.Data[1] = BW_7_MHZ; break; - case BANDWIDTH_6_MHZ: Msg.Data[1] = BW_6_MHZ; break; - case BANDWIDTH_AUTO: return -EOPNOTSUPP; - default: return -EINVAL; - } - - return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), - &client->tune_done); -} - -static int smsdvb_get_frontend(struct dvb_frontend *fe, - struct dvb_frontend_parameters *fep) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_debug(""); - - /* todo: */ - memcpy(fep, &client->fe_params, - sizeof(struct dvb_frontend_parameters)); - - return 0; -} - -static int smsdvb_init(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_board_power(client->coredev, 1); - - return 0; -} - -static int smsdvb_sleep(struct dvb_frontend *fe) -{ - struct smsdvb_client_t *client = - container_of(fe, struct smsdvb_client_t, frontend); - - sms_board_led_feedback(client->coredev, SMS_LED_OFF); - sms_board_power(client->coredev, 0); - - return 0; -} - -static void smsdvb_release(struct dvb_frontend *fe) -{ - /* do nothing */ -} - -static struct dvb_frontend_ops smsdvb_fe_ops = { - .info = { - .name = "Siano Mobile Digital SMS1xxx", - .type = FE_OFDM, - .frequency_min = 44250000, - .frequency_max = 867250000, - .frequency_stepsize = 250000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | - FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_RECOVER | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = smsdvb_release, - - .set_frontend = smsdvb_set_frontend, - .get_frontend = smsdvb_get_frontend, - .get_tune_settings = smsdvb_get_tune_settings, - - .read_status = smsdvb_read_status, - .read_ber = smsdvb_read_ber, - .read_signal_strength = smsdvb_read_signal_strength, - .read_snr = smsdvb_read_snr, - .read_ucblocks = smsdvb_read_ucblocks, - - .init = smsdvb_init, - .sleep = smsdvb_sleep, -}; - -static int smsdvb_hotplug(struct smscore_device_t *coredev, - struct device *device, int arrival) -{ - struct smsclient_params_t params; - struct smsdvb_client_t *client; - int rc; - - /* device removal handled by onremove callback */ - if (!arrival) - return 0; - - if (smscore_get_device_mode(coredev) != 4) { - sms_err("SMS Device mode is not set for " - "DVB operation."); - return 0; - } - - client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); - if (!client) { - sms_err("kmalloc() failed"); - return -ENOMEM; - } - - /* register dvb adapter */ - rc = dvb_register_adapter(&client->adapter, - sms_get_board( - smscore_get_board_id(coredev))->name, - THIS_MODULE, device, adapter_nr); - if (rc < 0) { - sms_err("dvb_register_adapter() failed %d", rc); - goto adapter_error; - } - - /* init dvb demux */ - client->demux.dmx.capabilities = DMX_TS_FILTERING; - client->demux.filternum = 32; /* todo: nova ??? */ - client->demux.feednum = 32; - client->demux.start_feed = smsdvb_start_feed; - client->demux.stop_feed = smsdvb_stop_feed; - - rc = dvb_dmx_init(&client->demux); - if (rc < 0) { - sms_err("dvb_dmx_init failed %d", rc); - goto dvbdmx_error; - } - - /* init dmxdev */ - client->dmxdev.filternum = 32; - client->dmxdev.demux = &client->demux.dmx; - client->dmxdev.capabilities = 0; - - rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter); - if (rc < 0) { - sms_err("dvb_dmxdev_init failed %d", rc); - goto dmxdev_error; - } - - /* init and register frontend */ - memcpy(&client->frontend.ops, &smsdvb_fe_ops, - sizeof(struct dvb_frontend_ops)); - - rc = dvb_register_frontend(&client->adapter, &client->frontend); - if (rc < 0) { - sms_err("frontend registration failed %d", rc); - goto frontend_error; - } - - params.initial_id = 1; - params.data_type = MSG_SMS_DVBT_BDA_DATA; - params.onresponse_handler = smsdvb_onresponse; - params.onremove_handler = smsdvb_onremove; - params.context = client; - - rc = smscore_register_client(coredev, ¶ms, &client->smsclient); - if (rc < 0) { - sms_err("smscore_register_client() failed %d", rc); - goto client_error; - } - - client->coredev = coredev; - - init_completion(&client->tune_done); - init_completion(&client->stat_done); - - kmutex_lock(&g_smsdvb_clientslock); - - list_add(&client->entry, &g_smsdvb_clients); - - kmutex_unlock(&g_smsdvb_clientslock); - - sms_info("success"); - - sms_board_setup(coredev); - - return 0; - -client_error: - dvb_unregister_frontend(&client->frontend); - -frontend_error: - dvb_dmxdev_release(&client->dmxdev); - -dmxdev_error: - dvb_dmx_release(&client->demux); - -dvbdmx_error: - dvb_unregister_adapter(&client->adapter); - -adapter_error: - kfree(client); - return rc; -} - -int smsdvb_register(void) -{ - int rc; - - INIT_LIST_HEAD(&g_smsdvb_clients); - kmutex_init(&g_smsdvb_clientslock); - - rc = smscore_register_hotplug(smsdvb_hotplug); - - sms_debug(""); - - return rc; -} - -void smsdvb_unregister(void) -{ - smscore_unregister_hotplug(smsdvb_hotplug); - - kmutex_lock(&g_smsdvb_clientslock); - - while (!list_empty(&g_smsdvb_clients)) - smsdvb_unregister_client( - (struct smsdvb_client_t *) g_smsdvb_clients.next); - - kmutex_unlock(&g_smsdvb_clientslock); -} diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c deleted file mode 100644 index 5d7ca341771..00000000000 --- a/drivers/media/dvb/siano/smsusb.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Driver for the Siano SMS1xxx USB dongle - * - * author: Anatoly Greenblat - * - * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * Software distributed under the License is distributed on an "AS IS" - * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. - * - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/usb.h> -#include <linux/firmware.h> - -#include "smscoreapi.h" -#include "sms-cards.h" - -#define USB1_BUFFER_SIZE 0x1000 -#define USB2_BUFFER_SIZE 0x4000 - -#define MAX_BUFFERS 50 -#define MAX_URBS 10 - -struct smsusb_device_t; - -struct smsusb_urb_t { - struct smscore_buffer_t *cb; - struct smsusb_device_t *dev; - - struct urb urb; -}; - -struct smsusb_device_t { - struct usb_device *udev; - struct smscore_device_t *coredev; - - struct smsusb_urb_t surbs[MAX_URBS]; - - int response_alignment; - int buffer_size; -}; - -static int smsusb_submit_urb(struct smsusb_device_t *dev, - struct smsusb_urb_t *surb); - -static void smsusb_onresponse(struct urb *urb) -{ - struct smsusb_urb_t *surb = (struct smsusb_urb_t *) urb->context; - struct smsusb_device_t *dev = surb->dev; - - if (urb->status < 0) { - sms_err("error, urb status %d, %d bytes", - urb->status, urb->actual_length); - return; - } - - if (urb->actual_length > 0) { - struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) surb->cb->p; - - if (urb->actual_length >= phdr->msgLength) { - surb->cb->size = phdr->msgLength; - - if (dev->response_alignment && - (phdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG)) { - - surb->cb->offset = - dev->response_alignment + - ((phdr->msgFlags >> 8) & 3); - - /* sanity check */ - if (((int) phdr->msgLength + - surb->cb->offset) > urb->actual_length) { - sms_err("invalid response " - "msglen %d offset %d " - "size %d", - phdr->msgLength, - surb->cb->offset, - urb->actual_length); - goto exit_and_resubmit; - } - - /* move buffer pointer and - * copy header to its new location */ - memcpy((char *) phdr + surb->cb->offset, - phdr, sizeof(struct SmsMsgHdr_ST)); - } else - surb->cb->offset = 0; - - smscore_onresponse(dev->coredev, surb->cb); - surb->cb = NULL; - } else { - sms_err("invalid response " - "msglen %d actual %d", - phdr->msgLength, urb->actual_length); - } - } - -exit_and_resubmit: - smsusb_submit_urb(dev, surb); -} - -static int smsusb_submit_urb(struct smsusb_device_t *dev, - struct smsusb_urb_t *surb) -{ - if (!surb->cb) { - surb->cb = smscore_getbuffer(dev->coredev); - if (!surb->cb) { - sms_err("smscore_getbuffer(...) returned NULL"); - return -ENOMEM; - } - } - - usb_fill_bulk_urb( - &surb->urb, - dev->udev, - usb_rcvbulkpipe(dev->udev, 0x81), - surb->cb->p, - dev->buffer_size, - smsusb_onresponse, - surb - ); - surb->urb.transfer_dma = surb->cb->phys; - surb->urb.transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - - return usb_submit_urb(&surb->urb, GFP_ATOMIC); -} - -static void smsusb_stop_streaming(struct smsusb_device_t *dev) -{ - int i; - - for (i = 0; i < MAX_URBS; i++) { - usb_kill_urb(&dev->surbs[i].urb); - - if (dev->surbs[i].cb) { - smscore_putbuffer(dev->coredev, dev->surbs[i].cb); - dev->surbs[i].cb = NULL; - } - } -} - -static int smsusb_start_streaming(struct smsusb_device_t *dev) -{ - int i, rc; - - for (i = 0; i < MAX_URBS; i++) { - rc = smsusb_submit_urb(dev, &dev->surbs[i]); - if (rc < 0) { - sms_err("smsusb_submit_urb(...) failed"); - smsusb_stop_streaming(dev); - break; - } - } - - return rc; -} - -static int smsusb_sendrequest(void *context, void *buffer, size_t size) -{ - struct smsusb_device_t *dev = (struct smsusb_device_t *) context; - int dummy; - - return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), - buffer, size, &dummy, 1000); -} - -static char *smsusb1_fw_lkup[] = { - "dvbt_stellar_usb.inp", - "dvbh_stellar_usb.inp", - "tdmb_stellar_usb.inp", - "none", - "dvbt_bda_stellar_usb.inp", -}; - -static inline char *sms_get_fw_name(int mode, int board_id) -{ - char **fw = sms_get_board(board_id)->fw; - return (fw && fw[mode]) ? fw[mode] : smsusb1_fw_lkup[mode]; -} - -static int smsusb1_load_firmware(struct usb_device *udev, int id, int board_id) -{ - const struct firmware *fw; - u8 *fw_buffer; - int rc, dummy; - char *fw_filename; - - if (id < DEVICE_MODE_DVBT || id > DEVICE_MODE_DVBT_BDA) { - sms_err("invalid firmware id specified %d", id); - return -EINVAL; - } - - fw_filename = sms_get_fw_name(id, board_id); - - rc = request_firmware(&fw, fw_filename, &udev->dev); - if (rc < 0) { - sms_warn("failed to open \"%s\" mode %d, " - "trying again with default firmware", fw_filename, id); - - fw_filename = smsusb1_fw_lkup[id]; - rc = request_firmware(&fw, fw_filename, &udev->dev); - if (rc < 0) { - sms_warn("failed to open \"%s\" mode %d", - fw_filename, id); - - return rc; - } - } - - fw_buffer = kmalloc(fw->size, GFP_KERNEL); - if (fw_buffer) { - memcpy(fw_buffer, fw->data, fw->size); - - rc = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 2), - fw_buffer, fw->size, &dummy, 1000); - - sms_info("sent %zd(%d) bytes, rc %d", fw->size, dummy, rc); - - kfree(fw_buffer); - } else { - sms_err("failed to allocate firmware buffer"); - rc = -ENOMEM; - } - sms_info("read FW %s, size=%zd", fw_filename, fw->size); - - release_firmware(fw); - - return rc; -} - -static void smsusb1_detectmode(void *context, int *mode) -{ - char *product_string = - ((struct smsusb_device_t *) context)->udev->product; - - *mode = DEVICE_MODE_NONE; - - if (!product_string) { - product_string = "none"; - sms_err("product string not found"); - } else if (strstr(product_string, "DVBH")) - *mode = 1; - else if (strstr(product_string, "BDA")) - *mode = 4; - else if (strstr(product_string, "DVBT")) - *mode = 0; - else if (strstr(product_string, "TDMB")) - *mode = 2; - - sms_info("%d \"%s\"", *mode, product_string); -} - -static int smsusb1_setmode(void *context, int mode) -{ - struct SmsMsgHdr_ST Msg = { MSG_SW_RELOAD_REQ, 0, HIF_TASK, - sizeof(struct SmsMsgHdr_ST), 0 }; - - if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { - sms_err("invalid firmware id specified %d", mode); - return -EINVAL; - } - - return smsusb_sendrequest(context, &Msg, sizeof(Msg)); -} - -static void smsusb_term_device(struct usb_interface *intf) -{ - struct smsusb_device_t *dev = - (struct smsusb_device_t *) usb_get_intfdata(intf); - - if (dev) { - smsusb_stop_streaming(dev); - - /* unregister from smscore */ - if (dev->coredev) - smscore_unregister_device(dev->coredev); - - kfree(dev); - - sms_info("device %p destroyed", dev); - } - - usb_set_intfdata(intf, NULL); -} - -static int smsusb_init_device(struct usb_interface *intf, int board_id) -{ - struct smsdevice_params_t params; - struct smsusb_device_t *dev; - int i, rc; - - /* create device object */ - dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); - if (!dev) { - sms_err("kzalloc(sizeof(struct smsusb_device_t) failed"); - return -ENOMEM; - } - - memset(¶ms, 0, sizeof(params)); - usb_set_intfdata(intf, dev); - dev->udev = interface_to_usbdev(intf); - - params.device_type = sms_get_board(board_id)->type; - - switch (params.device_type) { - case SMS_STELLAR: - dev->buffer_size = USB1_BUFFER_SIZE; - - params.setmode_handler = smsusb1_setmode; - params.detectmode_handler = smsusb1_detectmode; - break; - default: - sms_err("Unspecified sms device type!"); - /* fall-thru */ - case SMS_NOVA_A0: - case SMS_NOVA_B0: - case SMS_VEGA: - dev->buffer_size = USB2_BUFFER_SIZE; - dev->response_alignment = - dev->udev->ep_in[1]->desc.wMaxPacketSize - - sizeof(struct SmsMsgHdr_ST); - - params.flags |= SMS_DEVICE_FAMILY2; - break; - } - - params.device = &dev->udev->dev; - params.buffer_size = dev->buffer_size; - params.num_buffers = MAX_BUFFERS; - params.sendrequest_handler = smsusb_sendrequest; - params.context = dev; - snprintf(params.devpath, sizeof(params.devpath), - "usb\\%d-%s", dev->udev->bus->busnum, dev->udev->devpath); - - /* register in smscore */ - rc = smscore_register_device(¶ms, &dev->coredev); - if (rc < 0) { - sms_err("smscore_register_device(...) failed, rc %d", rc); - smsusb_term_device(intf); - return rc; - } - - smscore_set_board_id(dev->coredev, board_id); - - /* initialize urbs */ - for (i = 0; i < MAX_URBS; i++) { - dev->surbs[i].dev = dev; - usb_init_urb(&dev->surbs[i].urb); - } - - sms_info("smsusb_start_streaming(...)."); - rc = smsusb_start_streaming(dev); - if (rc < 0) { - sms_err("smsusb_start_streaming(...) failed"); - smsusb_term_device(intf); - return rc; - } - - rc = smscore_start_device(dev->coredev); - if (rc < 0) { - sms_err("smscore_start_device(...) failed"); - smsusb_term_device(intf); - return rc; - } - - sms_info("device %p created", dev); - - return rc; -} - -static int smsusb_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(intf); - char devpath[32]; - int i, rc; - - rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); - rc = usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); - - if (intf->num_altsetting > 0) { - rc = usb_set_interface( - udev, intf->cur_altsetting->desc.bInterfaceNumber, 0); - if (rc < 0) { - sms_err("usb_set_interface failed, rc %d", rc); - return rc; - } - } - - sms_info("smsusb_probe %d", - intf->cur_altsetting->desc.bInterfaceNumber); - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) - sms_info("endpoint %d %02x %02x %d", i, - intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, - intf->cur_altsetting->endpoint[i].desc.bmAttributes, - intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - - if ((udev->actconfig->desc.bNumInterfaces == 2) && - (intf->cur_altsetting->desc.bInterfaceNumber == 0)) { - sms_err("rom interface 0 is not used"); - return -ENODEV; - } - - if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { - snprintf(devpath, sizeof(devpath), "usb\\%d-%s", - udev->bus->busnum, udev->devpath); - sms_info("stellar device was found."); - return smsusb1_load_firmware( - udev, smscore_registry_getmode(devpath), - id->driver_info); - } - - rc = smsusb_init_device(intf, id->driver_info); - sms_info("rc %d", rc); - return rc; -} - -static void smsusb_disconnect(struct usb_interface *intf) -{ - smsusb_term_device(intf); -} - -static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg) -{ - struct smsusb_device_t *dev = - (struct smsusb_device_t *)usb_get_intfdata(intf); - printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event); - smsusb_stop_streaming(dev); - return 0; -} - -static int smsusb_resume(struct usb_interface *intf) -{ - int rc, i; - struct smsusb_device_t *dev = - (struct smsusb_device_t *)usb_get_intfdata(intf); - struct usb_device *udev = interface_to_usbdev(intf); - - printk(KERN_INFO "%s Entering.\n", __func__); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81)); - usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02)); - - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) - printk(KERN_INFO "endpoint %d %02x %02x %d\n", i, - intf->cur_altsetting->endpoint[i].desc.bEndpointAddress, - intf->cur_altsetting->endpoint[i].desc.bmAttributes, - intf->cur_altsetting->endpoint[i].desc.wMaxPacketSize); - - if (intf->num_altsetting > 0) { - rc = usb_set_interface(udev, - intf->cur_altsetting->desc. - bInterfaceNumber, 0); - if (rc < 0) { - printk(KERN_INFO - "%s usb_set_interface failed, rc %d\n", - __func__, rc); - return rc; - } - } - - smsusb_start_streaming(dev); - return 0; -} - -static struct usb_driver smsusb_driver = { - .name = "sms1xxx", - .probe = smsusb_probe, - .disconnect = smsusb_disconnect, - .id_table = smsusb_id_table, - - .suspend = smsusb_suspend, - .resume = smsusb_resume, -}; - -int smsusb_register(void) -{ - int rc = usb_register(&smsusb_driver); - if (rc) - sms_err("usb_register failed. Error number %d", rc); - - sms_debug(""); - - return rc; -} - -void smsusb_unregister(void) -{ - sms_debug(""); - /* Regular USB Cleanup */ - usb_deregister(&smsusb_driver); -} - diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig deleted file mode 100644 index ab0bcd208c7..00000000000 --- a/drivers/media/dvb/ttpci/Kconfig +++ /dev/null @@ -1,169 +0,0 @@ -config TTPCI_EEPROM - tristate - default n - -config DVB_AV7110 - tristate "AV7110 cards" - depends on DVB_CORE && PCI && I2C - select TTPCI_EEPROM - select VIDEO_SAA7146_VV - depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV - select DVB_VES1820 if !DVB_FE_CUSTOMISE - select DVB_VES1X93 if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_TDA8083 if !DVB_FE_CUSTOMISE - select DVB_SP8870 if !DVB_FE_CUSTOMISE - select DVB_STV0297 if !DVB_FE_CUSTOMISE - select DVB_L64781 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - help - Support for SAA7146 and AV7110 based DVB cards as produced - by Fujitsu-Siemens, Technotrend, Hauppauge and others. - - This driver only supports the fullfeatured cards with - onboard MPEG2 decoder. - - This driver needs an external firmware. Please use the script - "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - - Say Y if you own such a card and want to use it. - -config DVB_AV7110_FIRMWARE - bool "Compile AV7110 firmware into the driver" - depends on DVB_AV7110 && !STANDALONE - default y if DVB_AV7110=y - help - The AV7110 firmware is normally loaded by the firmware hotplug manager. - If you want to compile the firmware into the driver you need to say - Y here and provide the correct path of the firmware. You need this - option if you want to compile the whole driver statically into the - kernel. - - All other people say N. - -config DVB_AV7110_FIRMWARE_FILE - string "Full pathname of av7110 firmware file" - depends on DVB_AV7110_FIRMWARE - default "/usr/lib/hotplug/firmware/dvb-ttpci-01.fw" - -config DVB_AV7110_OSD - bool "AV7110 OSD support" - depends on DVB_AV7110 - default y if DVB_AV7110=y || DVB_AV7110=m - help - The AV7110 firmware provides some code to generate an OnScreenDisplay - on the video output. This is kind of nonstandard and not guaranteed to - be maintained. - - Anyway, some popular DVB software like VDR uses this OSD to render - its menus, so say Y if you want to use this software. - - All other people say N. - -config DVB_BUDGET_CORE - tristate "SAA7146 DVB cards (aka Budget, Nova-PCI)" - depends on DVB_CORE && PCI && I2C - select VIDEO_SAA7146 - select TTPCI_EEPROM - help - Support for simple SAA7146 based DVB cards - (so called Budget- or Nova-PCI cards) without onboard - MPEG2 decoder. - -config DVB_BUDGET - tristate "Budget cards" - depends on DVB_BUDGET_CORE && I2C - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_VES1X93 if !DVB_FE_CUSTOMISE - select DVB_VES1820 if !DVB_FE_CUSTOMISE - select DVB_L64781 if !DVB_FE_CUSTOMISE - select DVB_TDA8083 if !DVB_FE_CUSTOMISE - select DVB_TDA10021 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE - select DVB_S5H1420 if !DVB_FE_CUSTOMISE - select DVB_TDA10086 if !DVB_FE_CUSTOMISE - select DVB_TDA826X if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_TDA1004X if !DVB_FE_CUSTOMISE - help - Support for simple SAA7146 based DVB cards (so called Budget- - or Nova-PCI cards) without onboard MPEG2 decoder, and without - analog inputs or an onboard Common Interface connector. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget. - -config DVB_BUDGET_CI - tristate "Budget cards with onboard CI connector" - depends on DVB_BUDGET_CORE && I2C - depends on INPUT # due to IR - select DVB_STV0297 if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_TDA1004X if !DVB_FE_CUSTOMISE - select DVB_STB0899 if !DVB_FE_CUSTOMISE - select DVB_STB6100 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE - select VIDEO_IR - help - Support for simple SAA7146 based DVB cards - (so called Budget- or Nova-PCI cards) without onboard - MPEG2 decoder, but with onboard Common Interface connector. - - Note: The Common Interface is not yet supported by this driver - due to lack of information from the vendor. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget-ci. - -config DVB_BUDGET_AV - tristate "Budget cards with analog video inputs" - depends on DVB_BUDGET_CORE && I2C - select VIDEO_SAA7146_VV - depends on VIDEO_DEV # dependencies of VIDEO_SAA7146_VV - select DVB_PLL if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_TDA1004X if !DVB_FE_CUSTOMISE - select DVB_TDA10021 if !DVB_FE_CUSTOMISE - select DVB_TDA10023 if !DVB_FE_CUSTOMISE - select DVB_STB0899 if !DVB_FE_CUSTOMISE - select DVB_TDA8261 if !DVB_FE_CUSTOMISE - select DVB_TUA6100 if !DVB_FE_CUSTOMISE - help - Support for simple SAA7146 based DVB cards - (so called Budget- or Nova-PCI cards) without onboard - MPEG2 decoder, but with one or more analog video inputs. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget-av. - -config DVB_BUDGET_PATCH - tristate "AV7110 cards with Budget Patch" - depends on DVB_BUDGET_CORE && I2C - depends on DVB_AV7110 - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_VES1X93 if !DVB_FE_CUSTOMISE - select DVB_TDA8083 if !DVB_FE_CUSTOMISE - help - Support for Budget Patch (full TS) modification on - SAA7146+AV7110 based cards (DVB-S cards). This - driver doesn't use onboard MPEG2 decoder. The - card is driven in Budget-only mode. Card is - required to have loaded firmware to tune properly. - Firmware can be loaded by insertion and removal of - standard AV7110 driver prior to loading this - driver. - - Say Y if you own such a card and want to use it. - - To compile this driver as a module, choose M here: the - module will be called budget-patch. diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile deleted file mode 100644 index 71451237294..00000000000 --- a/drivers/media/dvb/ttpci/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Makefile for the kernel SAA7146 FULL TS DVB device driver -# and the AV7110 DVB device driver -# - -dvb-ttpci-objs := av7110_hw.o av7110_v4l.o av7110_av.o av7110_ca.o av7110.o av7110_ipack.o - -ifdef CONFIG_INPUT_EVDEV -dvb-ttpci-objs += av7110_ir.o -endif - -obj-$(CONFIG_TTPCI_EEPROM) += ttpci-eeprom.o -obj-$(CONFIG_DVB_BUDGET_CORE) += budget-core.o -obj-$(CONFIG_DVB_BUDGET) += budget.o -obj-$(CONFIG_DVB_BUDGET_AV) += budget-av.o -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 - -hostprogs-y := fdump - -ifeq ($(CONFIG_DVB_AV7110_FIRMWARE),y) -$(obj)/av7110.o: $(obj)/av7110_firm.h - -$(obj)/av7110_firm.h: $(obj)/fdump - $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ -endif diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c deleted file mode 100644 index aa1ff524256..00000000000 --- a/drivers/media/dvb/ttpci/av7110.c +++ /dev/null @@ -1,2941 +0,0 @@ -/* - * driver for the SAA7146 based AV110 cards (like the Fujitsu-Siemens DVB) - * av7110.c: initialization and demux stuff - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * originally based on code by: - * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - - -#include <linux/module.h> -#include <linux/kmod.h> -#include <linux/delay.h> -#include <linux/fs.h> -#include <linux/timer.h> -#include <linux/poll.h> -#include <linux/smp_lock.h> - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/fcntl.h> -#include <linux/interrupt.h> -#include <linux/string.h> -#include <linux/pci.h> -#include <linux/vmalloc.h> -#include <linux/firmware.h> -#include <linux/crc32.h> -#include <linux/i2c.h> -#include <linux/kthread.h> -#include <asm/unaligned.h> -#include <asm/byteorder.h> - -#include <asm/system.h> - -#include <linux/dvb/frontend.h> - -#include "dvb_frontend.h" - -#include "ttpci-eeprom.h" -#include "av7110.h" -#include "av7110_hw.h" -#include "av7110_av.h" -#include "av7110_ca.h" -#include "av7110_ipack.h" - -#include "bsbe1.h" -#include "lnbp21.h" -#include "bsru6.h" - -#define TS_WIDTH 376 -#define TS_HEIGHT 512 -#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) -#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE) - - -int av7110_debug; - -static int vidmode = CVBS_RGB_OUT; -static int pids_off; -static int adac = DVB_ADAC_TI; -static int hw_sections; -static int rgb_on; -static int volume = 255; -static int budgetpatch; -static int wss_cfg_4_3 = 0x4008; -static int wss_cfg_16_9 = 0x0007; -static int tv_standard; -static int full_ts; - -module_param_named(debug, av7110_debug, int, 0644); -MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)"); -module_param(vidmode, int, 0444); -MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC"); -module_param(pids_off, int, 0444); -MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed"); -module_param(adac, int, 0444); -MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)"); -module_param(hw_sections, int, 0444); -MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware"); -module_param(rgb_on, int, 0444); -MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control" - " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB"); -module_param(volume, int, 0444); -MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)"); -module_param(budgetpatch, int, 0444); -MODULE_PARM_DESC(budgetpatch, "use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)"); -module_param(full_ts, int, 0444); -MODULE_PARM_DESC(full_ts, "enable code for full-ts hardware modification: 0 disable (default), 1 enable"); -module_param(wss_cfg_4_3, int, 0444); -MODULE_PARM_DESC(wss_cfg_4_3, "WSS 4:3 - default 0x4008 - bit 15: disable, 14: burst mode, 13..0: wss data"); -module_param(wss_cfg_16_9, int, 0444); -MODULE_PARM_DESC(wss_cfg_16_9, "WSS 16:9 - default 0x0007 - bit 15: disable, 14: burst mode, 13..0: wss data"); -module_param(tv_standard, int, 0444); -MODULE_PARM_DESC(tv_standard, "TV standard: 0 PAL (default), 1 NTSC"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static void restart_feeds(struct av7110 *av7110); -static int budget_start_feed(struct dvb_demux_feed *feed); -static int budget_stop_feed(struct dvb_demux_feed *feed); - -static int av7110_num; - -#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \ -{\ - if (fe_func != NULL) { \ - av7110_copy = fe_func; \ - fe_func = av7110_func; \ - } \ -} - - -static void init_av7110_av(struct av7110 *av7110) -{ - int ret; - struct saa7146_dev *dev = av7110->dev; - - /* set internal volume control to maximum */ - av7110->adac_type = DVB_ADAC_TI; - ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); - if (ret < 0) - printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret); - - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, - 1, (u16) av7110->display_ar); - if (ret < 0) - printk("dvb-ttpci: unable to set aspect ratio\n"); - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, - 1, av7110->display_panscan); - if (ret < 0) - printk("dvb-ttpci: unable to set pan scan\n"); - - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 2, wss_cfg_4_3); - if (ret < 0) - printk("dvb-ttpci: unable to configure 4:3 wss\n"); - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 3, wss_cfg_16_9); - if (ret < 0) - printk("dvb-ttpci: unable to configure 16:9 wss\n"); - - ret = av7710_set_video_mode(av7110, vidmode); - if (ret < 0) - printk("dvb-ttpci:cannot set video mode:%d\n",ret); - - /* handle different card types */ - /* remaining inits according to card and frontend type */ - av7110->analog_tuner_flags = 0; - av7110->current_input = 0; - if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) - av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on - if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { - printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", - av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_CRYSTAL; - i2c_writereg(av7110, 0x20, 0x01, 0xd2); - i2c_writereg(av7110, 0x20, 0x02, 0x49); - i2c_writereg(av7110, 0x20, 0x03, 0x00); - i2c_writereg(av7110, 0x20, 0x04, 0x00); - - /** - * some special handling for the Siemens DVB-C cards... - */ - } else if (0 == av7110_init_analog_module(av7110)) { - /* done. */ - } - else if (dev->pci->subsystem_vendor == 0x110a) { - printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n", - av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_NONE; - } - else { - av7110->adac_type = adac; - printk("dvb-ttpci: adac type set to %d @ card %d\n", - av7110->adac_type, av7110->dvb_adapter.num); - } - - if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) { - // switch DVB SCART on - ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); - if (ret < 0) - printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret); - ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); - if (ret < 0) - printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret); - if (rgb_on && - ((av7110->dev->pci->subsystem_vendor == 0x110a) || - (av7110->dev->pci->subsystem_vendor == 0x13c2)) && - (av7110->dev->pci->subsystem_device == 0x0000)) { - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 - //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 - } - } - - if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000e) - av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, SpdifSwitch, 1, 0); // SPDIF on - - ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); - if (ret < 0) - printk("dvb-ttpci:cannot set volume :%d\n",ret); -} - -static void recover_arm(struct av7110 *av7110) -{ - dprintk(4, "%p\n",av7110); - - av7110_bootarm(av7110); - msleep(100); - - init_av7110_av(av7110); - - /* card-specific recovery */ - if (av7110->recover) - av7110->recover(av7110); - - restart_feeds(av7110); - -#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) - av7110_check_ir_config(av7110, true); -#endif -} - -static void av7110_arm_sync(struct av7110 *av7110) -{ - if (av7110->arm_thread) - kthread_stop(av7110->arm_thread); - - av7110->arm_thread = NULL; -} - -static int arm_thread(void *data) -{ - struct av7110 *av7110 = data; - u16 newloops = 0; - int timeout; - - dprintk(4, "%p\n",av7110); - - for (;;) { - timeout = wait_event_interruptible_timeout(av7110->arm_wait, - kthread_should_stop(), 5 * HZ); - - if (-ERESTARTSYS == timeout || kthread_should_stop()) { - /* got signal or told to quit*/ - break; - } - - if (!av7110->arm_ready) - continue; - -#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) - av7110_check_ir_config(av7110, false); -#endif - - if (mutex_lock_interruptible(&av7110->dcomlock)) - break; - newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); - mutex_unlock(&av7110->dcomlock); - - if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { - printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", - av7110->dvb_adapter.num); - - recover_arm(av7110); - - if (mutex_lock_interruptible(&av7110->dcomlock)) - break; - newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; - mutex_unlock(&av7110->dcomlock); - } - av7110->arm_loops = newloops; - av7110->arm_errors = 0; - } - - return 0; -} - - -/**************************************************************************** - * IRQ handling - ****************************************************************************/ - -static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len, - u8 *buffer2, size_t buffer2_len, - struct dvb_demux_filter *dvbdmxfilter, - enum dmx_success success, - struct av7110 *av7110) -{ - if (!dvbdmxfilter->feed->demux->dmx.frontend) - return 0; - if (dvbdmxfilter->feed->demux->dmx.frontend->source == DMX_MEMORY_FE) - return 0; - - switch (dvbdmxfilter->type) { - case DMX_TYPE_SEC: - if ((((buffer1[1] << 8) | buffer1[2]) & 0xfff) + 3 != buffer1_len) - return 0; - if (dvbdmxfilter->doneq) { - struct dmx_section_filter *filter = &dvbdmxfilter->filter; - int i; - u8 xor, neq = 0; - - for (i = 0; i < DVB_DEMUX_MASK_MAX; i++) { - xor = filter->filter_value[i] ^ buffer1[i]; - neq |= dvbdmxfilter->maskandnotmode[i] & xor; - } - if (!neq) - return 0; - } - return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, - buffer2, buffer2_len, - &dvbdmxfilter->filter, - DMX_OK); - case DMX_TYPE_TS: - if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) - return 0; - if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) - return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, - buffer2, buffer2_len, - &dvbdmxfilter->feed->feed.ts, - DMX_OK); - else - av7110_p2t_write(buffer1, buffer1_len, - dvbdmxfilter->feed->pid, - &av7110->p2t_filter[dvbdmxfilter->index]); - default: - return 0; - } -} - - -//#define DEBUG_TIMING -static inline void print_time(char *s) -{ -#ifdef DEBUG_TIMING - struct timeval tv; - do_gettimeofday(&tv); - printk("%s: %d.%d\n", s, (int)tv.tv_sec, (int)tv.tv_usec); -#endif -} - -#define DEBI_READ 0 -#define DEBI_WRITE 1 -static inline void start_debi_dma(struct av7110 *av7110, int dir, - unsigned long addr, unsigned int len) -{ - dprintk(8, "%c %08lx %u\n", dir == DEBI_READ ? 'R' : 'W', addr, len); - if (saa7146_wait_for_debi_done(av7110->dev, 0)) { - printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__); - return; - } - - SAA7146_ISR_CLEAR(av7110->dev, MASK_19); /* for good measure */ - SAA7146_IER_ENABLE(av7110->dev, MASK_19); - if (len < 5) - len = 5; /* we want a real DEBI DMA */ - if (dir == DEBI_WRITE) - iwdebi(av7110, DEBISWAB, addr, 0, (len + 3) & ~3); - else - irdebi(av7110, DEBISWAB, addr, 0, len); -} - -static void debiirq(unsigned long cookie) -{ - struct av7110 *av7110 = (struct av7110 *)cookie; - int type = av7110->debitype; - int handle = (type >> 8) & 0x1f; - unsigned int xfer = 0; - - print_time("debi"); - dprintk(4, "type 0x%04x\n", type); - - if (type == -1) { - printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", - jiffies, saa7146_read(av7110->dev, PSR), - saa7146_read(av7110->dev, SSR)); - goto debi_done; - } - av7110->debitype = -1; - - switch (type & 0xff) { - - case DATA_TS_RECORD: - dvb_dmx_swfilter_packets(&av7110->demux, - (const u8 *) av7110->debi_virt, - av7110->debilen / 188); - xfer = RX_BUFF; - break; - - case DATA_PES_RECORD: - if (av7110->demux.recording) - av7110_record_cb(&av7110->p2t[handle], - (u8 *) av7110->debi_virt, - av7110->debilen); - xfer = RX_BUFF; - break; - - case DATA_IPMPE: - case DATA_FSECTION: - case DATA_PIPING: - if (av7110->handle2filter[handle]) - DvbDmxFilterCallback((u8 *)av7110->debi_virt, - av7110->debilen, NULL, 0, - av7110->handle2filter[handle], - DMX_OK, av7110); - xfer = RX_BUFF; - break; - - case DATA_CI_GET: - { - u8 *data = av7110->debi_virt; - - if ((data[0] < 2) && data[2] == 0xff) { - int flags = 0; - if (data[5] > 0) - flags |= CA_CI_MODULE_PRESENT; - if (data[5] > 5) - flags |= CA_CI_MODULE_READY; - av7110->ci_slot[data[0]].flags = flags; - } else - ci_get_data(&av7110->ci_rbuffer, - av7110->debi_virt, - av7110->debilen); - xfer = RX_BUFF; - break; - } - - case DATA_COMMON_INTERFACE: - CI_handle(av7110, (u8 *)av7110->debi_virt, av7110->debilen); -#if 0 - { - int i; - - printk("av7110%d: ", av7110->num); - printk("%02x ", *(u8 *)av7110->debi_virt); - printk("%02x ", *(1+(u8 *)av7110->debi_virt)); - for (i = 2; i < av7110->debilen; i++) - printk("%02x ", (*(i+(unsigned char *)av7110->debi_virt))); - for (i = 2; i < av7110->debilen; i++) - printk("%c", chtrans(*(i+(unsigned char *)av7110->debi_virt))); - - printk("\n"); - } -#endif - xfer = RX_BUFF; - break; - - case DATA_DEBUG_MESSAGE: - ((s8*)av7110->debi_virt)[Reserved_SIZE - 1] = 0; - printk("%s\n", (s8 *) av7110->debi_virt); - xfer = RX_BUFF; - break; - - case DATA_CI_PUT: - dprintk(4, "debi DATA_CI_PUT\n"); - case DATA_MPEG_PLAY: - dprintk(4, "debi DATA_MPEG_PLAY\n"); - case DATA_BMP_LOAD: - dprintk(4, "debi DATA_BMP_LOAD\n"); - xfer = TX_BUFF; - break; - default: - break; - } -debi_done: - spin_lock(&av7110->debilock); - if (xfer) - iwdebi(av7110, DEBINOSWAP, xfer, 0, 2); - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); -} - -/* irq from av7110 firmware writing the mailbox register in the DPRAM */ -static void gpioirq(unsigned long cookie) -{ - struct av7110 *av7110 = (struct av7110 *)cookie; - u32 rxbuf, txbuf; - int len; - - if (av7110->debitype != -1) - /* we shouldn't get any irq while a debi xfer is running */ - printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", - jiffies, saa7146_read(av7110->dev, PSR), - saa7146_read(av7110->dev, SSR)); - - if (saa7146_wait_for_debi_done(av7110->dev, 0)) { - printk(KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n", __func__); - BUG(); /* maybe we should try resetting the debi? */ - } - - spin_lock(&av7110->debilock); - ARM_ClearIrq(av7110); - - /* see what the av7110 wants */ - av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); - av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - rxbuf = irdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - txbuf = irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - len = (av7110->debilen + 3) & ~3; - - print_time("gpio"); - dprintk(8, "GPIO0 irq 0x%04x %d\n", av7110->debitype, av7110->debilen); - - switch (av7110->debitype & 0xff) { - - case DATA_TS_PLAY: - case DATA_PES_PLAY: - break; - - case DATA_MPEG_VIDEO_EVENT: - { - u32 h_ar; - struct video_event event; - - av7110->video_size.w = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_WIDTH, 0, 2); - h_ar = irdebi(av7110, DEBINOSWAP, STATUS_MPEG_HEIGHT_AR, 0, 2); - - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - - av7110->video_size.h = h_ar & 0xfff; - - event.type = VIDEO_EVENT_SIZE_CHANGED; - event.u.size.w = av7110->video_size.w; - event.u.size.h = av7110->video_size.h; - switch ((h_ar >> 12) & 0xf) - { - case 3: - av7110->video_size.aspect_ratio = VIDEO_FORMAT_16_9; - event.u.size.aspect_ratio = VIDEO_FORMAT_16_9; - av7110->videostate.video_format = VIDEO_FORMAT_16_9; - break; - case 4: - av7110->video_size.aspect_ratio = VIDEO_FORMAT_221_1; - event.u.size.aspect_ratio = VIDEO_FORMAT_221_1; - av7110->videostate.video_format = VIDEO_FORMAT_221_1; - break; - default: - av7110->video_size.aspect_ratio = VIDEO_FORMAT_4_3; - event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; - av7110->videostate.video_format = VIDEO_FORMAT_4_3; - } - - dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", - av7110->video_size.w, av7110->video_size.h, - av7110->video_size.aspect_ratio); - - dvb_video_add_event(av7110, &event); - break; - } - - case DATA_CI_PUT: - { - int avail; - struct dvb_ringbuffer *cibuf = &av7110->ci_wbuffer; - - avail = dvb_ringbuffer_avail(cibuf); - if (avail <= 2) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8; - len |= DVB_RINGBUFFER_PEEK(cibuf, 1); - if (avail < len + 2) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - DVB_RINGBUFFER_SKIP(cibuf, 2); - - dvb_ringbuffer_read(cibuf, av7110->debi_virt, len); - - iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - dprintk(8, "DMA: CI\n"); - start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len); - spin_unlock(&av7110->debilock); - wake_up(&cibuf->queue); - return; - } - - case DATA_MPEG_PLAY: - if (!av7110->playing) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - len = 0; - if (av7110->debitype & 0x100) { - spin_lock(&av7110->aout.lock); - len = av7110_pes_play(av7110->debi_virt, &av7110->aout, 2048); - spin_unlock(&av7110->aout.lock); - } - if (len <= 0 && (av7110->debitype & 0x200) - &&av7110->videostate.play_state != VIDEO_FREEZED) { - spin_lock(&av7110->avout.lock); - len = av7110_pes_play(av7110->debi_virt, &av7110->avout, 2048); - spin_unlock(&av7110->avout.lock); - } - if (len <= 0) { - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - break; - } - dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len); - iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - dprintk(8, "DMA: MPEG_PLAY\n"); - start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE + txbuf, len); - spin_unlock(&av7110->debilock); - return; - - case DATA_BMP_LOAD: - len = av7110->debilen; - dprintk(8, "gpio DATA_BMP_LOAD len %d\n", len); - if (!len) { - av7110->bmp_state = BMP_LOADED; - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_LEN, 0, 2); - iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2); - wake_up(&av7110->bmpq); - dprintk(8, "gpio DATA_BMP_LOAD done\n"); - break; - } - if (len > av7110->bmplen) - len = av7110->bmplen; - if (len > 2 * 1024) - len = 2 * 1024; - iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2); - iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2); - memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len); - av7110->bmpp += len; - av7110->bmplen -= len; - dprintk(8, "gpio DATA_BMP_LOAD DMA len %d\n", len); - start_debi_dma(av7110, DEBI_WRITE, DPRAM_BASE+txbuf, len); - spin_unlock(&av7110->debilock); - return; - - case DATA_CI_GET: - case DATA_COMMON_INTERFACE: - case DATA_FSECTION: - case DATA_IPMPE: - case DATA_PIPING: - if (!len || len > 4 * 1024) { - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - break; - } - /* fall through */ - - case DATA_TS_RECORD: - case DATA_PES_RECORD: - dprintk(8, "DMA: TS_REC etc.\n"); - start_debi_dma(av7110, DEBI_READ, DPRAM_BASE+rxbuf, len); - spin_unlock(&av7110->debilock); - return; - - case DATA_DEBUG_MESSAGE: - if (!len || len > 0xff) { - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - break; - } - start_debi_dma(av7110, DEBI_READ, Reserved, len); - spin_unlock(&av7110->debilock); - return; - - case DATA_IRCOMMAND: - if (av7110->ir.ir_handler) - av7110->ir.ir_handler(av7110, - swahw32(irdebi(av7110, DEBINOSWAP, Reserved, 0, 4))); - iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); - break; - - default: - printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n", - av7110->debitype, av7110->debilen); - break; - } - av7110->debitype = -1; - ARM_ClearMailBox(av7110); - spin_unlock(&av7110->debilock); -} - - -#ifdef CONFIG_DVB_AV7110_OSD -static int dvb_osd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(4, "%p\n", av7110); - - if (cmd == OSD_SEND_CMD) - return av7110_osd_cmd(av7110, (osd_cmd_t *) parg); - if (cmd == OSD_GET_CAPABILITY) - return av7110_osd_capability(av7110, (osd_cap_t *) parg); - - return -EINVAL; -} - - -static struct file_operations dvb_osd_fops = { - .owner = THIS_MODULE, - .ioctl = dvb_generic_ioctl, - .open = dvb_generic_open, - .release = dvb_generic_release, -}; - -static struct dvb_device dvbdev_osd = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_osd_fops, - .kernel_ioctl = dvb_osd_ioctl, -}; -#endif /* CONFIG_DVB_AV7110_OSD */ - - -static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, - u16 subpid, u16 pcrpid) -{ - u16 aflags = 0; - - dprintk(4, "%p\n", av7110); - - if (vpid == 0x1fff || apid == 0x1fff || - ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) { - vpid = apid = ttpid = subpid = pcrpid = 0; - av7110->pids[DMX_PES_VIDEO] = 0; - av7110->pids[DMX_PES_AUDIO] = 0; - av7110->pids[DMX_PES_TELETEXT] = 0; - av7110->pids[DMX_PES_PCR] = 0; - } - - if (av7110->audiostate.bypass_mode) - aflags |= 0x8000; - - return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6, - pcrpid, vpid, apid, ttpid, subpid, aflags); -} - -int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, - u16 subpid, u16 pcrpid) -{ - int ret = 0; - dprintk(4, "%p\n", av7110); - - if (mutex_lock_interruptible(&av7110->pid_mutex)) - return -ERESTARTSYS; - - if (!(vpid & 0x8000)) - av7110->pids[DMX_PES_VIDEO] = vpid; - if (!(apid & 0x8000)) - av7110->pids[DMX_PES_AUDIO] = apid; - if (!(ttpid & 0x8000)) - av7110->pids[DMX_PES_TELETEXT] = ttpid; - if (!(pcrpid & 0x8000)) - av7110->pids[DMX_PES_PCR] = pcrpid; - - av7110->pids[DMX_PES_SUBTITLE] = 0; - - if (av7110->fe_synced) { - pcrpid = av7110->pids[DMX_PES_PCR]; - ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); - } - - mutex_unlock(&av7110->pid_mutex); - return ret; -} - - -/****************************************************************************** - * hardware filter functions - ******************************************************************************/ - -static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) -{ - struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed; - struct av7110 *av7110 = dvbdmxfeed->demux->priv; - u16 buf[20]; - int ret, i; - u16 handle; -// u16 mode = 0x0320; - u16 mode = 0xb96a; - - dprintk(4, "%p\n", av7110); - - if (av7110->full_ts) - return 0; - - if (dvbdmxfilter->type == DMX_TYPE_SEC) { - if (hw_sections) { - buf[4] = (dvbdmxfilter->filter.filter_value[0] << 8) | - dvbdmxfilter->maskandmode[0]; - for (i = 3; i < 18; i++) - buf[i + 4 - 2] = - (dvbdmxfilter->filter.filter_value[i] << 8) | - dvbdmxfilter->maskandmode[i]; - mode = 4; - } - } else if ((dvbdmxfeed->ts_type & TS_PACKET) && - !(dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)) { - av7110_p2t_init(&av7110->p2t_filter[dvbdmxfilter->index], dvbdmxfeed); - } - - buf[0] = (COMTYPE_PID_FILTER << 8) + AddPIDFilter; - buf[1] = 16; - buf[2] = dvbdmxfeed->pid; - buf[3] = mode; - - ret = av7110_fw_request(av7110, buf, 20, &handle, 1); - if (ret != 0 || handle >= 32) { - printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " - "ret %d handle %04x\n", - __func__, buf[0], buf[1], buf[2], buf[3], - ret, handle); - dvbdmxfilter->hw_handle = 0xffff; - if (!ret) - ret = -1; - return ret; - } - - av7110->handle2filter[handle] = dvbdmxfilter; - dvbdmxfilter->hw_handle = handle; - - return ret; -} - -static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) -{ - struct av7110 *av7110 = dvbdmxfilter->feed->demux->priv; - u16 buf[3]; - u16 answ[2]; - int ret; - u16 handle; - - dprintk(4, "%p\n", av7110); - - if (av7110->full_ts) - return 0; - - handle = dvbdmxfilter->hw_handle; - if (handle >= 32) { - printk("%s tried to stop invalid filter %04x, filter type = %x\n", - __func__, handle, dvbdmxfilter->type); - return -EINVAL; - } - - av7110->handle2filter[handle] = NULL; - - buf[0] = (COMTYPE_PID_FILTER << 8) + DelPIDFilter; - buf[1] = 1; - buf[2] = handle; - ret = av7110_fw_request(av7110, buf, 3, answ, 2); - if (ret != 0 || answ[1] != handle) { - printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x " - "resp %04x %04x pid %d\n", - __func__, buf[0], buf[1], buf[2], ret, - answ[0], answ[1], dvbdmxfilter->feed->pid); - if (!ret) - ret = -1; - } - return ret; -} - - -static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - struct av7110 *av7110 = dvbdmx->priv; - u16 *pid = dvbdmx->pids, npids[5]; - int i; - int ret = 0; - - dprintk(4, "%p\n", av7110); - - npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff; - i = dvbdmxfeed->pes_type; - npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; - if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { - npids[i] = 0; - ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); - if (!ret) - ret = StartHWFilter(dvbdmxfeed->filter); - return ret; - } - if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) { - ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); - if (ret) - return ret; - } - - if (dvbdmxfeed->pes_type < 2 && npids[0]) - if (av7110->fe_synced) - { - ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); - if (ret) - return ret; - } - - if ((dvbdmxfeed->ts_type & TS_PACKET) && !av7110->full_ts) { - if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) - ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); - if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) - ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed); - } - return ret; -} - -static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - struct av7110 *av7110 = dvbdmx->priv; - u16 *pid = dvbdmx->pids, npids[5]; - int i; - - int ret = 0; - - dprintk(4, "%p\n", av7110); - - if (dvbdmxfeed->pes_type <= 1) { - ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); - if (ret) - return ret; - if (!av7110->rec_mode) - dvbdmx->recording = 0; - if (!av7110->playing) - dvbdmx->playing = 0; - } - npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff; - i = dvbdmxfeed->pes_type; - switch (i) { - case 2: //teletext - if (dvbdmxfeed->ts_type & TS_PACKET) - ret = StopHWFilter(dvbdmxfeed->filter); - npids[2] = 0; - break; - case 0: - case 1: - case 4: - if (!pids_off) - return 0; - npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; - break; - } - if (!ret) - ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); - return ret; -} - -static int av7110_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = demux->priv; - int ret = 0; - - dprintk(4, "%p\n", av7110); - - if (!demux->dmx.frontend) - return -EINVAL; - - if (!av7110->full_ts && feed->pid > 0x1fff) - return -EINVAL; - - if (feed->type == DMX_TYPE_TS) { - if ((feed->ts_type & TS_DECODER) && - (feed->pes_type < DMX_TS_PES_OTHER)) { - switch (demux->dmx.frontend->source) { - case DMX_MEMORY_FE: - if (feed->ts_type & TS_DECODER) - if (feed->pes_type < 2 && - !(demux->pids[0] & 0x8000) && - !(demux->pids[1] & 0x8000)) { - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - ret = av7110_av_start_play(av7110,RP_AV); - if (!ret) - demux->playing = 1; - } - break; - default: - ret = dvb_feed_start_pid(feed); - break; - } - } else if ((feed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source != DMX_MEMORY_FE)) { - ret = StartHWFilter(feed->filter); - } - } - - if (av7110->full_ts) { - budget_start_feed(feed); - return ret; - } - - if (feed->type == DMX_TYPE_SEC) { - int i; - - for (i = 0; i < demux->filternum; i++) { - if (demux->filter[i].state != DMX_STATE_READY) - continue; - if (demux->filter[i].type != DMX_TYPE_SEC) - continue; - if (demux->filter[i].filter.parent != &feed->feed.sec) - continue; - demux->filter[i].state = DMX_STATE_GO; - if (demux->dmx.frontend->source != DMX_MEMORY_FE) { - ret = StartHWFilter(&demux->filter[i]); - if (ret) - break; - } - } - } - - return ret; -} - - -static int av7110_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = demux->priv; - int i, rc, ret = 0; - dprintk(4, "%p\n", av7110); - - if (feed->type == DMX_TYPE_TS) { - if (feed->ts_type & TS_DECODER) { - if (feed->pes_type >= DMX_TS_PES_OTHER || - !demux->pesfilter[feed->pes_type]) - return -EINVAL; - demux->pids[feed->pes_type] |= 0x8000; - demux->pesfilter[feed->pes_type] = NULL; - } - if (feed->ts_type & TS_DECODER && - feed->pes_type < DMX_TS_PES_OTHER) { - ret = dvb_feed_stop_pid(feed); - } else - if ((feed->ts_type & TS_PACKET) && - (demux->dmx.frontend->source != DMX_MEMORY_FE)) - ret = StopHWFilter(feed->filter); - } - - if (av7110->full_ts) { - budget_stop_feed(feed); - return ret; - } - - if (feed->type == DMX_TYPE_SEC) { - for (i = 0; i<demux->filternum; i++) { - if (demux->filter[i].state == DMX_STATE_GO && - demux->filter[i].filter.parent == &feed->feed.sec) { - demux->filter[i].state = DMX_STATE_READY; - if (demux->dmx.frontend->source != DMX_MEMORY_FE) { - rc = StopHWFilter(&demux->filter[i]); - if (!ret) - ret = rc; - /* keep going, stop as many filters as possible */ - } - } - } - } - - return ret; -} - - -static void restart_feeds(struct av7110 *av7110) -{ - struct dvb_demux *dvbdmx = &av7110->demux; - struct dvb_demux_feed *feed; - int mode; - int feeding; - int i, j; - - dprintk(4, "%p\n", av7110); - - mode = av7110->playing; - av7110->playing = 0; - av7110->rec_mode = 0; - - feeding = av7110->feeding1; /* full_ts mod */ - - for (i = 0; i < dvbdmx->feednum; i++) { - feed = &dvbdmx->feed[i]; - if (feed->state == DMX_STATE_GO) { - if (feed->type == DMX_TYPE_SEC) { - for (j = 0; j < dvbdmx->filternum; j++) { - if (dvbdmx->filter[j].type != DMX_TYPE_SEC) - continue; - if (dvbdmx->filter[j].filter.parent != &feed->feed.sec) - continue; - if (dvbdmx->filter[j].state == DMX_STATE_GO) - dvbdmx->filter[j].state = DMX_STATE_READY; - } - } - av7110_start_feed(feed); - } - } - - av7110->feeding1 = feeding; /* full_ts mod */ - - if (mode) - av7110_av_start_play(av7110, mode); -} - -static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, - uint64_t *stc, unsigned int *base) -{ - int ret; - u16 fwstc[4]; - u16 tag = ((COMTYPE_REQUEST << 8) + ReqSTC); - struct dvb_demux *dvbdemux; - struct av7110 *av7110; - - /* pointer casting paranoia... */ - BUG_ON(!demux); - dvbdemux = demux->priv; - BUG_ON(!dvbdemux); - av7110 = dvbdemux->priv; - - dprintk(4, "%p\n", av7110); - - if (num != 0) - return -EINVAL; - - ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); - if (ret) { - printk(KERN_ERR "%s: av7110_fw_request error\n", __func__); - return ret; - } - dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", - fwstc[0], fwstc[1], fwstc[2], fwstc[3]); - - *stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) | - (((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]); - *base = 1; - - dprintk(4, "stc = %lu\n", (unsigned long)*stc); - - return 0; -} - - -/****************************************************************************** - * SEC device file operations - ******************************************************************************/ - - -static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct av7110* av7110 = fe->dvb->priv; - - switch (tone) { - case SEC_TONE_ON: - return Set22K(av7110, 1); - - case SEC_TONE_OFF: - return Set22K(av7110, 0); - - default: - return -EINVAL; - } -} - -static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); -} - -static int av7110_diseqc_send_burst(struct dvb_frontend* fe, - fe_sec_mini_cmd_t minicmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - return av7110_diseqc_send(av7110, 0, NULL, minicmd); -} - -/* simplified code from budget-core.c */ -static int stop_ts_capture(struct av7110 *budget) -{ - dprintk(2, "budget: %p\n", budget); - - if (--budget->feeding1) - return budget->feeding1; - saa7146_write(budget->dev, MC1, MASK_20); /* DMA3 off */ - SAA7146_IER_DISABLE(budget->dev, MASK_10); - SAA7146_ISR_CLEAR(budget->dev, MASK_10); - return 0; -} - -static int start_ts_capture(struct av7110 *budget) -{ - dprintk(2, "budget: %p\n", budget); - - if (budget->feeding1) - return ++budget->feeding1; - memset(budget->grabbing, 0x00, TS_BUFLEN); - budget->ttbp = 0; - SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */ - SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ - saa7146_write(budget->dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ - return ++budget->feeding1; -} - -static int budget_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *budget = demux->priv; - int status; - - dprintk(2, "av7110: %p\n", budget); - - spin_lock(&budget->feedlock1); - feed->pusi_seen = 0; /* have a clean section start */ - status = start_ts_capture(budget); - spin_unlock(&budget->feedlock1); - return status; -} - -static int budget_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *budget = demux->priv; - int status; - - dprintk(2, "budget: %p\n", budget); - - spin_lock(&budget->feedlock1); - status = stop_ts_capture(budget); - spin_unlock(&budget->feedlock1); - return status; -} - -static void vpeirq(unsigned long cookie) -{ - struct av7110 *budget = (struct av7110 *)cookie; - u8 *mem = (u8 *) (budget->grabbing); - u32 olddma = budget->ttbp; - u32 newdma = saa7146_read(budget->dev, PCI_VDP3); - struct dvb_demux *demux = budget->full_ts ? &budget->demux : &budget->demux1; - - /* nearest lower position divisible by 188 */ - newdma -= newdma % 188; - - if (newdma >= TS_BUFLEN) - return; - - budget->ttbp = newdma; - - if (!budget->feeding1 || (newdma == olddma)) - return; - - /* Ensure streamed PCI data is synced to CPU */ - pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); - -#if 0 - /* track rps1 activity */ - printk("vpeirq: %02x Event Counter 1 0x%04x\n", - mem[olddma], - saa7146_read(budget->dev, EC1R) & 0x3fff); -#endif - - if (newdma > olddma) - /* no wraparound, dump olddma..newdma */ - dvb_dmx_swfilter_packets(demux, mem + olddma, (newdma - olddma) / 188); - else { - /* wraparound, dump olddma..buflen and 0..newdma */ - dvb_dmx_swfilter_packets(demux, mem + olddma, (TS_BUFLEN - olddma) / 188); - dvb_dmx_swfilter_packets(demux, mem, newdma / 188); - } -} - -static int av7110_register(struct av7110 *av7110) -{ - int ret, i; - struct dvb_demux *dvbdemux = &av7110->demux; - struct dvb_demux *dvbdemux1 = &av7110->demux1; - - dprintk(4, "%p\n", av7110); - - if (av7110->registered) - return -1; - - av7110->registered = 1; - - dvbdemux->priv = (void *) av7110; - - for (i = 0; i < 32; i++) - av7110->handle2filter[i] = NULL; - - dvbdemux->filternum = (av7110->full_ts) ? 256 : 32; - dvbdemux->feednum = (av7110->full_ts) ? 256 : 32; - dvbdemux->start_feed = av7110_start_feed; - dvbdemux->stop_feed = av7110_stop_feed; - dvbdemux->write_to_decoder = av7110_write_to_decoder; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - - dvb_dmx_init(&av7110->demux); - av7110->demux.dmx.get_stc = dvb_get_stc; - - av7110->dmxdev.filternum = (av7110->full_ts) ? 256 : 32; - av7110->dmxdev.demux = &dvbdemux->dmx; - av7110->dmxdev.capabilities = 0; - - dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter); - - av7110->hw_frontend.source = DMX_FRONTEND_0; - - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->hw_frontend); - - if (ret < 0) - return ret; - - av7110->mem_frontend.source = DMX_MEMORY_FE; - - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &av7110->mem_frontend); - - if (ret < 0) - return ret; - - ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, - &av7110->hw_frontend); - if (ret < 0) - return ret; - - av7110_av_register(av7110); - av7110_ca_register(av7110); - -#ifdef CONFIG_DVB_AV7110_OSD - dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev, - &dvbdev_osd, av7110, DVB_DEVICE_OSD); -#endif - - dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); - - if (budgetpatch) { - /* initialize software demux1 without its own frontend - * demux1 hardware is connected to frontend0 of demux0 - */ - dvbdemux1->priv = (void *) av7110; - - dvbdemux1->filternum = 256; - dvbdemux1->feednum = 256; - dvbdemux1->start_feed = budget_start_feed; - dvbdemux1->stop_feed = budget_stop_feed; - dvbdemux1->write_to_decoder = NULL; - - dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - - dvb_dmx_init(&av7110->demux1); - - av7110->dmxdev1.filternum = 256; - av7110->dmxdev1.demux = &dvbdemux1->dmx; - av7110->dmxdev1.capabilities = 0; - - dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter); - - dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx); - printk("dvb-ttpci: additional demux1 for budget-patch registered\n"); - } - return 0; -} - - -static void dvb_unregister(struct av7110 *av7110) -{ - struct dvb_demux *dvbdemux = &av7110->demux; - struct dvb_demux *dvbdemux1 = &av7110->demux1; - - dprintk(4, "%p\n", av7110); - - if (!av7110->registered) - return; - - if (budgetpatch) { - dvb_net_release(&av7110->dvb_net1); - dvbdemux->dmx.close(&dvbdemux1->dmx); - dvb_dmxdev_release(&av7110->dmxdev1); - dvb_dmx_release(&av7110->demux1); - } - - dvb_net_release(&av7110->dvb_net); - - dvbdemux->dmx.close(&dvbdemux->dmx); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->hw_frontend); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &av7110->mem_frontend); - - dvb_dmxdev_release(&av7110->dmxdev); - dvb_dmx_release(&av7110->demux); - - if (av7110->fe != NULL) { - dvb_unregister_frontend(av7110->fe); - dvb_frontend_detach(av7110->fe); - } - dvb_unregister_device(av7110->osd_dev); - av7110_av_unregister(av7110); - av7110_ca_unregister(av7110); -} - - -/**************************************************************************** - * I2C client commands - ****************************************************************************/ - -int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) -{ - u8 msg[2] = { reg, val }; - struct i2c_msg msgs; - - msgs.flags = 0; - msgs.addr = id / 2; - msgs.len = 2; - msgs.buf = msg; - return i2c_transfer(&av7110->i2c_adap, &msgs, 1); -} - -u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) -{ - u8 mm1[] = {0x00}; - u8 mm2[] = {0x00}; - struct i2c_msg msgs[2]; - - msgs[0].flags = 0; - msgs[1].flags = I2C_M_RD; - msgs[0].addr = msgs[1].addr = id / 2; - mm1[0] = reg; - msgs[0].len = 1; msgs[1].len = 1; - msgs[0].buf = mm1; msgs[1].buf = mm2; - i2c_transfer(&av7110->i2c_adap, msgs, 2); - - return mm2[0]; -} - -/**************************************************************************** - * INITIALIZATION - ****************************************************************************/ - - -static int check_firmware(struct av7110* av7110) -{ - u32 crc = 0, len = 0; - unsigned char *ptr; - - /* check for firmware magic */ - ptr = av7110->bin_fw; - if (ptr[0] != 'A' || ptr[1] != 'V' || - ptr[2] != 'F' || ptr[3] != 'W') { - printk("dvb-ttpci: this is not an av7110 firmware\n"); - return -EINVAL; - } - ptr += 4; - - /* check dpram file */ - crc = get_unaligned_be32(ptr); - ptr += 4; - len = get_unaligned_be32(ptr); - ptr += 4; - if (len >= 512) { - printk("dvb-ttpci: dpram file is way too big.\n"); - return -EINVAL; - } - if (crc != crc32_le(0, ptr, len)) { - printk("dvb-ttpci: crc32 of dpram file does not match.\n"); - return -EINVAL; - } - av7110->bin_dpram = ptr; - av7110->size_dpram = len; - ptr += len; - - /* check root file */ - crc = get_unaligned_be32(ptr); - ptr += 4; - len = get_unaligned_be32(ptr); - ptr += 4; - - if (len <= 200000 || len >= 300000 || - len > ((av7110->bin_fw + av7110->size_fw) - ptr)) { - printk("dvb-ttpci: root file has strange size (%d). aborting.\n", len); - return -EINVAL; - } - if( crc != crc32_le(0, ptr, len)) { - printk("dvb-ttpci: crc32 of root file does not match.\n"); - return -EINVAL; - } - av7110->bin_root = ptr; - av7110->size_root = len; - return 0; -} - -#ifdef CONFIG_DVB_AV7110_FIRMWARE_FILE -#include "av7110_firm.h" -static void put_firmware(struct av7110* av7110) -{ - av7110->bin_fw = NULL; -} - -static inline int get_firmware(struct av7110* av7110) -{ - av7110->bin_fw = dvb_ttpci_fw; - av7110->size_fw = sizeof(dvb_ttpci_fw); - return check_firmware(av7110); -} -#else -static void put_firmware(struct av7110* av7110) -{ - vfree(av7110->bin_fw); -} - -static int get_firmware(struct av7110* av7110) -{ - int ret; - const struct firmware *fw; - - /* request the av7110 firmware, this will block until someone uploads it */ - ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); - if (ret) { - if (ret == -ENOENT) { - printk(KERN_ERR "dvb-ttpci: could not load firmware," - " file not found: dvb-ttpci-01.fw\n"); - printk(KERN_ERR "dvb-ttpci: usually this should be in " - "/usr/lib/hotplug/firmware or /lib/firmware\n"); - printk(KERN_ERR "dvb-ttpci: and can be downloaded from" - " http://www.linuxtv.org/download/dvb/firmware/\n"); - } else - printk(KERN_ERR "dvb-ttpci: cannot request firmware" - " (error %i)\n", ret); - return -EINVAL; - } - - if (fw->size <= 200000) { - printk("dvb-ttpci: this firmware is way too small.\n"); - release_firmware(fw); - return -EINVAL; - } - - /* check if the firmware is available */ - av7110->bin_fw = vmalloc(fw->size); - if (NULL == av7110->bin_fw) { - dprintk(1, "out of memory\n"); - release_firmware(fw); - return -ENOMEM; - } - - memcpy(av7110->bin_fw, fw->data, fw->size); - av7110->size_fw = fw->size; - if ((ret = check_firmware(av7110))) - vfree(av7110->bin_fw); - - release_firmware(fw); - return ret; -} -#endif - - -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u8 pwr = 0; - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; - - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; - else pwr = 2; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = ((div & 0x18000) >> 10) | 0x95; - buf[3] = (pwr << 6) | 0x30; - - // NOTE: since we're using a prescaler of 2, we set the - // divisor frequency to 62.5kHz and divide by 125 above - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1x93_config alps_bsrv2_config = { - .demod_address = 0x08, - .xin = 90100000UL, - .invert_pwm = 0, -}; - -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (params->frequency + 35937500 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1820_config alps_tdbe2_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, -}; - - - - -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = params->frequency / 125; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = 0x00; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct tda8083_config grundig_29504_451_config = { - .demod_address = 0x68, -}; - - - -static int philips_cd1516_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u32 f = params->frequency; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (f + 36125000 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1820_config philips_cd1516_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, -}; - - - -static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div, pwr; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (params->frequency + 36200000) / 166666; - - if (params->frequency <= 782000000) - pwr = 1; - else - pwr = 2; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85; - data[3] = pwr << 6; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) -{ -#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE) - struct av7110* av7110 = fe->dvb->priv; - - return request_firmware(fw, name, &av7110->dev->pci->dev); -#else - return -EINVAL; -#endif -} - -static struct sp8870_config alps_tdlb7_config = { - - .demod_address = 0x71, - .request_firmware = alps_tdlb7_request_firmware, -}; - - -static u8 nexusca_stv0297_inittab[] = { - 0x80, 0x01, - 0x80, 0x00, - 0x81, 0x01, - 0x81, 0x00, - 0x00, 0x09, - 0x01, 0x69, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x20, 0x00, - 0x21, 0x40, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x40, - 0x25, 0x88, - 0x30, 0xff, - 0x31, 0x00, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x50, - 0x35, 0x7f, - 0x36, 0x00, - 0x37, 0x20, - 0x38, 0x00, - 0x40, 0x1c, - 0x41, 0xff, - 0x42, 0x29, - 0x43, 0x00, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0x00, - 0x4b, 0x7b, - 0x52, 0x30, - 0x55, 0xae, - 0x56, 0x47, - 0x57, 0xe1, - 0x58, 0x3a, - 0x5a, 0x1e, - 0x5b, 0x34, - 0x60, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x02, - 0x6b, 0x00, - 0x70, 0xff, - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x00, - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x80, - 0x86, 0x24, - 0x87, 0x78, - 0x88, 0x10, - 0x89, 0x00, - 0x90, 0x01, - 0x91, 0x01, - 0xa0, 0x04, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x53, - 0xc1, 0x70, - 0xc2, 0x12, - 0xd0, 0x00, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x00, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x00, - 0x61, 0x49, - 0x62, 0x0b, - 0x53, 0x08, - 0x59, 0x08, - 0xff, 0xff, -}; - -static int nexusca_stv0297_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) }; - struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 }; - int i; - - div = (params->frequency + 36150000 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0xce; - - if (params->frequency < 45000000) - return -EINVAL; - else if (params->frequency < 137000000) - data[3] = 0x01; - else if (params->frequency < 403000000) - data[3] = 0x02; - else if (params->frequency < 860000000) - data[3] = 0x04; - else - return -EINVAL; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&av7110->i2c_adap, &msg, 1) != 1) { - printk("nexusca: pll transfer failed!\n"); - return -EIO; - } - - // wait for PLL lock - for(i = 0; i < 20; i++) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&av7110->i2c_adap, &readmsg, 1) == 1) - if (data[0] & 0x40) break; - msleep(10); - } - - return 0; -} - -static struct stv0297_config nexusca_stv0297_config = { - - .demod_address = 0x1C, - .inittab = nexusca_stv0297_inittab, - .invert = 1, - .stop_during_read = 1, -}; - - - -static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) -{ - struct av7110* av7110 = fe->dvb->priv; - u32 div; - u8 cfg, cpump, band_select; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (36125000 + params->frequency) / 166666; - - cfg = 0x88; - - if (params->frequency < 175000000) cpump = 2; - else if (params->frequency < 390000000) cpump = 1; - else if (params->frequency < 470000000) cpump = 2; - else if (params->frequency < 750000000) cpump = 1; - else cpump = 3; - - if (params->frequency < 175000000) band_select = 0x0e; - else if (params->frequency < 470000000) band_select = 0x05; - else band_select = 0x03; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = ((div >> 10) & 0x60) | cfg; - data[3] = (cpump << 6) | band_select; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct l64781_config grundig_29504_401_config = { - .demod_address = 0x55, -}; - - - -static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) -{ - int ret = 0; - int synced = (status & FE_HAS_LOCK) ? 1 : 0; - - av7110->fe_status = status; - - if (av7110->fe_synced == synced) - return 0; - - if (av7110->playing) { - av7110->fe_synced = synced; - return 0; - } - - if (mutex_lock_interruptible(&av7110->pid_mutex)) - return -ERESTARTSYS; - - if (synced) { - ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], - av7110->pids[DMX_PES_AUDIO], - av7110->pids[DMX_PES_TELETEXT], 0, - av7110->pids[DMX_PES_PCR]); - if (!ret) - ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); - } else { - ret = SetPIDs(av7110, 0, 0, 0, 0, 0); - if (!ret) { - ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); - if (!ret) - ret = av7110_wait_msgstate(av7110, GPMQBusy); - } - } - - if (!ret) - av7110->fe_synced = synced; - - mutex_unlock(&av7110->pid_mutex); - return ret; -} - -static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_fe_params = *params; - ret = av7110->fe_set_frontend(fe, params); - } - return ret; -} - -static int av7110_fe_init(struct dvb_frontend* fe) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) - ret = av7110->fe_init(fe); - return ret; -} - -static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct av7110* av7110 = fe->dvb->priv; - - /* call the real implementation */ - int ret = av7110->fe_read_status(fe, status); - if (!ret) - if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) - ret = av7110_fe_lock_fix(av7110, *status); - return ret; -} - -static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) - ret = av7110->fe_diseqc_reset_overload(fe); - return ret; -} - -static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd* cmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_master_cmd = *cmd; - ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); - } - return ret; -} - -static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_minicmd = minicmd; - ret = av7110->fe_diseqc_send_burst(fe, minicmd); - } - return ret; -} - -static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_tone = tone; - ret = av7110->fe_set_tone(fe, tone); - } - return ret; -} - -static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_voltage = voltage; - ret = av7110->fe_set_voltage(fe, voltage); - } - return ret; -} - -static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd) -{ - struct av7110* av7110 = fe->dvb->priv; - - int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) - ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd); - return ret; -} - -static void dvb_s_recover(struct av7110* av7110) -{ - av7110_fe_init(av7110->fe); - - av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage); - if (av7110->saved_master_cmd.msg_len) { - msleep(20); - av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd); - } - msleep(20); - av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd); - msleep(20); - av7110_fe_set_tone(av7110->fe, av7110->saved_tone); - - av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params); -} - -static u8 read_pwm(struct av7110* av7110) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, - { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; - - if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - -static int frontend_init(struct av7110 *av7110) -{ - int ret; - - if (av7110->dev->pci->subsystem_vendor == 0x110a) { - switch(av7110->dev->pci->subsystem_device) { - case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) - av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, - &av7110->i2c_adap, read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; - } - break; - } - - } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) { - switch(av7110->dev->pci->subsystem_device) { - case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X - case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X - case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE - - // try the ALPS BSRV2 first of all - av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; - break; - } - - // try the ALPS BSRU6 now - av7110->fe = dvb_attach(stv0299_attach, &alps_bsru6_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - av7110->fe->tuner_priv = &av7110->i2c_adap; - - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; - break; - } - - // Try the grundig 29504-451 - av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; - break; - } - - /* Try DVB-C cards */ - switch(av7110->dev->pci->subsystem_device) { - case 0x0000: - /* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */ - av7110->fe = dvb_attach(ves1820_attach, &philips_cd1516_config, &av7110->i2c_adap, - read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = philips_cd1516_tuner_set_params; - } - break; - case 0x0003: - /* Hauppauge DVB-C 2.1 VES1820/ALPS TDBE2 */ - av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, - read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - } - break; - } - break; - - case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X - // try ALPS TDLB7 first, then Grundig 29504-401 - av7110->fe = dvb_attach(sp8870_attach, &alps_tdlb7_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_tdlb7_tuner_set_params; - break; - } - /* fall-thru */ - - case 0x0008: // Hauppauge/TT DVB-T - // Grundig 29504-401 - av7110->fe = dvb_attach(l64781_attach, &grundig_29504_401_config, &av7110->i2c_adap); - if (av7110->fe) - av7110->fe->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - break; - - case 0x0002: // Hauppauge/TT DVB-C premium rev2.X - - av7110->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - } - break; - - case 0x0004: // Galaxis DVB-S rev1.3 - /* ALPS BSRV2 */ - av7110->fe = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; - } - break; - - case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ - /* Grundig 29504-451 */ - av7110->fe = dvb_attach(tda8083_attach, &grundig_29504_451_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - av7110->fe->ops.diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; - av7110->fe->ops.diseqc_send_burst = av7110_diseqc_send_burst; - av7110->fe->ops.set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; - } - break; - - case 0x000A: // Hauppauge/TT Nexus-CA rev1.X - - av7110->fe = dvb_attach(stv0297_attach, &nexusca_stv0297_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = nexusca_stv0297_tuner_set_params; - - /* set TDA9819 into DVB mode */ - saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) - saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) - - /* tuner on this needs a slower i2c bus speed */ - av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - break; - } - break; - - case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ - /* ALPS BSBE1 */ - av7110->fe = dvb_attach(stv0299_attach, &alps_bsbe1_config, &av7110->i2c_adap); - if (av7110->fe) { - av7110->fe->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - av7110->fe->tuner_priv = &av7110->i2c_adap; - - if (dvb_attach(lnbp21_attach, av7110->fe, &av7110->i2c_adap, 0, 0) == NULL) { - printk("dvb-ttpci: LNBP21 not found!\n"); - if (av7110->fe->ops.release) - av7110->fe->ops.release(av7110->fe); - av7110->fe = NULL; - } else { - av7110->fe->ops.dishnetwork_send_legacy_command = NULL; - av7110->recover = dvb_s_recover; - } - } - break; - } - } - - if (!av7110->fe) { - /* FIXME: propagate the failure code from the lower layers */ - ret = -ENOMEM; - printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - av7110->dev->pci->vendor, - av7110->dev->pci->device, - av7110->dev->pci->subsystem_vendor, - av7110->dev->pci->subsystem_device); - } else { - FE_FUNC_OVERRIDE(av7110->fe->ops.init, av7110->fe_init, av7110_fe_init); - FE_FUNC_OVERRIDE(av7110->fe->ops.read_status, av7110->fe_read_status, av7110_fe_read_status); - FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload); - FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd); - FE_FUNC_OVERRIDE(av7110->fe->ops.diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_tone, av7110->fe_set_tone, av7110_fe_set_tone); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage); - FE_FUNC_OVERRIDE(av7110->fe->ops.dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); - FE_FUNC_OVERRIDE(av7110->fe->ops.set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); - - ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); - if (ret < 0) { - printk("av7110: Frontend registration failed!\n"); - dvb_frontend_detach(av7110->fe); - av7110->fe = NULL; - } - } - return ret; -} - -/* Budgetpatch note: - * Original hardware design by Roberto Deza: - * There is a DVB_Wiki at - * http://212.227.36.83/linuxtv/wiki/index.php/Main_Page - * where is described this 'DVB TT Budget Patch', on Card Modding: - * http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch - * On the short description there is also a link to a external file, - * with more details: - * http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip - * - * New software triggering design by Emard that works on - * original Roberto Deza's hardware: - * - * rps1 code for budgetpatch will copy internal HS event to GPIO3 pin. - * GPIO3 is in budget-patch hardware connectd to port B VSYNC - * HS is an internal event of 7146, accessible with RPS - * and temporarily raised high every n lines - * (n in defined in the RPS_THRESH1 counter threshold) - * I think HS is raised high on the beginning of the n-th line - * and remains high until this n-th line that triggered - * it is completely received. When the receiption of n-th line - * ends, HS is lowered. - * - * To transmit data over DMA, 7146 needs changing state at - * port B VSYNC pin. Any changing of port B VSYNC will - * cause some DMA data transfer, with more or less packets loss. - * It depends on the phase and frequency of VSYNC and - * the way of 7146 is instructed to trigger on port B (defined - * in DD1_INIT register, 3rd nibble from the right valid - * numbers are 0-7, see datasheet) - * - * The correct triggering can minimize packet loss, - * dvbtraffic should give this stable bandwidths: - * 22k transponder = 33814 kbit/s - * 27.5k transponder = 38045 kbit/s - * by experiment it is found that the best results - * (stable bandwidths and almost no packet loss) - * are obtained using DD1_INIT triggering number 2 - * (Va at rising edge of VS Fa = HS x VS-failing forced toggle) - * and a VSYNC phase that occurs in the middle of DMA transfer - * (about byte 188*512=96256 in the DMA window). - * - * Phase of HS is still not clear to me how to control, - * It just happens to be so. It can be seen if one enables - * RPS_IRQ and print Event Counter 1 in vpeirq(). Every - * time RPS_INTERRUPT is called, the Event Counter 1 will - * increment. That's how the 7146 is programmed to do event - * counting in this budget-patch.c - * I *think* HPS setting has something to do with the phase - * of HS but I cant be 100% sure in that. - * - * hardware debug note: a working budget card (including budget patch) - * with vpeirq() interrupt setup in mode "0x90" (every 64K) will - * generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes - * and that means 3*25=75 Hz of interrupt freqency, as seen by - * watch cat /proc/interrupts - * - * If this frequency is 3x lower (and data received in the DMA - * buffer don't start with 0x47, but in the middle of packets, - * whose lengths appear to be like 188 292 188 104 etc. - * this means VSYNC line is not connected in the hardware. - * (check soldering pcb and pins) - * The same behaviour of missing VSYNC can be duplicated on budget - * cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. - */ -static int __devinit av7110_attach(struct saa7146_dev* dev, - struct saa7146_pci_extension_data *pci_ext) -{ - const int length = TS_WIDTH * TS_HEIGHT; - struct pci_dev *pdev = dev->pci; - struct av7110 *av7110; - struct task_struct *thread; - int ret, count = 0; - - dprintk(4, "dev: %p\n", dev); - - /* Set RPS_IRQ to 1 to track rps1 activity. - * Enabling this won't send any interrupt to PC CPU. - */ -#define RPS_IRQ 0 - - if (budgetpatch == 1) { - budgetpatch = 0; - /* autodetect the presence of budget patch - * this only works if saa7146 has been recently - * reset with with MASK_31 to MC1 - * - * will wait for VBI_B event (vertical blank at port B) - * and will reset GPIO3 after VBI_B is detected. - * (GPIO3 should be raised high by CPU to - * test if GPIO3 will generate vertical blank signal - * in budget patch GPIO3 is connected to VSYNC_B - */ - - /* RESET SAA7146 */ - saa7146_write(dev, MC1, MASK_31); - /* autodetection success seems to be time-dependend after reset */ - - /* Fix VSYNC level */ - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - /* set vsync_b triggering */ - saa7146_write(dev, DD1_STREAM_B, 0); - /* port B VSYNC at rising edge */ - saa7146_write(dev, DD1_INIT, 0x00000200); - saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI - saa7146_write(dev, MC2, - 1 * (MASK_08 | MASK_24) | // BRS control - 0 * (MASK_09 | MASK_25) | // a - 1 * (MASK_10 | MASK_26) | // b - 0 * (MASK_06 | MASK_22) | // HPS_CTRL1 - 0 * (MASK_05 | MASK_21) | // HPS_CTRL2 - 0 * (MASK_01 | MASK_15) // DEBI - ); - - /* start writing RPS1 code from beginning */ - count = 0; - /* Disable RPS1 */ - saa7146_write(dev, MC1, MASK_29); - /* RPS1 timeout disable */ - saa7146_write(dev, RPS_TOV1, 0); - WRITE_RPS1(CMD_PAUSE | EVT_VBI_B); - WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - WRITE_RPS1(GPIO3_MSK); - WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); -#if RPS_IRQ - /* issue RPS1 interrupt to increment counter */ - WRITE_RPS1(CMD_INTERRUPT); -#endif - WRITE_RPS1(CMD_STOP); - /* Jump to begin of RPS program as safety measure (p37) */ - WRITE_RPS1(CMD_JUMP); - WRITE_RPS1(dev->d_rps1.dma_handle); - -#if RPS_IRQ - /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) - * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled - * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called - */ - saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); - /* set event counter 1 treshold to maximum allowed value (rEC p55) */ - saa7146_write(dev, ECT1R, 0x3fff ); -#endif - /* Set RPS1 Address register to point to RPS code (r108 p42) */ - saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - /* Enable RPS1, (rFC p33) */ - saa7146_write(dev, MC1, (MASK_13 | MASK_29 )); - - mdelay(10); - /* now send VSYNC_B to rps1 by rising GPIO3 */ - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - mdelay(10); - /* if rps1 responded by lowering the GPIO3, - * then we have budgetpatch hardware - */ - if ((saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) { - budgetpatch = 1; - printk("dvb-ttpci: BUDGET-PATCH DETECTED.\n"); - } - /* Disable RPS1 */ - saa7146_write(dev, MC1, ( MASK_29 )); -#if RPS_IRQ - printk("dvb-ttpci: Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff ); -#endif - } - - /* prepare the av7110 device struct */ - av7110 = kzalloc(sizeof(struct av7110), GFP_KERNEL); - if (!av7110) { - dprintk(1, "out of memory\n"); - return -ENOMEM; - } - - av7110->card_name = (char*) pci_ext->ext_priv; - av7110->dev = dev; - dev->ext_priv = av7110; - - ret = get_firmware(av7110); - if (ret < 0) - goto err_kfree_0; - - ret = dvb_register_adapter(&av7110->dvb_adapter, av7110->card_name, - THIS_MODULE, &dev->pci->dev, adapter_nr); - if (ret < 0) - goto err_put_firmware_1; - - /* the Siemens DVB needs this if you want to have the i2c chips - get recognized before the main driver is fully loaded */ - saa7146_write(dev, GPIO_CTRL, 0x500000); - - av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name)); - - saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ - - ret = i2c_add_adapter(&av7110->i2c_adap); - if (ret < 0) - goto err_dvb_unregister_adapter_2; - - ttpci_eeprom_parse_mac(&av7110->i2c_adap, - av7110->dvb_adapter.proposed_mac); - ret = -ENOMEM; - - /* full-ts mod? */ - if (full_ts) - av7110->full_ts = true; - - /* check for full-ts flag in eeprom */ - if (i2c_readreg(av7110, 0xaa, 0) == 0x4f && i2c_readreg(av7110, 0xaa, 1) == 0x45) { - u8 flags = i2c_readreg(av7110, 0xaa, 2); - if (flags != 0xff && (flags & 0x01)) - av7110->full_ts = true; - } - - if (av7110->full_ts) { - printk(KERN_INFO "dvb-ttpci: full-ts mode enabled for saa7146 port B\n"); - spin_lock_init(&av7110->feedlock1); - av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, - &av7110->pt); - if (!av7110->grabbing) - goto err_i2c_del_3; - - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, MC2, (MASK_10 | MASK_26)); - - saa7146_write(dev, DD1_INIT, 0x00000600); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - saa7146_write(dev, BRS_CTRL, 0x60000000); - saa7146_write(dev, MC2, MASK_08 | MASK_24); - - /* dma3 */ - saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); - saa7146_write(dev, BASE_ODD3, 0); - saa7146_write(dev, BASE_EVEN3, 0); - saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); - saa7146_write(dev, PITCH3, TS_WIDTH); - saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90); - saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); - saa7146_write(dev, MC2, MASK_04 | MASK_20); - - tasklet_init(&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); - - } else if (budgetpatch) { - spin_lock_init(&av7110->feedlock1); - av7110->grabbing = saa7146_vmalloc_build_pgtable(pdev, length, - &av7110->pt); - if (!av7110->grabbing) - goto err_i2c_del_3; - - saa7146_write(dev, PCI_BT_V1, 0x1c1f101f); - saa7146_write(dev, BCS_CTRL, 0x80400040); - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x03000200); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - saa7146_write(dev, BASE_ODD3, 0); - saa7146_write(dev, BASE_EVEN3, 0); - saa7146_write(dev, PROT_ADDR3, TS_WIDTH * TS_HEIGHT); - saa7146_write(dev, BASE_PAGE3, av7110->pt.dma | ME1 | 0x90); - - saa7146_write(dev, PITCH3, TS_WIDTH); - saa7146_write(dev, NUM_LINE_BYTE3, (TS_HEIGHT << 16) | TS_WIDTH); - - /* upload all */ - saa7146_write(dev, MC2, 0x077c077c); - saa7146_write(dev, GPIO_CTRL, 0x000000); -#if RPS_IRQ - /* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) - * use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled - * use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called - */ - saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); - /* set event counter 1 treshold to maximum allowed value (rEC p55) */ - saa7146_write(dev, ECT1R, 0x3fff ); -#endif - /* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */ - count = 0; - - /* Wait Source Line Counter Threshold (p36) */ - WRITE_RPS1(CMD_PAUSE | EVT_HS); - /* Set GPIO3=1 (p42) */ - WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - WRITE_RPS1(GPIO3_MSK); - WRITE_RPS1(SAA7146_GPIO_OUTHI<<24); -#if RPS_IRQ - /* issue RPS1 interrupt */ - WRITE_RPS1(CMD_INTERRUPT); -#endif - /* Wait reset Source Line Counter Threshold (p36) */ - WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS); - /* Set GPIO3=0 (p42) */ - WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - WRITE_RPS1(GPIO3_MSK); - WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); -#if RPS_IRQ - /* issue RPS1 interrupt */ - WRITE_RPS1(CMD_INTERRUPT); -#endif - /* Jump to begin of RPS program (p37) */ - WRITE_RPS1(CMD_JUMP); - WRITE_RPS1(dev->d_rps1.dma_handle); - - /* Fix VSYNC level */ - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - /* Set RPS1 Address register to point to RPS code (r108 p42) */ - saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - /* Set Source Line Counter Threshold, using BRS (rCC p43) - * It generates HS event every TS_HEIGHT lines - * this is related to TS_WIDTH set in register - * NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits - * are set to TS_WIDTH bytes (TS_WIDTH=2*188), - * then RPS_THRESH1 should be set to trigger - * every TS_HEIGHT (512) lines. - */ - saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 ); - - /* Enable RPS1 (rFC p33) */ - saa7146_write(dev, MC1, (MASK_13 | MASK_29)); - - /* end of budgetpatch register initialization */ - tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long) av7110); - } else { - saa7146_write(dev, PCI_BT_V1, 0x1c00101f); - saa7146_write(dev, BCS_CTRL, 0x80400040); - - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, DD1_INIT, 0x03000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - /* upload all */ - saa7146_write(dev, MC2, 0x077c077c); - saa7146_write(dev, GPIO_CTRL, 0x000000); - } - - tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long) av7110); - tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long) av7110); - - mutex_init(&av7110->pid_mutex); - - /* locks for data transfers from/to AV7110 */ - spin_lock_init(&av7110->debilock); - mutex_init(&av7110->dcomlock); - av7110->debitype = -1; - - /* default OSD window */ - av7110->osdwin = 1; - mutex_init(&av7110->osd_mutex); - - /* TV standard */ - av7110->vidmode = tv_standard == 1 ? AV7110_VIDEO_MODE_NTSC - : AV7110_VIDEO_MODE_PAL; - - /* ARM "watchdog" */ - init_waitqueue_head(&av7110->arm_wait); - av7110->arm_thread = NULL; - - /* allocate and init buffers */ - av7110->debi_virt = pci_alloc_consistent(pdev, 8192, &av7110->debi_bus); - if (!av7110->debi_virt) - goto err_saa71466_vfree_4; - - - av7110->iobuf = vmalloc(AVOUTLEN+AOUTLEN+BMPLEN+4*IPACKS); - if (!av7110->iobuf) - goto err_pci_free_5; - - ret = av7110_av_init(av7110); - if (ret < 0) - goto err_iobuf_vfree_6; - - /* init BMP buffer */ - av7110->bmpbuf = av7110->iobuf+AVOUTLEN+AOUTLEN; - init_waitqueue_head(&av7110->bmpq); - - ret = av7110_ca_init(av7110); - if (ret < 0) - goto err_av7110_av_exit_7; - - /* load firmware into AV7110 cards */ - ret = av7110_bootarm(av7110); - if (ret < 0) - goto err_av7110_ca_exit_8; - - ret = av7110_firmversion(av7110); - if (ret < 0) - goto err_stop_arm_9; - - if (FW_VERSION(av7110->arm_app)<0x2501) - printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " - "System might be unstable!\n", FW_VERSION(av7110->arm_app)); - - thread = kthread_run(arm_thread, (void *) av7110, "arm_mon"); - if (IS_ERR(thread)) { - ret = PTR_ERR(thread); - goto err_stop_arm_9; - } - av7110->arm_thread = thread; - - /* set initial volume in mixer struct */ - av7110->mixer.volume_left = volume; - av7110->mixer.volume_right = volume; - - ret = av7110_register(av7110); - if (ret < 0) - goto err_arm_thread_stop_10; - - init_av7110_av(av7110); - - /* special case DVB-C: these cards have an analog tuner - plus need some special handling, so we have separate - saa7146_ext_vv data for these... */ - ret = av7110_init_v4l(av7110); - if (ret < 0) - goto err_av7110_unregister_11; - - av7110->dvb_adapter.priv = av7110; - ret = frontend_init(av7110); - if (ret < 0) - goto err_av7110_exit_v4l_12; - -#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) - av7110_ir_init(av7110); -#endif - printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num); - av7110_num++; -out: - return ret; - -err_av7110_exit_v4l_12: - av7110_exit_v4l(av7110); -err_av7110_unregister_11: - dvb_unregister(av7110); -err_arm_thread_stop_10: - av7110_arm_sync(av7110); -err_stop_arm_9: - /* Nothing to do. Rejoice. */ -err_av7110_ca_exit_8: - av7110_ca_exit(av7110); -err_av7110_av_exit_7: - av7110_av_exit(av7110); -err_iobuf_vfree_6: - vfree(av7110->iobuf); -err_pci_free_5: - pci_free_consistent(pdev, 8192, av7110->debi_virt, av7110->debi_bus); -err_saa71466_vfree_4: - if (av7110->grabbing) - saa7146_vfree_destroy_pgtable(pdev, av7110->grabbing, &av7110->pt); -err_i2c_del_3: - i2c_del_adapter(&av7110->i2c_adap); -err_dvb_unregister_adapter_2: - dvb_unregister_adapter(&av7110->dvb_adapter); -err_put_firmware_1: - put_firmware(av7110); -err_kfree_0: - kfree(av7110); - goto out; -} - -static int __devexit av7110_detach(struct saa7146_dev* saa) -{ - struct av7110 *av7110 = saa->ext_priv; - dprintk(4, "%p\n", av7110); - -#if defined(CONFIG_INPUT_EVDEV) || defined(CONFIG_INPUT_EVDEV_MODULE) - av7110_ir_exit(av7110); -#endif - if (budgetpatch || av7110->full_ts) { - if (budgetpatch) { - /* Disable RPS1 */ - saa7146_write(saa, MC1, MASK_29); - /* VSYNC LOW (inactive) */ - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - } - saa7146_write(saa, MC1, MASK_20); /* DMA3 off */ - SAA7146_IER_DISABLE(saa, MASK_10); - SAA7146_ISR_CLEAR(saa, MASK_10); - msleep(50); - tasklet_kill(&av7110->vpe_tasklet); - saa7146_vfree_destroy_pgtable(saa->pci, av7110->grabbing, &av7110->pt); - } - av7110_exit_v4l(av7110); - - av7110_arm_sync(av7110); - - tasklet_kill(&av7110->debi_tasklet); - tasklet_kill(&av7110->gpio_tasklet); - - dvb_unregister(av7110); - - SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03); - SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03); - - av7110_ca_exit(av7110); - av7110_av_exit(av7110); - - vfree(av7110->iobuf); - pci_free_consistent(saa->pci, 8192, av7110->debi_virt, - av7110->debi_bus); - - i2c_del_adapter(&av7110->i2c_adap); - - dvb_unregister_adapter (&av7110->dvb_adapter); - - av7110_num--; - - put_firmware(av7110); - - kfree(av7110); - - saa->ext_priv = NULL; - - return 0; -} - - -static void av7110_irq(struct saa7146_dev* dev, u32 *isr) -{ - struct av7110 *av7110 = dev->ext_priv; - - //print_time("av7110_irq"); - - /* Note: Don't try to handle the DEBI error irq (MASK_18), in - * intel mode the timeout is asserted all the time... - */ - - if (*isr & MASK_19) { - //printk("av7110_irq: DEBI\n"); - /* Note 1: The DEBI irq is level triggered: We must enable it - * only after we started a DMA xfer, and disable it here - * immediately, or it will be signalled all the time while - * DEBI is idle. - * Note 2: You would think that an irq which is masked is - * not signalled by the hardware. Not so for the SAA7146: - * An irq is signalled as long as the corresponding bit - * in the ISR is set, and disabling irqs just prevents the - * hardware from setting the ISR bit. This means a) that we - * must clear the ISR *after* disabling the irq (which is why - * we must do it here even though saa7146_core did it already), - * and b) that if we were to disable an edge triggered irq - * (like the gpio irqs sadly are) temporarily we would likely - * loose some. This sucks :-( - */ - SAA7146_IER_DISABLE(av7110->dev, MASK_19); - SAA7146_ISR_CLEAR(av7110->dev, MASK_19); - tasklet_schedule(&av7110->debi_tasklet); - } - - if (*isr & MASK_03) { - //printk("av7110_irq: GPIO\n"); - tasklet_schedule(&av7110->gpio_tasklet); - } - - if (*isr & MASK_10) - tasklet_schedule(&av7110->vpe_tasklet); -} - - -static struct saa7146_extension av7110_extension_driver; - -#define MAKE_AV7110_INFO(x_var,x_name) \ -static struct saa7146_pci_extension_data x_var = { \ - .ext_priv = x_name, \ - .ext = &av7110_extension_driver } - -MAKE_AV7110_INFO(tts_1_X_fsc,"Technotrend/Hauppauge WinTV DVB-S rev1.X or Fujitsu Siemens DVB-C"); -MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X"); -MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X"); -MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X"); -MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X"); -MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3"); -MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE"); -MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); -MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); -MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); -MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3"); - -static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), - MAKE_EXTENSION_PCI(tts_1_X_fsc, 0x13c2, 0x0000), - MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), - MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), - MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), - MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004), - MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), - MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), - MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), - MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), - MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), - -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? - - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - - -static struct saa7146_extension av7110_extension_driver = { - .name = "dvb", - .flags = SAA7146_USE_I2C_IRQ, - - .module = THIS_MODULE, - .pci_tbl = &pci_tbl[0], - .attach = av7110_attach, - .detach = __devexit_p(av7110_detach), - - .irq_mask = MASK_19 | MASK_03 | MASK_10, - .irq_func = av7110_irq, -}; - - -static int __init av7110_init(void) -{ - int retval; - retval = saa7146_register_extension(&av7110_extension_driver); - return retval; -} - - -static void __exit av7110_exit(void) -{ - saa7146_unregister_extension(&av7110_extension_driver); -} - -module_init(av7110_init); -module_exit(av7110_exit); - -MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " - "Siemens, Technotrend, Hauppauge"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h deleted file mode 100644 index d85b8512ac3..00000000000 --- a/drivers/media/dvb/ttpci/av7110.h +++ /dev/null @@ -1,315 +0,0 @@ -#ifndef _AV7110_H_ -#define _AV7110_H_ - -#include <linux/interrupt.h> -#include <linux/socket.h> -#include <linux/netdevice.h> -#include <linux/i2c.h> -#include <linux/input.h> - -#include <linux/dvb/video.h> -#include <linux/dvb/audio.h> -#include <linux/dvb/dmx.h> -#include <linux/dvb/ca.h> -#include <linux/dvb/osd.h> -#include <linux/dvb/net.h> -#include <linux/mutex.h> - -#include "dvbdev.h" -#include "demux.h" -#include "dvb_demux.h" -#include "dmxdev.h" -#include "dvb_filter.h" -#include "dvb_net.h" -#include "dvb_ringbuffer.h" -#include "dvb_frontend.h" -#include "ves1820.h" -#include "ves1x93.h" -#include "stv0299.h" -#include "tda8083.h" -#include "sp8870.h" -#include "stv0297.h" -#include "l64781.h" - -#include <media/saa7146_vv.h> - - -#define ANALOG_TUNER_VES1820 1 -#define ANALOG_TUNER_STV0297 2 - -extern int av7110_debug; - -#define dprintk(level,args...) \ - do { if ((av7110_debug & level)) { printk("dvb-ttpci: %s(): ", __func__); printk(args); } } while (0) - -#define MAXFILT 32 - -enum {AV_PES_STREAM, PS_STREAM, TS_STREAM, PES_STREAM}; - -enum av7110_video_mode { - AV7110_VIDEO_MODE_PAL = 0, - AV7110_VIDEO_MODE_NTSC = 1 -}; - -struct av7110_p2t { - u8 pes[TS_SIZE]; - u8 counter; - long int pos; - int frags; - struct dvb_demux_feed *feed; -}; - -/* video MPEG decoder events: */ -/* (code copied from dvb_frontend.c, should maybe be factored out...) */ -#define MAX_VIDEO_EVENT 8 -struct dvb_video_events { - struct video_event events[MAX_VIDEO_EVENT]; - int eventw; - int eventr; - int overflow; - wait_queue_head_t wait_queue; - spinlock_t lock; -}; - - -struct av7110; - -/* infrared remote control */ -struct infrared { - u16 key_map[256]; - struct input_dev *input_dev; - char input_phys[32]; - struct timer_list keyup_timer; - struct tasklet_struct ir_tasklet; - void (*ir_handler)(struct av7110 *av7110, u32 ircom); - u32 ir_command; - u32 ir_config; - u32 device_mask; - u8 protocol; - u8 inversion; - u16 last_key; - u16 last_toggle; - u8 delay_timer_finished; -}; - - -/* place to store all the necessary device information */ -struct av7110 { - - /* devices */ - - struct dvb_device dvb_dev; - struct dvb_net dvb_net; - - struct video_device *v4l_dev; - struct video_device *vbi_dev; - - struct saa7146_dev *dev; - - struct i2c_adapter i2c_adap; - - char *card_name; - - /* support for analog module of dvb-c */ - int analog_tuner_flags; - int current_input; - u32 current_freq; - - struct tasklet_struct debi_tasklet; - struct tasklet_struct gpio_tasklet; - - int adac_type; /* audio DAC type */ -#define DVB_ADAC_TI 0 -#define DVB_ADAC_CRYSTAL 1 -#define DVB_ADAC_MSP34x0 2 -#define DVB_ADAC_MSP34x5 3 -#define DVB_ADAC_NONE -1 - - - /* buffers */ - - void *iobuf; /* memory for all buffers */ - struct dvb_ringbuffer avout; /* buffer for video or A/V mux */ -#define AVOUTLEN (128*1024) - struct dvb_ringbuffer aout; /* buffer for audio */ -#define AOUTLEN (64*1024) - void *bmpbuf; -#define BMPLEN (8*32768+1024) - - /* bitmap buffers and states */ - - int bmpp; - int bmplen; - volatile int bmp_state; -#define BMP_NONE 0 -#define BMP_LOADING 1 -#define BMP_LOADED 2 - wait_queue_head_t bmpq; - - - /* DEBI and polled command interface */ - - spinlock_t debilock; - struct mutex dcomlock; - volatile int debitype; - volatile int debilen; - - - /* Recording and playback flags */ - - int rec_mode; - int playing; -#define RP_NONE 0 -#define RP_VIDEO 1 -#define RP_AUDIO 2 -#define RP_AV 3 - - - /* OSD */ - - int osdwin; /* currently active window */ - u16 osdbpp[8]; - struct mutex osd_mutex; - - /* CA */ - - ca_slot_info_t ci_slot[2]; - - enum av7110_video_mode vidmode; - struct dmxdev dmxdev; - struct dvb_demux demux; - - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - - /* for budget mode demux1 */ - struct dmxdev dmxdev1; - struct dvb_demux demux1; - struct dvb_net dvb_net1; - spinlock_t feedlock1; - int feeding1; - u32 ttbp; - unsigned char *grabbing; - struct saa7146_pgtable pt; - struct tasklet_struct vpe_tasklet; - bool full_ts; - - int fe_synced; - struct mutex pid_mutex; - - int video_blank; - struct video_status videostate; - u16 display_panscan; - int display_ar; - int trickmode; -#define TRICK_NONE 0 -#define TRICK_FAST 1 -#define TRICK_SLOW 2 -#define TRICK_FREEZE 3 - struct audio_status audiostate; - - struct dvb_demux_filter *handle2filter[32]; - struct av7110_p2t p2t_filter[MAXFILT]; - struct dvb_filter_pes2ts p2t[2]; - struct ipack ipack[2]; - u8 *kbuf[2]; - - int sinfo; - int feeding; - - int arm_errors; - int registered; - - - /* AV711X */ - - u32 arm_fw; - u32 arm_rtsl; - u32 arm_vid; - u32 arm_app; - u32 avtype; - int arm_ready; - struct task_struct *arm_thread; - wait_queue_head_t arm_wait; - u16 arm_loops; - - void *debi_virt; - dma_addr_t debi_bus; - - u16 pids[DMX_PES_OTHER]; - - struct dvb_ringbuffer ci_rbuffer; - struct dvb_ringbuffer ci_wbuffer; - - struct audio_mixer mixer; - - struct dvb_adapter dvb_adapter; - struct dvb_device *video_dev; - struct dvb_device *audio_dev; - struct dvb_device *ca_dev; - struct dvb_device *osd_dev; - - struct dvb_video_events video_events; - video_size_t video_size; - - u16 wssMode; - u16 wssData; - - struct infrared ir; - - /* firmware stuff */ - unsigned char *bin_fw; - unsigned long size_fw; - - unsigned char *bin_dpram; - unsigned long size_dpram; - - unsigned char *bin_root; - unsigned long size_root; - - struct dvb_frontend* fe; - fe_status_t fe_status; - - /* crash recovery */ - void (*recover)(struct av7110* av7110); - struct dvb_frontend_parameters saved_fe_params; - fe_sec_voltage_t saved_voltage; - fe_sec_tone_mode_t saved_tone; - struct dvb_diseqc_master_cmd saved_master_cmd; - fe_sec_mini_cmd_t saved_minicmd; - - int (*fe_init)(struct dvb_frontend* fe); - int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); - int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); - int (*fe_diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); - int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); - int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); - int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); - int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); - int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); -}; - - -extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, - u16 subpid, u16 pcrpid); - -extern int av7110_check_ir_config(struct av7110 *av7110, int force); -extern int av7110_ir_init(struct av7110 *av7110); -extern void av7110_ir_exit(struct av7110 *av7110); - -/* msp3400 i2c subaddresses */ -#define MSP_WR_DEM 0x10 -#define MSP_RD_DEM 0x11 -#define MSP_WR_DSP 0x12 -#define MSP_RD_DSP 0x13 - -extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val); -extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg); -extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val); - - -extern int av7110_init_analog_module(struct av7110 *av7110); -extern int av7110_init_v4l(struct av7110 *av7110); -extern int av7110_exit_v4l(struct av7110 *av7110); - -#endif /* _AV7110_H_ */ diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c deleted file mode 100644 index bdc62acf209..00000000000 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ /dev/null @@ -1,1563 +0,0 @@ -/* - * av7110_av.c: audio and video MPEG decoder stuff - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * originally based on code by: - * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/delay.h> -#include <linux/fs.h> - -#include "av7110.h" -#include "av7110_hw.h" -#include "av7110_av.h" -#include "av7110_ipack.h" - -/* MPEG-2 (ISO 13818 / H.222.0) stream types */ -#define PROG_STREAM_MAP 0xBC -#define PRIVATE_STREAM1 0xBD -#define PADDING_STREAM 0xBE -#define PRIVATE_STREAM2 0xBF -#define AUDIO_STREAM_S 0xC0 -#define AUDIO_STREAM_E 0xDF -#define VIDEO_STREAM_S 0xE0 -#define VIDEO_STREAM_E 0xEF -#define ECM_STREAM 0xF0 -#define EMM_STREAM 0xF1 -#define DSM_CC_STREAM 0xF2 -#define ISO13522_STREAM 0xF3 -#define PROG_STREAM_DIR 0xFF - -#define PTS_DTS_FLAGS 0xC0 - -//pts_dts flags -#define PTS_ONLY 0x80 -#define PTS_DTS 0xC0 -#define TS_SIZE 188 -#define TRANS_ERROR 0x80 -#define PAY_START 0x40 -#define TRANS_PRIO 0x20 -#define PID_MASK_HI 0x1F -//flags -#define TRANS_SCRMBL1 0x80 -#define TRANS_SCRMBL2 0x40 -#define ADAPT_FIELD 0x20 -#define PAYLOAD 0x10 -#define COUNT_MASK 0x0F - -// adaptation flags -#define DISCON_IND 0x80 -#define RAND_ACC_IND 0x40 -#define ES_PRI_IND 0x20 -#define PCR_FLAG 0x10 -#define OPCR_FLAG 0x08 -#define SPLICE_FLAG 0x04 -#define TRANS_PRIV 0x02 -#define ADAP_EXT_FLAG 0x01 - -// adaptation extension flags -#define LTW_FLAG 0x80 -#define PIECE_RATE 0x40 -#define SEAM_SPLICE 0x20 - - -static void p_to_t(u8 const *buf, long int length, u16 pid, - u8 *counter, struct dvb_demux_feed *feed); - - -int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) p2t->priv; - - if (!(dvbdmxfeed->ts_type & TS_PACKET)) - return 0; - if (buf[3] == 0xe0) // video PES do not have a length in TS - buf[4] = buf[5] = 0; - if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) - return dvbdmxfeed->cb.ts(buf, len, NULL, 0, - &dvbdmxfeed->feed.ts, DMX_OK); - else - return dvb_filter_pes2ts(p2t, buf, len, 1); -} - -static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) -{ - struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; - - dvbdmxfeed->cb.ts(data, 188, NULL, 0, - &dvbdmxfeed->feed.ts, DMX_OK); - return 0; -} - -int av7110_av_start_record(struct av7110 *av7110, int av, - struct dvb_demux_feed *dvbdmxfeed) -{ - int ret = 0; - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - - dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed); - - if (av7110->playing || (av7110->rec_mode & av)) - return -EBUSY; - av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); - dvbdmx->recording = 1; - av7110->rec_mode |= av; - - switch (av7110->rec_mode) { - case RP_AUDIO: - dvb_filter_pes2ts_init(&av7110->p2t[0], - dvbdmx->pesfilter[0]->pid, - dvb_filter_pes2ts_cb, - (void *) dvbdmx->pesfilter[0]); - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); - break; - - case RP_VIDEO: - dvb_filter_pes2ts_init(&av7110->p2t[1], - dvbdmx->pesfilter[1]->pid, - dvb_filter_pes2ts_cb, - (void *) dvbdmx->pesfilter[1]); - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); - break; - - case RP_AV: - dvb_filter_pes2ts_init(&av7110->p2t[0], - dvbdmx->pesfilter[0]->pid, - dvb_filter_pes2ts_cb, - (void *) dvbdmx->pesfilter[0]); - dvb_filter_pes2ts_init(&av7110->p2t[1], - dvbdmx->pesfilter[1]->pid, - dvb_filter_pes2ts_cb, - (void *) dvbdmx->pesfilter[1]); - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); - break; - } - return ret; -} - -int av7110_av_start_play(struct av7110 *av7110, int av) -{ - int ret = 0; - dprintk(2, "av7110:%p, \n", av7110); - - if (av7110->rec_mode) - return -EBUSY; - if (av7110->playing & av) - return -EBUSY; - - av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); - - if (av7110->playing == RP_NONE) { - av7110_ipack_reset(&av7110->ipack[0]); - av7110_ipack_reset(&av7110->ipack[1]); - } - - av7110->playing |= av; - switch (av7110->playing) { - case RP_AUDIO: - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); - break; - case RP_VIDEO: - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); - av7110->sinfo = 0; - break; - case RP_AV: - av7110->sinfo = 0; - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); - break; - } - if (!ret) - ret = av7110->playing; - return ret; -} - -int av7110_av_stop(struct av7110 *av7110, int av) -{ - int ret = 0; - dprintk(2, "av7110:%p, \n", av7110); - - if (!(av7110->playing & av) && !(av7110->rec_mode & av)) - return 0; - av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); - if (av7110->playing) { - av7110->playing &= ~av; - switch (av7110->playing) { - case RP_AUDIO: - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); - break; - case RP_VIDEO: - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); - break; - case RP_NONE: - ret = av7110_set_vidmode(av7110, av7110->vidmode); - break; - } - } else { - av7110->rec_mode &= ~av; - switch (av7110->rec_mode) { - case RP_AUDIO: - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); - break; - case RP_VIDEO: - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); - break; - case RP_NONE: - break; - } - } - return ret; -} - - -int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen) -{ - int len; - u32 sync; - u16 blen; - - if (!dlen) { - wake_up(&buf->queue); - return -1; - } - while (1) { - if ((len = dvb_ringbuffer_avail(buf)) < 6) - return -1; - sync = DVB_RINGBUFFER_PEEK(buf, 0) << 24; - sync |= DVB_RINGBUFFER_PEEK(buf, 1) << 16; - sync |= DVB_RINGBUFFER_PEEK(buf, 2) << 8; - sync |= DVB_RINGBUFFER_PEEK(buf, 3); - - if (((sync &~ 0x0f) == 0x000001e0) || - ((sync &~ 0x1f) == 0x000001c0) || - (sync == 0x000001bd)) - break; - printk("resync\n"); - DVB_RINGBUFFER_SKIP(buf, 1); - } - blen = DVB_RINGBUFFER_PEEK(buf, 4) << 8; - blen |= DVB_RINGBUFFER_PEEK(buf, 5); - blen += 6; - if (len < blen || blen > dlen) { - //printk("buffer empty - avail %d blen %u dlen %d\n", len, blen, dlen); - wake_up(&buf->queue); - return -1; - } - - dvb_ringbuffer_read(buf, dest, (size_t) blen); - - dprintk(2, "pread=0x%08lx, pwrite=0x%08lx\n", - (unsigned long) buf->pread, (unsigned long) buf->pwrite); - wake_up(&buf->queue); - return blen; -} - - -int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) -{ - int err, vol, val, balance = 0; - - dprintk(2, "av7110:%p, \n", av7110); - - av7110->mixer.volume_left = volleft; - av7110->mixer.volume_right = volright; - - switch (av7110->adac_type) { - case DVB_ADAC_TI: - volleft = (volleft * 256) / 1036; - volright = (volright * 256) / 1036; - if (volleft > 0x3f) - volleft = 0x3f; - if (volright > 0x3f) - volright = 0x3f; - if ((err = SendDAC(av7110, 3, 0x80 + volleft))) - return err; - return SendDAC(av7110, 4, volright); - - case DVB_ADAC_CRYSTAL: - volleft = 127 - volleft / 2; - volright = 127 - volright / 2; - i2c_writereg(av7110, 0x20, 0x03, volleft); - i2c_writereg(av7110, 0x20, 0x04, volright); - return 0; - - case DVB_ADAC_MSP34x0: - vol = (volleft > volright) ? volleft : volright; - val = (vol * 0x73 / 255) << 8; - if (vol > 0) - balance = ((volright - volleft) * 127) / vol; - msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ - msp_writereg(av7110, MSP_WR_DSP, 0x0006, val); /* headphonesr */ - return 0; - - case DVB_ADAC_MSP34x5: - vol = (volleft > volright) ? volleft : volright; - val = (vol * 0x73 / 255) << 8; - if (vol > 0) - balance = ((volright - volleft) * 127) / vol; - msp_writereg(av7110, MSP_WR_DSP, 0x0001, balance << 8); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, val); /* loudspeaker */ - return 0; - } - - return 0; -} - -int av7110_set_vidmode(struct av7110 *av7110, enum av7110_video_mode mode) -{ - int ret; - dprintk(2, "av7110:%p, \n", av7110); - - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); - - if (!ret && !av7110->playing) { - ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], - av7110->pids[DMX_PES_AUDIO], - av7110->pids[DMX_PES_TELETEXT], - 0, av7110->pids[DMX_PES_PCR]); - if (!ret) - ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); - } - return ret; -} - - -static enum av7110_video_mode sw2mode[16] = { - AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, - AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_PAL, - AV7110_VIDEO_MODE_NTSC, AV7110_VIDEO_MODE_NTSC, - AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_NTSC, - AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, - AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, - AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, - AV7110_VIDEO_MODE_PAL, AV7110_VIDEO_MODE_PAL, -}; - -static int get_video_format(struct av7110 *av7110, u8 *buf, int count) -{ - int i; - int hsize, vsize; - int sw; - u8 *p; - int ret = 0; - - dprintk(2, "av7110:%p, \n", av7110); - - if (av7110->sinfo) - return 0; - for (i = 7; i < count - 10; i++) { - p = buf + i; - if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) - continue; - p += 4; - hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); - vsize = ((p[1] &0x0F) << 8) | (p[2]); - sw = (p[3] & 0x0F); - ret = av7110_set_vidmode(av7110, sw2mode[sw]); - if (!ret) { - dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); - av7110->sinfo = 1; - } - break; - } - return ret; -} - - -/**************************************************************************** - * I/O buffer management and control - ****************************************************************************/ - -static inline long aux_ring_buffer_write(struct dvb_ringbuffer *rbuf, - const u8 *buf, unsigned long count) -{ - unsigned long todo = count; - int free; - - while (todo > 0) { - if (dvb_ringbuffer_free(rbuf) < 2048) { - if (wait_event_interruptible(rbuf->queue, - (dvb_ringbuffer_free(rbuf) >= 2048))) - return count - todo; - } - free = dvb_ringbuffer_free(rbuf); - if (free > todo) - free = todo; - dvb_ringbuffer_write(rbuf, buf, free); - todo -= free; - buf += free; - } - - return count - todo; -} - -static void play_video_cb(u8 *buf, int count, void *priv) -{ - struct av7110 *av7110 = (struct av7110 *) priv; - dprintk(2, "av7110:%p, \n", av7110); - - if ((buf[3] & 0xe0) == 0xe0) { - get_video_format(av7110, buf, count); - aux_ring_buffer_write(&av7110->avout, buf, count); - } else - aux_ring_buffer_write(&av7110->aout, buf, count); -} - -static void play_audio_cb(u8 *buf, int count, void *priv) -{ - struct av7110 *av7110 = (struct av7110 *) priv; - dprintk(2, "av7110:%p, \n", av7110); - - aux_ring_buffer_write(&av7110->aout, buf, count); -} - -#define FREE_COND (dvb_ringbuffer_free(&av7110->avout) >= 20 * 1024 && \ - dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) - -static ssize_t dvb_play(struct av7110 *av7110, const char __user *buf, - unsigned long count, int nonblock, int type) -{ - unsigned long todo = count, n; - dprintk(2, "av7110:%p, \n", av7110); - - if (!av7110->kbuf[type]) - return -ENOBUFS; - - if (nonblock && !FREE_COND) - return -EWOULDBLOCK; - - while (todo > 0) { - if (!FREE_COND) { - if (nonblock) - return count - todo; - if (wait_event_interruptible(av7110->avout.queue, - FREE_COND)) - return count - todo; - } - n = todo; - if (n > IPACKS * 2) - n = IPACKS * 2; - if (copy_from_user(av7110->kbuf[type], buf, n)) - return -EFAULT; - av7110_ipack_instant_repack(av7110->kbuf[type], n, - &av7110->ipack[type]); - todo -= n; - buf += n; - } - return count - todo; -} - -static ssize_t dvb_play_kernel(struct av7110 *av7110, const u8 *buf, - unsigned long count, int nonblock, int type) -{ - unsigned long todo = count, n; - dprintk(2, "av7110:%p, \n", av7110); - - if (!av7110->kbuf[type]) - return -ENOBUFS; - - if (nonblock && !FREE_COND) - return -EWOULDBLOCK; - - while (todo > 0) { - if (!FREE_COND) { - if (nonblock) - return count - todo; - if (wait_event_interruptible(av7110->avout.queue, - FREE_COND)) - return count - todo; - } - n = todo; - if (n > IPACKS * 2) - n = IPACKS * 2; - av7110_ipack_instant_repack(buf, n, &av7110->ipack[type]); - todo -= n; - buf += n; - } - return count - todo; -} - -static ssize_t dvb_aplay(struct av7110 *av7110, const char __user *buf, - unsigned long count, int nonblock, int type) -{ - unsigned long todo = count, n; - dprintk(2, "av7110:%p, \n", av7110); - - if (!av7110->kbuf[type]) - return -ENOBUFS; - if (nonblock && dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) - return -EWOULDBLOCK; - - while (todo > 0) { - if (dvb_ringbuffer_free(&av7110->aout) < 20 * 1024) { - if (nonblock) - return count - todo; - if (wait_event_interruptible(av7110->aout.queue, - (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024))) - return count-todo; - } - n = todo; - if (n > IPACKS * 2) - n = IPACKS * 2; - if (copy_from_user(av7110->kbuf[type], buf, n)) - return -EFAULT; - av7110_ipack_instant_repack(av7110->kbuf[type], n, - &av7110->ipack[type]); - todo -= n; - buf += n; - } - return count - todo; -} - -void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed) -{ - memset(p->pes, 0, TS_SIZE); - p->counter = 0; - p->pos = 0; - p->frags = 0; - if (feed) - p->feed = feed; -} - -static void clear_p2t(struct av7110_p2t *p) -{ - memset(p->pes, 0, TS_SIZE); -// p->counter = 0; - p->pos = 0; - p->frags = 0; -} - - -static int find_pes_header(u8 const *buf, long int length, int *frags) -{ - int c = 0; - int found = 0; - - *frags = 0; - - while (c < length - 3 && !found) { - if (buf[c] == 0x00 && buf[c + 1] == 0x00 && - buf[c + 2] == 0x01) { - switch ( buf[c + 3] ) { - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - found = 1; - break; - - default: - c++; - break; - } - } else - c++; - } - if (c == length - 3 && !found) { - if (buf[length - 1] == 0x00) - *frags = 1; - if (buf[length - 2] == 0x00 && - buf[length - 1] == 0x00) - *frags = 2; - if (buf[length - 3] == 0x00 && - buf[length - 2] == 0x00 && - buf[length - 1] == 0x01) - *frags = 3; - return -1; - } - - return c; -} - -void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p) -{ - int c, c2, l, add; - int check, rest; - - c = 0; - c2 = 0; - if (p->frags){ - check = 0; - switch(p->frags) { - case 1: - if (buf[c] == 0x00 && buf[c + 1] == 0x01) { - check = 1; - c += 2; - } - break; - case 2: - if (buf[c] == 0x01) { - check = 1; - c++; - } - break; - case 3: - check = 1; - } - if (check) { - switch (buf[c]) { - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - p->pes[0] = 0x00; - p->pes[1] = 0x00; - p->pes[2] = 0x01; - p->pes[3] = buf[c]; - p->pos = 4; - memcpy(p->pes + p->pos, buf + c, (TS_SIZE - 4) - p->pos); - c += (TS_SIZE - 4) - p->pos; - p_to_t(p->pes, (TS_SIZE - 4), pid, &p->counter, p->feed); - clear_p2t(p); - break; - - default: - c = 0; - break; - } - } - p->frags = 0; - } - - if (p->pos) { - c2 = find_pes_header(buf + c, length - c, &p->frags); - if (c2 >= 0 && c2 < (TS_SIZE - 4) - p->pos) - l = c2+c; - else - l = (TS_SIZE - 4) - p->pos; - memcpy(p->pes + p->pos, buf, l); - c += l; - p->pos += l; - p_to_t(p->pes, p->pos, pid, &p->counter, p->feed); - clear_p2t(p); - } - - add = 0; - while (c < length) { - c2 = find_pes_header(buf + c + add, length - c - add, &p->frags); - if (c2 >= 0) { - c2 += c + add; - if (c2 > c){ - p_to_t(buf + c, c2 - c, pid, &p->counter, p->feed); - c = c2; - clear_p2t(p); - add = 0; - } else - add = 1; - } else { - l = length - c; - rest = l % (TS_SIZE - 4); - l -= rest; - p_to_t(buf + c, l, pid, &p->counter, p->feed); - memcpy(p->pes, buf + c + l, rest); - p->pos = rest; - c = length; - } - } -} - - -static int write_ts_header2(u16 pid, u8 *counter, int pes_start, u8 *buf, u8 length) -{ - int i; - int c = 0; - int fill; - u8 tshead[4] = { 0x47, 0x00, 0x00, 0x10 }; - - fill = (TS_SIZE - 4) - length; - if (pes_start) - tshead[1] = 0x40; - if (fill) - tshead[3] = 0x30; - tshead[1] |= (u8)((pid & 0x1F00) >> 8); - tshead[2] |= (u8)(pid & 0x00FF); - tshead[3] |= ((*counter)++ & 0x0F); - memcpy(buf, tshead, 4); - c += 4; - - if (fill) { - buf[4] = fill - 1; - c++; - if (fill > 1) { - buf[5] = 0x00; - c++; - } - for (i = 6; i < fill + 4; i++) { - buf[i] = 0xFF; - c++; - } - } - - return c; -} - - -static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, - struct dvb_demux_feed *feed) -{ - int l, pes_start; - u8 obuf[TS_SIZE]; - long c = 0; - - pes_start = 0; - if (length > 3 && - buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01) - switch (buf[3]) { - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - case PRIVATE_STREAM1: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - pes_start = 1; - break; - - default: - break; - } - - while (c < length) { - memset(obuf, 0, TS_SIZE); - if (length - c >= (TS_SIZE - 4)){ - l = write_ts_header2(pid, counter, pes_start, - obuf, (TS_SIZE - 4)); - memcpy(obuf + l, buf + c, TS_SIZE - l); - c += TS_SIZE - l; - } else { - l = write_ts_header2(pid, counter, pes_start, - obuf, length - c); - memcpy(obuf + l, buf + c, TS_SIZE - l); - c = length; - } - feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, DMX_OK); - pes_start = 0; - } -} - - -int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len) -{ - struct dvb_demux *demux = feed->demux; - struct av7110 *av7110 = (struct av7110 *) demux->priv; - struct ipack *ipack = &av7110->ipack[feed->pes_type]; - - dprintk(2, "av7110:%p, \n", av7110); - - if (av7110->full_ts && demux->dmx.frontend->source != DMX_MEMORY_FE) - return 0; - - switch (feed->pes_type) { - case 0: - if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) - return -EINVAL; - break; - case 1: - if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) - return -EINVAL; - break; - default: - return -1; - } - - if (!(buf[3] & 0x10)) /* no payload? */ - return -1; - if (buf[1] & 0x40) - av7110_ipack_flush(ipack); - - if (buf[3] & 0x20) { /* adaptation field? */ - len -= buf[4] + 1; - buf += buf[4] + 1; - if (!len) - return 0; - } - - av7110_ipack_instant_repack(buf + 4, len - 4, &av7110->ipack[feed->pes_type]); - return 0; -} - - - -/****************************************************************************** - * Video MPEG decoder events - ******************************************************************************/ -void dvb_video_add_event(struct av7110 *av7110, struct video_event *event) -{ - struct dvb_video_events *events = &av7110->video_events; - int wp; - - spin_lock_bh(&events->lock); - - wp = (events->eventw + 1) % MAX_VIDEO_EVENT; - if (wp == events->eventr) { - events->overflow = 1; - events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; - } - - //FIXME: timestamp? - memcpy(&events->events[events->eventw], event, sizeof(struct video_event)); - events->eventw = wp; - - spin_unlock_bh(&events->lock); - - wake_up_interruptible(&events->wait_queue); -} - - -static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event, int flags) -{ - struct dvb_video_events *events = &av7110->video_events; - - if (events->overflow) { - events->overflow = 0; - return -EOVERFLOW; - } - if (events->eventw == events->eventr) { - int ret; - - if (flags & O_NONBLOCK) - return -EWOULDBLOCK; - - ret = wait_event_interruptible(events->wait_queue, - events->eventw != events->eventr); - if (ret < 0) - return ret; - } - - spin_lock_bh(&events->lock); - - memcpy(event, &events->events[events->eventr], - sizeof(struct video_event)); - events->eventr = (events->eventr + 1) % MAX_VIDEO_EVENT; - - spin_unlock_bh(&events->lock); - - return 0; -} - - -/****************************************************************************** - * DVB device file operations - ******************************************************************************/ - -static unsigned int dvb_video_poll(struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - unsigned int mask = 0; - - dprintk(2, "av7110:%p, \n", av7110); - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) - poll_wait(file, &av7110->avout.queue, wait); - - poll_wait(file, &av7110->video_events.wait_queue, wait); - - if (av7110->video_events.eventw != av7110->video_events.eventr) - mask = POLLPRI; - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - if (av7110->playing) { - if (FREE_COND) - mask |= (POLLOUT | POLLWRNORM); - } else /* if not playing: may play if asked for */ - mask |= (POLLOUT | POLLWRNORM); - } - - return mask; -} - -static ssize_t dvb_video_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(2, "av7110:%p, \n", av7110); - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) - return -EPERM; - - if (av7110->videostate.stream_source != VIDEO_SOURCE_MEMORY) - return -EPERM; - - return dvb_play(av7110, buf, count, file->f_flags & O_NONBLOCK, 1); -} - -static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - unsigned int mask = 0; - - dprintk(2, "av7110:%p, \n", av7110); - - poll_wait(file, &av7110->aout.queue, wait); - - if (av7110->playing) { - if (dvb_ringbuffer_free(&av7110->aout) >= 20 * 1024) - mask |= (POLLOUT | POLLWRNORM); - } else /* if not playing: may play if asked for */ - mask = (POLLOUT | POLLWRNORM); - - return mask; -} - -static ssize_t dvb_audio_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(2, "av7110:%p, \n", av7110); - - if (av7110->audiostate.stream_source != AUDIO_SOURCE_MEMORY) { - printk(KERN_ERR "not audio source memory\n"); - return -EPERM; - } - return dvb_aplay(av7110, buf, count, file->f_flags & O_NONBLOCK, 0); -} - -static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00 }; - -#define MIN_IFRAME 400000 - -static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) -{ - unsigned i, n; - int progressive = 0; - int match = 0; - - dprintk(2, "av7110:%p, \n", av7110); - - if (!(av7110->playing & RP_VIDEO)) { - if (av7110_av_start_play(av7110, RP_VIDEO) < 0) - return -EBUSY; - } - - /* search in buf for instances of 00 00 01 b5 1? */ - for (i = 0; i < len; i++) { - unsigned char c; - if (get_user(c, buf + i)) - return -EFAULT; - if (match == 5) { - progressive = c & 0x08; - match = 0; - } - if (c == 0x00) { - match = (match == 1 || match == 2) ? 2 : 1; - continue; - } - switch (match++) { - case 2: if (c == 0x01) - continue; - break; - case 3: if (c == 0xb5) - continue; - break; - case 4: if ((c & 0xf0) == 0x10) - continue; - break; - } - match = 0; - } - - /* setting n always > 1, fixes problems when playing stillframes - consisting of I- and P-Frames */ - n = MIN_IFRAME / len + 1; - - /* FIXME: nonblock? */ - dvb_play_kernel(av7110, iframe_header, sizeof(iframe_header), 0, 1); - - for (i = 0; i < n; i++) - dvb_play(av7110, buf, len, 0, 1); - - av7110_ipack_flush(&av7110->ipack[1]); - - if (progressive) - return vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); - else - return 0; -} - - -static int dvb_video_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - unsigned long arg = (unsigned long) parg; - int ret = 0; - - dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); - - if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && - cmd != VIDEO_GET_SIZE ) { - return -EPERM; - } - } - - switch (cmd) { - case VIDEO_STOP: - av7110->videostate.play_state = VIDEO_STOPPED; - if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) - ret = av7110_av_stop(av7110, RP_VIDEO); - else - ret = vidcom(av7110, AV_VIDEO_CMD_STOP, - av7110->videostate.video_blank ? 0 : 1); - if (!ret) - av7110->trickmode = TRICK_NONE; - break; - - case VIDEO_PLAY: - av7110->trickmode = TRICK_NONE; - if (av7110->videostate.play_state == VIDEO_FREEZED) { - av7110->videostate.play_state = VIDEO_PLAYING; - ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); - if (ret) - break; - } - - if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { - if (av7110->playing == RP_AV) { - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); - if (ret) - break; - av7110->playing &= ~RP_VIDEO; - } - ret = av7110_av_start_play(av7110, RP_VIDEO); - } - if (!ret) - ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); - if (!ret) - av7110->videostate.play_state = VIDEO_PLAYING; - break; - - case VIDEO_FREEZE: - av7110->videostate.play_state = VIDEO_FREEZED; - if (av7110->playing & RP_VIDEO) - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); - else - ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1); - if (!ret) - av7110->trickmode = TRICK_FREEZE; - break; - - case VIDEO_CONTINUE: - if (av7110->playing & RP_VIDEO) - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); - if (!ret) - ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); - if (!ret) { - av7110->videostate.play_state = VIDEO_PLAYING; - av7110->trickmode = TRICK_NONE; - } - break; - - case VIDEO_SELECT_SOURCE: - av7110->videostate.stream_source = (video_stream_source_t) arg; - break; - - case VIDEO_SET_BLANK: - av7110->videostate.video_blank = (int) arg; - break; - - case VIDEO_GET_STATUS: - memcpy(parg, &av7110->videostate, sizeof(struct video_status)); - break; - - case VIDEO_GET_EVENT: - ret = dvb_video_get_event(av7110, parg, file->f_flags); - break; - - case VIDEO_GET_SIZE: - memcpy(parg, &av7110->video_size, sizeof(video_size_t)); - break; - - case VIDEO_SET_DISPLAY_FORMAT: - { - video_displayformat_t format = (video_displayformat_t) arg; - - switch (format) { - case VIDEO_PAN_SCAN: - av7110->display_panscan = VID_PAN_SCAN_PREF; - break; - - case VIDEO_LETTER_BOX: - av7110->display_panscan = VID_VC_AND_PS_PREF; - break; - - case VIDEO_CENTER_CUT_OUT: - av7110->display_panscan = VID_CENTRE_CUT_PREF; - break; - - default: - ret = -EINVAL; - } - if (ret < 0) - break; - av7110->videostate.display_format = format; - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, - 1, av7110->display_panscan); - break; - } - - case VIDEO_SET_FORMAT: - if (arg > 1) { - ret = -EINVAL; - break; - } - av7110->display_ar = arg; - ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetMonitorType, - 1, (u16) arg); - break; - - case VIDEO_STILLPICTURE: - { - struct video_still_picture *pic = - (struct video_still_picture *) parg; - av7110->videostate.stream_source = VIDEO_SOURCE_MEMORY; - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - ret = play_iframe(av7110, pic->iFrame, pic->size, - file->f_flags & O_NONBLOCK); - break; - } - - case VIDEO_FAST_FORWARD: - //note: arg is ignored by firmware - if (av7110->playing & RP_VIDEO) - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, - __Scan_I, 2, AV_PES, 0); - else - ret = vidcom(av7110, AV_VIDEO_CMD_FFWD, arg); - if (!ret) { - av7110->trickmode = TRICK_FAST; - av7110->videostate.play_state = VIDEO_PLAYING; - } - break; - - case VIDEO_SLOWMOTION: - if (av7110->playing&RP_VIDEO) { - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); - if (!ret) - ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); - } else { - ret = vidcom(av7110, AV_VIDEO_CMD_PLAY, 0); - if (!ret) - ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 0); - if (!ret) - ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); - } - if (!ret) { - av7110->trickmode = TRICK_SLOW; - av7110->videostate.play_state = VIDEO_PLAYING; - } - break; - - case VIDEO_GET_CAPABILITIES: - *(int *)parg = VIDEO_CAP_MPEG1 | VIDEO_CAP_MPEG2 | - VIDEO_CAP_SYS | VIDEO_CAP_PROG; - break; - - case VIDEO_CLEAR_BUFFER: - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - av7110_ipack_reset(&av7110->ipack[1]); - - if (av7110->playing == RP_AV) { - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, - __Play, 2, AV_PES, 0); - if (ret) - break; - if (av7110->trickmode == TRICK_FAST) - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, - __Scan_I, 2, AV_PES, 0); - if (av7110->trickmode == TRICK_SLOW) { - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, - __Slow, 2, 0, 0); - if (!ret) - ret = vidcom(av7110, AV_VIDEO_CMD_SLOW, arg); - } - if (av7110->trickmode == TRICK_FREEZE) - ret = vidcom(av7110, AV_VIDEO_CMD_STOP, 1); - } - break; - - case VIDEO_SET_STREAMTYPE: - - break; - - default: - ret = -ENOIOCTLCMD; - break; - } - return ret; -} - -static int dvb_audio_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - unsigned long arg = (unsigned long) parg; - int ret = 0; - - dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd); - - if (((file->f_flags & O_ACCMODE) == O_RDONLY) && - (cmd != AUDIO_GET_STATUS)) - return -EPERM; - - switch (cmd) { - case AUDIO_STOP: - if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) - ret = av7110_av_stop(av7110, RP_AUDIO); - else - ret = audcom(av7110, AUDIO_CMD_MUTE); - if (!ret) - av7110->audiostate.play_state = AUDIO_STOPPED; - break; - - case AUDIO_PLAY: - if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) - ret = av7110_av_start_play(av7110, RP_AUDIO); - if (!ret) - ret = audcom(av7110, AUDIO_CMD_UNMUTE); - if (!ret) - av7110->audiostate.play_state = AUDIO_PLAYING; - break; - - case AUDIO_PAUSE: - ret = audcom(av7110, AUDIO_CMD_MUTE); - if (!ret) - av7110->audiostate.play_state = AUDIO_PAUSED; - break; - - case AUDIO_CONTINUE: - if (av7110->audiostate.play_state == AUDIO_PAUSED) { - av7110->audiostate.play_state = AUDIO_PLAYING; - ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); - } - break; - - case AUDIO_SELECT_SOURCE: - av7110->audiostate.stream_source = (audio_stream_source_t) arg; - break; - - case AUDIO_SET_MUTE: - { - ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); - if (!ret) - av7110->audiostate.mute_state = (int) arg; - break; - } - - case AUDIO_SET_AV_SYNC: - av7110->audiostate.AV_sync_state = (int) arg; - ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); - break; - - case AUDIO_SET_BYPASS_MODE: - if (FW_VERSION(av7110->arm_app) < 0x2621) - ret = -EINVAL; - av7110->audiostate.bypass_mode = (int)arg; - break; - - case AUDIO_CHANNEL_SELECT: - av7110->audiostate.channel_select = (audio_channel_select_t) arg; - - switch(av7110->audiostate.channel_select) { - case AUDIO_STEREO: - ret = audcom(av7110, AUDIO_CMD_STEREO); - if (!ret) { - if (av7110->adac_type == DVB_ADAC_CRYSTAL) - i2c_writereg(av7110, 0x20, 0x02, 0x49); - else if (av7110->adac_type == DVB_ADAC_MSP34x5) - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); - } - break; - - case AUDIO_MONO_LEFT: - ret = audcom(av7110, AUDIO_CMD_MONO_L); - if (!ret) { - if (av7110->adac_type == DVB_ADAC_CRYSTAL) - i2c_writereg(av7110, 0x20, 0x02, 0x4a); - else if (av7110->adac_type == DVB_ADAC_MSP34x5) - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0200); - } - break; - - case AUDIO_MONO_RIGHT: - ret = audcom(av7110, AUDIO_CMD_MONO_R); - if (!ret) { - if (av7110->adac_type == DVB_ADAC_CRYSTAL) - i2c_writereg(av7110, 0x20, 0x02, 0x45); - else if (av7110->adac_type == DVB_ADAC_MSP34x5) - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0210); - } - break; - - default: - ret = -EINVAL; - break; - } - break; - - case AUDIO_GET_STATUS: - memcpy(parg, &av7110->audiostate, sizeof(struct audio_status)); - break; - - case AUDIO_GET_CAPABILITIES: - if (FW_VERSION(av7110->arm_app) < 0x2621) - *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; - else - *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | - AUDIO_CAP_MP1 | AUDIO_CAP_MP2; - break; - - case AUDIO_CLEAR_BUFFER: - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - av7110_ipack_reset(&av7110->ipack[0]); - if (av7110->playing == RP_AV) - ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, - __Play, 2, AV_PES, 0); - break; - case AUDIO_SET_ID: - - break; - case AUDIO_SET_MIXER: - { - struct audio_mixer *amix = (struct audio_mixer *)parg; - - ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right); - break; - } - case AUDIO_SET_STREAMTYPE: - break; - default: - ret = -ENOIOCTLCMD; - } - return ret; -} - - -static int dvb_video_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - int err; - - dprintk(2, "av7110:%p, \n", av7110); - - if ((err = dvb_generic_open(inode, file)) < 0) - return err; - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - av7110->video_blank = 1; - av7110->audiostate.AV_sync_state = 1; - av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; - - /* empty event queue */ - av7110->video_events.eventr = av7110->video_events.eventw = 0; - } - - return 0; -} - -static int dvb_video_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(2, "av7110:%p, \n", av7110); - - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { - av7110_av_stop(av7110, RP_VIDEO); - } - - return dvb_generic_release(inode, file); -} - -static int dvb_audio_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - int err = dvb_generic_open(inode, file); - - dprintk(2, "av7110:%p, \n", av7110); - - if (err < 0) - return err; - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; - return 0; -} - -static int dvb_audio_release(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(2, "av7110:%p, \n", av7110); - - av7110_av_stop(av7110, RP_AUDIO); - return dvb_generic_release(inode, file); -} - - - -/****************************************************************************** - * driver registration - ******************************************************************************/ - -static struct file_operations dvb_video_fops = { - .owner = THIS_MODULE, - .write = dvb_video_write, - .ioctl = dvb_generic_ioctl, - .open = dvb_video_open, - .release = dvb_video_release, - .poll = dvb_video_poll, -}; - -static struct dvb_device dvbdev_video = { - .priv = NULL, - .users = 6, - .readers = 5, /* arbitrary */ - .writers = 1, - .fops = &dvb_video_fops, - .kernel_ioctl = dvb_video_ioctl, -}; - -static struct file_operations dvb_audio_fops = { - .owner = THIS_MODULE, - .write = dvb_audio_write, - .ioctl = dvb_generic_ioctl, - .open = dvb_audio_open, - .release = dvb_audio_release, - .poll = dvb_audio_poll, -}; - -static struct dvb_device dvbdev_audio = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_audio_fops, - .kernel_ioctl = dvb_audio_ioctl, -}; - - -int av7110_av_register(struct av7110 *av7110) -{ - av7110->audiostate.AV_sync_state = 0; - av7110->audiostate.mute_state = 0; - av7110->audiostate.play_state = AUDIO_STOPPED; - av7110->audiostate.stream_source = AUDIO_SOURCE_DEMUX; - av7110->audiostate.channel_select = AUDIO_STEREO; - av7110->audiostate.bypass_mode = 0; - - av7110->videostate.video_blank = 0; - av7110->videostate.play_state = VIDEO_STOPPED; - av7110->videostate.stream_source = VIDEO_SOURCE_DEMUX; - av7110->videostate.video_format = VIDEO_FORMAT_4_3; - av7110->videostate.display_format = VIDEO_LETTER_BOX; - av7110->display_ar = VIDEO_FORMAT_4_3; - av7110->display_panscan = VID_VC_AND_PS_PREF; - - init_waitqueue_head(&av7110->video_events.wait_queue); - spin_lock_init(&av7110->video_events.lock); - av7110->video_events.eventw = av7110->video_events.eventr = 0; - av7110->video_events.overflow = 0; - memset(&av7110->video_size, 0, sizeof (video_size_t)); - - dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, - &dvbdev_video, av7110, DVB_DEVICE_VIDEO); - - dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, - &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); - - return 0; -} - -void av7110_av_unregister(struct av7110 *av7110) -{ - dvb_unregister_device(av7110->audio_dev); - dvb_unregister_device(av7110->video_dev); -} - -int av7110_av_init(struct av7110 *av7110) -{ - void (*play[])(u8 *, int, void *) = { play_audio_cb, play_video_cb }; - int i, ret; - - for (i = 0; i < 2; i++) { - struct ipack *ipack = av7110->ipack + i; - - ret = av7110_ipack_init(ipack, IPACKS, play[i]); - if (ret < 0) { - if (i) - av7110_ipack_free(--ipack); - goto out; - } - ipack->data = av7110; - } - - dvb_ringbuffer_init(&av7110->avout, av7110->iobuf, AVOUTLEN); - dvb_ringbuffer_init(&av7110->aout, av7110->iobuf + AVOUTLEN, AOUTLEN); - - av7110->kbuf[0] = (u8 *)(av7110->iobuf + AVOUTLEN + AOUTLEN + BMPLEN); - av7110->kbuf[1] = av7110->kbuf[0] + 2 * IPACKS; -out: - return ret; -} - -void av7110_av_exit(struct av7110 *av7110) -{ - av7110_ipack_free(&av7110->ipack[0]); - av7110_ipack_free(&av7110->ipack[1]); -} diff --git a/drivers/media/dvb/ttpci/av7110_av.h b/drivers/media/dvb/ttpci/av7110_av.h deleted file mode 100644 index 5f02ef85e47..00000000000 --- a/drivers/media/dvb/ttpci/av7110_av.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _AV7110_AV_H_ -#define _AV7110_AV_H_ - -struct av7110; - -extern int av7110_set_vidmode(struct av7110 *av7110, - enum av7110_video_mode mode); - -extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len); -extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen); -extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len); - -extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright); -extern int av7110_av_stop(struct av7110 *av7110, int av); -extern int av7110_av_start_record(struct av7110 *av7110, int av, - struct dvb_demux_feed *dvbdmxfeed); -extern int av7110_av_start_play(struct av7110 *av7110, int av); - -extern void dvb_video_add_event(struct av7110 *av7110, struct video_event *event); - -extern void av7110_p2t_init(struct av7110_p2t *p, struct dvb_demux_feed *feed); -extern void av7110_p2t_write(u8 const *buf, long int length, u16 pid, struct av7110_p2t *p); - -extern int av7110_av_register(struct av7110 *av7110); -extern void av7110_av_unregister(struct av7110 *av7110); -extern int av7110_av_init(struct av7110 *av7110); -extern void av7110_av_exit(struct av7110 *av7110); - - -#endif /* _AV7110_AV_H_ */ diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c deleted file mode 100644 index 261135ded48..00000000000 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * av7110_ca.c: CA and CI stuff - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * originally based on code by: - * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/delay.h> -#include <linux/fs.h> -#include <linux/timer.h> -#include <linux/poll.h> - -#include "av7110.h" -#include "av7110_hw.h" -#include "av7110_ca.h" - - -void CI_handle(struct av7110 *av7110, u8 *data, u16 len) -{ - dprintk(8, "av7110:%p\n",av7110); - - if (len < 3) - return; - switch (data[0]) { - case CI_MSG_CI_INFO: - if (data[2] != 1 && data[2] != 2) - break; - switch (data[1]) { - case 0: - av7110->ci_slot[data[2] - 1].flags = 0; - break; - case 1: - av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_PRESENT; - break; - case 2: - av7110->ci_slot[data[2] - 1].flags |= CA_CI_MODULE_READY; - break; - } - break; - case CI_SWITCH_PRG_REPLY: - //av7110->ci_stat=data[1]; - break; - default: - break; - } -} - - -void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len) -{ - if (dvb_ringbuffer_free(cibuf) < len + 2) - return; - - DVB_RINGBUFFER_WRITE_BYTE(cibuf, len >> 8); - DVB_RINGBUFFER_WRITE_BYTE(cibuf, len & 0xff); - dvb_ringbuffer_write(cibuf, data, len); - wake_up_interruptible(&cibuf->queue); -} - - -/****************************************************************************** - * CI link layer file ops - ******************************************************************************/ - -static int ci_ll_init(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf, int size) -{ - struct dvb_ringbuffer *tab[] = { cirbuf, ciwbuf, NULL }, **p; - void *data; - - for (p = tab; *p; p++) { - data = vmalloc(size); - if (!data) { - while (p-- != tab) { - vfree(p[0]->data); - p[0]->data = NULL; - } - return -ENOMEM; - } - dvb_ringbuffer_init(*p, data, size); - } - return 0; -} - -static void ci_ll_flush(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) -{ - dvb_ringbuffer_flush_spinlock_wakeup(cirbuf); - dvb_ringbuffer_flush_spinlock_wakeup(ciwbuf); -} - -static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer *ciwbuf) -{ - vfree(cirbuf->data); - cirbuf->data = NULL; - vfree(ciwbuf->data); - ciwbuf->data = NULL; -} - -static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, - int slots, ca_slot_info_t *slot) -{ - int i; - int len = 0; - u8 msg[8] = { 0x00, 0x06, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00 }; - - for (i = 0; i < 2; i++) { - if (slots & (1 << i)) - len += 8; - } - - if (dvb_ringbuffer_free(cibuf) < len) - return -EBUSY; - - for (i = 0; i < 2; i++) { - if (slots & (1 << i)) { - msg[2] = i; - dvb_ringbuffer_write(cibuf, msg, 8); - slot[i].flags = 0; - } - } - - return 0; -} - -static ssize_t ci_ll_write(struct dvb_ringbuffer *cibuf, struct file *file, - const char __user *buf, size_t count, loff_t *ppos) -{ - int free; - int non_blocking = file->f_flags & O_NONBLOCK; - u8 *page = (u8 *)__get_free_page(GFP_USER); - int res; - - if (!page) - return -ENOMEM; - - res = -EINVAL; - if (count > 2048) - goto out; - - res = -EFAULT; - if (copy_from_user(page, buf, count)) - goto out; - - free = dvb_ringbuffer_free(cibuf); - if (count + 2 > free) { - res = -EWOULDBLOCK; - if (non_blocking) - goto out; - res = -ERESTARTSYS; - if (wait_event_interruptible(cibuf->queue, - (dvb_ringbuffer_free(cibuf) >= count + 2))) - goto out; - } - - DVB_RINGBUFFER_WRITE_BYTE(cibuf, count >> 8); - DVB_RINGBUFFER_WRITE_BYTE(cibuf, count & 0xff); - - res = dvb_ringbuffer_write(cibuf, page, count); -out: - free_page((unsigned long)page); - return res; -} - -static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, - char __user *buf, size_t count, loff_t *ppos) -{ - int avail; - int non_blocking = file->f_flags & O_NONBLOCK; - ssize_t len; - - if (!cibuf->data || !count) - return 0; - if (non_blocking && (dvb_ringbuffer_empty(cibuf))) - return -EWOULDBLOCK; - if (wait_event_interruptible(cibuf->queue, - !dvb_ringbuffer_empty(cibuf))) - return -ERESTARTSYS; - avail = dvb_ringbuffer_avail(cibuf); - if (avail < 4) - return 0; - len = DVB_RINGBUFFER_PEEK(cibuf, 0) << 8; - len |= DVB_RINGBUFFER_PEEK(cibuf, 1); - if (avail < len + 2 || count < len) - return -EINVAL; - DVB_RINGBUFFER_SKIP(cibuf, 2); - - return dvb_ringbuffer_read_user(cibuf, buf, len); -} - -static int dvb_ca_open(struct inode *inode, struct file *file) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - int err = dvb_generic_open(inode, file); - - dprintk(8, "av7110:%p\n",av7110); - - if (err < 0) - return err; - ci_ll_flush(&av7110->ci_rbuffer, &av7110->ci_wbuffer); - return 0; -} - -static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer; - struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer; - unsigned int mask = 0; - - dprintk(8, "av7110:%p\n",av7110); - - poll_wait(file, &rbuf->queue, wait); - poll_wait(file, &wbuf->queue, wait); - - if (!dvb_ringbuffer_empty(rbuf)) - mask |= (POLLIN | POLLRDNORM); - - if (dvb_ringbuffer_free(wbuf) > 1024) - mask |= (POLLOUT | POLLWRNORM); - - return mask; -} - -static int dvb_ca_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *parg) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - unsigned long arg = (unsigned long) parg; - - dprintk(8, "av7110:%p\n",av7110); - - switch (cmd) { - case CA_RESET: - return ci_ll_reset(&av7110->ci_wbuffer, file, arg, &av7110->ci_slot[0]); - break; - case CA_GET_CAP: - { - ca_caps_t cap; - - cap.slot_num = 2; - cap.slot_type = (FW_CI_LL_SUPPORT(av7110->arm_app) ? - CA_CI_LINK : CA_CI) | CA_DESCR; - cap.descr_num = 16; - cap.descr_type = CA_ECD; - memcpy(parg, &cap, sizeof(cap)); - break; - } - - case CA_GET_SLOT_INFO: - { - ca_slot_info_t *info=(ca_slot_info_t *)parg; - - if (info->num > 1) - return -EINVAL; - av7110->ci_slot[info->num].num = info->num; - av7110->ci_slot[info->num].type = FW_CI_LL_SUPPORT(av7110->arm_app) ? - CA_CI_LINK : CA_CI; - memcpy(info, &av7110->ci_slot[info->num], sizeof(ca_slot_info_t)); - break; - } - - case CA_GET_MSG: - break; - - case CA_SEND_MSG: - break; - - case CA_GET_DESCR_INFO: - { - ca_descr_info_t info; - - info.num = 16; - info.type = CA_ECD; - memcpy(parg, &info, sizeof (info)); - break; - } - - case CA_SET_DESCR: - { - ca_descr_t *descr = (ca_descr_t*) parg; - - if (descr->index >= 16) - return -EINVAL; - if (descr->parity > 1) - return -EINVAL; - av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetDescr, 5, - (descr->index<<8)|descr->parity, - (descr->cw[0]<<8)|descr->cw[1], - (descr->cw[2]<<8)|descr->cw[3], - (descr->cw[4]<<8)|descr->cw[5], - (descr->cw[6]<<8)|descr->cw[7]); - break; - } - - default: - return -EINVAL; - } - return 0; -} - -static ssize_t dvb_ca_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(8, "av7110:%p\n",av7110); - return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos); -} - -static ssize_t dvb_ca_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct dvb_device *dvbdev = file->private_data; - struct av7110 *av7110 = dvbdev->priv; - - dprintk(8, "av7110:%p\n",av7110); - return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); -} - -static struct file_operations dvb_ca_fops = { - .owner = THIS_MODULE, - .read = dvb_ca_read, - .write = dvb_ca_write, - .ioctl = dvb_generic_ioctl, - .open = dvb_ca_open, - .release = dvb_generic_release, - .poll = dvb_ca_poll, -}; - -static struct dvb_device dvbdev_ca = { - .priv = NULL, - .users = 1, - .writers = 1, - .fops = &dvb_ca_fops, - .kernel_ioctl = dvb_ca_ioctl, -}; - - -int av7110_ca_register(struct av7110 *av7110) -{ - return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev, - &dvbdev_ca, av7110, DVB_DEVICE_CA); -} - -void av7110_ca_unregister(struct av7110 *av7110) -{ - dvb_unregister_device(av7110->ca_dev); -} - -int av7110_ca_init(struct av7110* av7110) -{ - return ci_ll_init(&av7110->ci_rbuffer, &av7110->ci_wbuffer, 8192); -} - -void av7110_ca_exit(struct av7110* av7110) -{ - ci_ll_release(&av7110->ci_rbuffer, &av7110->ci_wbuffer); -} diff --git a/drivers/media/dvb/ttpci/av7110_ca.h b/drivers/media/dvb/ttpci/av7110_ca.h deleted file mode 100644 index 70ee855ece1..00000000000 --- a/drivers/media/dvb/ttpci/av7110_ca.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _AV7110_CA_H_ -#define _AV7110_CA_H_ - -struct av7110; - -extern void CI_handle(struct av7110 *av7110, u8 *data, u16 len); -extern void ci_get_data(struct dvb_ringbuffer *cibuf, u8 *data, int len); - -extern int av7110_ca_register(struct av7110 *av7110); -extern void av7110_ca_unregister(struct av7110 *av7110); -extern int av7110_ca_init(struct av7110* av7110); -extern void av7110_ca_exit(struct av7110* av7110); - -#endif /* _AV7110_CA_H_ */ diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c deleted file mode 100644 index 3a3f5279e92..00000000000 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* - * av7110_hw.c: av7110 low level hardware access and firmware interface - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * originally based on code by: - * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -/* for debugging ARM communication: */ -//#define COM_DEBUG - -#include <stdarg.h> -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/delay.h> -#include <linux/fs.h> - -#include "av7110.h" -#include "av7110_hw.h" - -#define _NOHANDSHAKE - -/**************************************************************************** - * DEBI functions - ****************************************************************************/ - -/* This DEBI code is based on the Stradis driver - by Nathan Laredo <laredo@gnu.org> */ - -int av7110_debiwrite(struct av7110 *av7110, u32 config, - int addr, u32 val, int count) -{ - struct saa7146_dev *dev = av7110->dev; - - if (count <= 0 || count > 32764) { - printk("%s: invalid count %d\n", __func__, count); - return -1; - } - if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { - printk("%s: wait_for_debi_done failed\n", __func__); - return -1; - } - saa7146_write(dev, DEBI_CONFIG, config); - if (count <= 4) /* immediate transfer */ - saa7146_write(dev, DEBI_AD, val); - else /* block transfer */ - saa7146_write(dev, DEBI_AD, av7110->debi_bus); - saa7146_write(dev, DEBI_COMMAND, (count << 17) | (addr & 0xffff)); - saa7146_write(dev, MC2, (2 << 16) | 2); - return 0; -} - -u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count) -{ - struct saa7146_dev *dev = av7110->dev; - u32 result = 0; - - if (count > 32764 || count <= 0) { - printk("%s: invalid count %d\n", __func__, count); - return 0; - } - if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { - printk("%s: wait_for_debi_done #1 failed\n", __func__); - return 0; - } - saa7146_write(dev, DEBI_AD, av7110->debi_bus); - saa7146_write(dev, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); - - saa7146_write(dev, DEBI_CONFIG, config); - saa7146_write(dev, MC2, (2 << 16) | 2); - if (count > 4) - return count; - if (saa7146_wait_for_debi_done(av7110->dev, 0) < 0) { - printk("%s: wait_for_debi_done #2 failed\n", __func__); - return 0; - } - - result = saa7146_read(dev, DEBI_AD); - result &= (0xffffffffUL >> ((4 - count) * 8)); - return result; -} - - - -/* av7110 ARM core boot stuff */ -#if 0 -void av7110_reset_arm(struct av7110 *av7110) -{ - saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); - - /* Disable DEBI and GPIO irq */ - SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03); - SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); - - saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI); - msleep(30); /* the firmware needs some time to initialize */ - - ARM_ResetMailBox(av7110); - - SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); - SAA7146_IER_ENABLE(av7110->dev, MASK_03); - - av7110->arm_ready = 1; - dprintk(1, "reset ARM\n"); -} -#endif /* 0 */ - -static int waitdebi(struct av7110 *av7110, int adr, int state) -{ - int k; - - dprintk(4, "%p\n", av7110); - - for (k = 0; k < 100; k++) { - if (irdebi(av7110, DEBINOSWAP, adr, 0, 2) == state) - return 0; - udelay(5); - } - return -ETIMEDOUT; -} - -static int load_dram(struct av7110 *av7110, u32 *data, int len) -{ - int i; - int blocks, rest; - u32 base, bootblock = AV7110_BOOT_BLOCK; - - dprintk(4, "%p\n", av7110); - - blocks = len / AV7110_BOOT_MAX_SIZE; - rest = len % AV7110_BOOT_MAX_SIZE; - base = DRAM_START_CODE; - - for (i = 0; i < blocks; i++) { - if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { - printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at block %d\n", i); - return -ETIMEDOUT; - } - dprintk(4, "writing DRAM block %d\n", i); - mwdebi(av7110, DEBISWAB, bootblock, - ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, AV7110_BOOT_MAX_SIZE); - bootblock ^= 0x1400; - iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, AV7110_BOOT_MAX_SIZE, 2); - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - base += AV7110_BOOT_MAX_SIZE; - } - - if (rest > 0) { - if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { - printk(KERN_ERR "dvb-ttpci: load_dram(): timeout at last block\n"); - return -ETIMEDOUT; - } - if (rest > 4) - mwdebi(av7110, DEBISWAB, bootblock, - ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE, rest); - else - mwdebi(av7110, DEBISWAB, bootblock, - ((u8 *)data) + i * AV7110_BOOT_MAX_SIZE - 4, rest + 4); - - iwdebi(av7110, DEBISWAB, AV7110_BOOT_BASE, swab32(base), 4); - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, rest, 2); - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - } - if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_EMPTY) < 0) { - printk(KERN_ERR "dvb-ttpci: load_dram(): timeout after last block\n"); - return -ETIMEDOUT; - } - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_SIZE, 0, 2); - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - if (waitdebi(av7110, AV7110_BOOT_STATE, BOOTSTATE_AV7110_BOOT_COMPLETE) < 0) { - printk(KERN_ERR "dvb-ttpci: load_dram(): final handshake timeout\n"); - return -ETIMEDOUT; - } - return 0; -} - - -/* we cannot write av7110 DRAM directly, so load a bootloader into - * the DPRAM which implements a simple boot protocol */ -static u8 bootcode[] = { - 0xea, 0x00, 0x00, 0x0e, 0xe1, 0xb0, 0xf0, 0x0e, 0xe2, 0x5e, 0xf0, 0x04, - 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x08, 0xe2, 0x5e, 0xf0, 0x04, - 0xe2, 0x5e, 0xf0, 0x04, 0xe2, 0x5e, 0xf0, 0x04, 0x2c, 0x00, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x34, - 0x00, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0x5a, 0x5a, 0x00, 0x1f, 0x15, 0x55, - 0x00, 0x00, 0x00, 0x09, 0xe5, 0x9f, 0xd0, 0x7c, 0xe5, 0x9f, 0x40, 0x74, - 0xe3, 0xa0, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x00, 0xe5, 0x84, 0x00, 0x04, - 0xe5, 0x9f, 0x10, 0x70, 0xe5, 0x9f, 0x20, 0x70, 0xe5, 0x9f, 0x30, 0x64, - 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe1, 0x51, 0x00, 0x02, - 0xda, 0xff, 0xff, 0xfb, 0xe5, 0x9f, 0xf0, 0x50, 0xe1, 0xd4, 0x10, 0xb0, - 0xe3, 0x51, 0x00, 0x00, 0x0a, 0xff, 0xff, 0xfc, 0xe1, 0xa0, 0x10, 0x0d, - 0xe5, 0x94, 0x30, 0x04, 0xe1, 0xd4, 0x20, 0xb2, 0xe2, 0x82, 0x20, 0x3f, - 0xe1, 0xb0, 0x23, 0x22, 0x03, 0xa0, 0x00, 0x02, 0xe1, 0xc4, 0x00, 0xb0, - 0x0a, 0xff, 0xff, 0xf4, 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, - 0xe8, 0xb1, 0x1f, 0xe0, 0xe8, 0xa3, 0x1f, 0xe0, 0xe2, 0x52, 0x20, 0x01, - 0x1a, 0xff, 0xff, 0xf9, 0xe2, 0x2d, 0xdb, 0x05, 0xea, 0xff, 0xff, 0xec, - 0x2c, 0x00, 0x03, 0xf8, 0x2c, 0x00, 0x04, 0x00, 0x9e, 0x00, 0x08, 0x00, - 0x2c, 0x00, 0x00, 0x74, 0x2c, 0x00, 0x00, 0xc0 -}; - -int av7110_bootarm(struct av7110 *av7110) -{ - struct saa7146_dev *dev = av7110->dev; - u32 ret; - int i; - - dprintk(4, "%p\n", av7110); - - av7110->arm_ready = 0; - - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); - - /* Disable DEBI and GPIO irq */ - SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19); - SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); - - /* enable DEBI */ - saa7146_write(av7110->dev, MC1, 0x08800880); - saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); - saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - /* test DEBI */ - iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); - /* FIXME: Why does Nexus CA require 2x iwdebi for first init? */ - iwdebi(av7110, DEBISWAP, DPRAM_BASE, 0x76543210, 4); - - if ((ret=irdebi(av7110, DEBINOSWAP, DPRAM_BASE, 0, 4)) != 0x10325476) { - printk(KERN_ERR "dvb-ttpci: debi test in av7110_bootarm() failed: " - "%08x != %08x (check your BIOS 'Plug&Play OS' settings)\n", - ret, 0x10325476); - return -1; - } - for (i = 0; i < 8192; i += 4) - iwdebi(av7110, DEBISWAP, DPRAM_BASE + i, 0x00, 4); - dprintk(2, "debi test OK\n"); - - /* boot */ - dprintk(1, "load boot code\n"); - saa7146_setgpio(dev, ARM_IRQ_LINE, SAA7146_GPIO_IRQLO); - //saa7146_setgpio(dev, DEBI_DONE_LINE, SAA7146_GPIO_INPUT); - //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); - - mwdebi(av7110, DEBISWAB, DPRAM_BASE, bootcode, sizeof(bootcode)); - iwdebi(av7110, DEBINOSWAP, AV7110_BOOT_STATE, BOOTSTATE_BUFFER_FULL, 2); - - if (saa7146_wait_for_debi_done(av7110->dev, 1)) { - printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " - "saa7146_wait_for_debi_done() timed out\n"); - return -ETIMEDOUT; - } - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); - mdelay(1); - - dprintk(1, "load dram code\n"); - if (load_dram(av7110, (u32 *)av7110->bin_root, av7110->size_root) < 0) { - printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " - "load_dram() failed\n"); - return -1; - } - - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); - mdelay(1); - - dprintk(1, "load dpram code\n"); - mwdebi(av7110, DEBISWAB, DPRAM_BASE, av7110->bin_dpram, av7110->size_dpram); - - if (saa7146_wait_for_debi_done(av7110->dev, 1)) { - printk(KERN_ERR "dvb-ttpci: av7110_bootarm(): " - "saa7146_wait_for_debi_done() timed out after loading DRAM\n"); - return -ETIMEDOUT; - } - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); - msleep(30); /* the firmware needs some time to initialize */ - - //ARM_ClearIrq(av7110); - ARM_ResetMailBox(av7110); - SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03); - SAA7146_IER_ENABLE(av7110->dev, MASK_03); - - av7110->arm_errors = 0; - av7110->arm_ready = 1; - return 0; -} - - -/**************************************************************************** - * DEBI command polling - ****************************************************************************/ - -int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) -{ - unsigned long start; - u32 stat; - int err; - - if (FW_VERSION(av7110->arm_app) <= 0x261c) { - /* not supported by old firmware */ - msleep(50); - return 0; - } - - /* new firmware */ - start = jiffies; - for (;;) { - err = time_after(jiffies, start + ARM_WAIT_FREE); - if (mutex_lock_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - mutex_unlock(&av7110->dcomlock); - if ((stat & flags) == 0) - break; - if (err) { - printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n", - __func__, stat & flags); - return -ETIMEDOUT; - } - msleep(1); - } - return 0; -} - -static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) -{ - int i; - unsigned long start; - char *type = NULL; - u16 flags[2] = {0, 0}; - u32 stat; - int err; - -// dprintk(4, "%p\n", av7110); - - if (!av7110->arm_ready) { - dprintk(1, "arm not ready.\n"); - return -ENXIO; - } - - start = jiffies; - while (1) { - err = time_after(jiffies, start + ARM_WAIT_FREE); - if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) - break; - if (err) { - printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __func__); - av7110->arm_errors++; - return -ETIMEDOUT; - } - msleep(1); - } - - if (FW_VERSION(av7110->arm_app) <= 0x261f) - wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0xffff, 2); - -#ifndef _NOHANDSHAKE - start = jiffies; - while (1) { - err = time_after(jiffies, start + ARM_WAIT_SHAKE); - if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) - break; - if (err) { - printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for HANDSHAKE_REG\n", __func__); - return -ETIMEDOUT; - } - msleep(1); - } -#endif - - switch ((buf[0] >> 8) & 0xff) { - case COMTYPE_PIDFILTER: - case COMTYPE_ENCODER: - case COMTYPE_REC_PLAY: - case COMTYPE_MPEGDECODER: - type = "MSG"; - flags[0] = GPMQOver; - flags[1] = GPMQFull; - break; - case COMTYPE_OSD: - type = "OSD"; - flags[0] = OSDQOver; - flags[1] = OSDQFull; - break; - case COMTYPE_MISC: - if (FW_VERSION(av7110->arm_app) >= 0x261d) { - type = "MSG"; - flags[0] = GPMQOver; - flags[1] = GPMQBusy; - } - break; - default: - break; - } - - if (type != NULL) { - /* non-immediate COMMAND type */ - start = jiffies; - for (;;) { - err = time_after(jiffies, start + ARM_WAIT_FREE); - stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - if (stat & flags[0]) { - printk(KERN_ERR "%s: %s QUEUE overflow\n", - __func__, type); - return -1; - } - if ((stat & flags[1]) == 0) - break; - if (err) { - printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n", - __func__, type); - av7110->arm_errors++; - return -ETIMEDOUT; - } - msleep(1); - } - } - - for (i = 2; i < length; i++) - wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2); - - if (length) - wdebi(av7110, DEBINOSWAP, COMMAND + 2, (u32) buf[1], 2); - else - wdebi(av7110, DEBINOSWAP, COMMAND + 2, 0, 2); - - wdebi(av7110, DEBINOSWAP, COMMAND, (u32) buf[0], 2); - - if (FW_VERSION(av7110->arm_app) <= 0x261f) - wdebi(av7110, DEBINOSWAP, COM_IF_LOCK, 0x0000, 2); - -#ifdef COM_DEBUG - start = jiffies; - while (1) { - err = time_after(jiffies, start + ARM_WAIT_FREE); - if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) - break; - if (err) { - printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND %d to complete\n", - __func__, (buf[0] >> 8) & 0xff); - return -ETIMEDOUT; - } - msleep(1); - } - - stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - if (stat & GPMQOver) { - printk(KERN_ERR "dvb-ttpci: %s(): GPMQOver\n", __func__); - return -ENOSPC; - } - else if (stat & OSDQOver) { - printk(KERN_ERR "dvb-ttpci: %s(): OSDQOver\n", __func__); - return -ENOSPC; - } -#endif - - return 0; -} - -static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) -{ - int ret; - -// dprintk(4, "%p\n", av7110); - - if (!av7110->arm_ready) { - dprintk(1, "arm not ready.\n"); - return -1; - } - if (mutex_lock_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - - ret = __av7110_send_fw_cmd(av7110, buf, length); - mutex_unlock(&av7110->dcomlock); - if (ret && ret!=-ERESTARTSYS) - printk(KERN_ERR "dvb-ttpci: %s(): av7110_send_fw_cmd error %d\n", - __func__, ret); - return ret; -} - -int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...) -{ - va_list args; - u16 buf[num + 2]; - int i, ret; - -// dprintk(4, "%p\n", av7110); - - buf[0] = ((type << 8) | com); - buf[1] = num; - - if (num) { - va_start(args, num); - for (i = 0; i < num; i++) - buf[i + 2] = va_arg(args, u32); - va_end(args); - } - - ret = av7110_send_fw_cmd(av7110, buf, num + 2); - if (ret && ret != -ERESTARTSYS) - printk(KERN_ERR "dvb-ttpci: av7110_fw_cmd error %d\n", ret); - return ret; -} - -#if 0 -int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len) -{ - int i, ret; - u16 cmd[18] = { ((COMTYPE_COMMON_IF << 8) + subcom), - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - dprintk(4, "%p\n", av7110); - - for(i = 0; i < len && i < 32; i++) - { - if(i % 2 == 0) - cmd[(i / 2) + 2] = (u16)(buf[i]) << 8; - else - cmd[(i / 2) + 2] |= buf[i]; - } - - ret = av7110_send_fw_cmd(av7110, cmd, 18); - if (ret && ret != -ERESTARTSYS) - printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret); - return ret; -} -#endif /* 0 */ - -int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, - int request_buf_len, u16 *reply_buf, int reply_buf_len) -{ - int err; - s16 i; - unsigned long start; -#ifdef COM_DEBUG - u32 stat; -#endif - - dprintk(4, "%p\n", av7110); - - if (!av7110->arm_ready) { - dprintk(1, "arm not ready.\n"); - return -1; - } - - if (mutex_lock_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - - if ((err = __av7110_send_fw_cmd(av7110, request_buf, request_buf_len)) < 0) { - mutex_unlock(&av7110->dcomlock); - printk(KERN_ERR "dvb-ttpci: av7110_fw_request error %d\n", err); - return err; - } - - start = jiffies; - while (1) { - err = time_after(jiffies, start + ARM_WAIT_FREE); - if (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2) == 0) - break; - if (err) { - printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", __func__); - mutex_unlock(&av7110->dcomlock); - return -ETIMEDOUT; - } -#ifdef _NOHANDSHAKE - msleep(1); -#endif - } - -#ifndef _NOHANDSHAKE - start = jiffies; - while (1) { - err = time_after(jiffies, start + ARM_WAIT_SHAKE); - if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) - break; - if (err) { - printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __func__); - mutex_unlock(&av7110->dcomlock); - return -ETIMEDOUT; - } - msleep(1); - } -#endif - -#ifdef COM_DEBUG - stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2); - if (stat & GPMQOver) { - printk(KERN_ERR "%s: GPMQOver\n", __func__); - mutex_unlock(&av7110->dcomlock); - return -1; - } - else if (stat & OSDQOver) { - printk(KERN_ERR "%s: OSDQOver\n", __func__); - mutex_unlock(&av7110->dcomlock); - return -1; - } -#endif - - for (i = 0; i < reply_buf_len; i++) - reply_buf[i] = rdebi(av7110, DEBINOSWAP, COM_BUFF + 2 * i, 0, 2); - - mutex_unlock(&av7110->dcomlock); - return 0; -} - -static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length) -{ - int ret; - ret = av7110_fw_request(av7110, &tag, 0, buf, length); - if (ret) - printk(KERN_ERR "dvb-ttpci: av7110_fw_query error %d\n", ret); - return ret; -} - - -/**************************************************************************** - * Firmware commands - ****************************************************************************/ - -/* get version of the firmware ROM, RTSL, video ucode and ARM application */ -int av7110_firmversion(struct av7110 *av7110) -{ - u16 buf[20]; - u16 tag = ((COMTYPE_REQUEST << 8) + ReqVersion); - - dprintk(4, "%p\n", av7110); - - if (av7110_fw_query(av7110, tag, buf, 16)) { - printk("dvb-ttpci: failed to boot firmware @ card %d\n", - av7110->dvb_adapter.num); - return -EIO; - } - - av7110->arm_fw = (buf[0] << 16) + buf[1]; - av7110->arm_rtsl = (buf[2] << 16) + buf[3]; - av7110->arm_vid = (buf[4] << 16) + buf[5]; - av7110->arm_app = (buf[6] << 16) + buf[7]; - av7110->avtype = (buf[8] << 16) + buf[9]; - - printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n", - av7110->dvb_adapter.num, av7110->arm_fw, - av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); - - /* print firmware capabilities */ - if (FW_CI_LL_SUPPORT(av7110->arm_app)) - printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n", - av7110->dvb_adapter.num); - else - printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n", - av7110->dvb_adapter.num); - - return 0; -} - - -int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst) -{ - int i, ret; - u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) + SendDiSEqC), - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - dprintk(4, "%p\n", av7110); - - if (len > 10) - len = 10; - - buf[1] = len + 2; - buf[2] = len; - - if (burst != -1) - buf[3] = burst ? 0x01 : 0x00; - else - buf[3] = 0xffff; - - for (i = 0; i < len; i++) - buf[i + 4] = msg[i]; - - ret = av7110_send_fw_cmd(av7110, buf, 18); - if (ret && ret!=-ERESTARTSYS) - printk(KERN_ERR "dvb-ttpci: av7110_diseqc_send error %d\n", ret); - return ret; -} - - -#ifdef CONFIG_DVB_AV7110_OSD - -static inline int SetColorBlend(struct av7110 *av7110, u8 windownr) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, SetCBlend, 1, windownr); -} - -static inline int SetBlend_(struct av7110 *av7110, u8 windownr, - enum av7110_osd_palette_type colordepth, u16 index, u8 blending) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, SetBlend, 4, - windownr, colordepth, index, blending); -} - -static inline int SetColor_(struct av7110 *av7110, u8 windownr, - enum av7110_osd_palette_type colordepth, u16 index, u16 colorhi, u16 colorlo) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, SetColor, 5, - windownr, colordepth, index, colorhi, colorlo); -} - -static inline int SetFont(struct av7110 *av7110, u8 windownr, u8 fontsize, - u16 colorfg, u16 colorbg) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Font, 4, - windownr, fontsize, colorfg, colorbg); -} - -static int FlushText(struct av7110 *av7110) -{ - unsigned long start; - int err; - - if (mutex_lock_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - start = jiffies; - while (1) { - err = time_after(jiffies, start + ARM_WAIT_OSD); - if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) - break; - if (err) { - printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for BUFF1_BASE == 0\n", - __func__); - mutex_unlock(&av7110->dcomlock); - return -ETIMEDOUT; - } - msleep(1); - } - mutex_unlock(&av7110->dcomlock); - return 0; -} - -static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, char *buf) -{ - int i, ret; - unsigned long start; - int length = strlen(buf) + 1; - u16 cbuf[5] = { (COMTYPE_OSD << 8) + DText, 3, win, x, y }; - - if (mutex_lock_interruptible(&av7110->dcomlock)) - return -ERESTARTSYS; - - start = jiffies; - while (1) { - ret = time_after(jiffies, start + ARM_WAIT_OSD); - if (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2) == 0) - break; - if (ret) { - printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for BUFF1_BASE == 0\n", - __func__); - mutex_unlock(&av7110->dcomlock); - return -ETIMEDOUT; - } - msleep(1); - } -#ifndef _NOHANDSHAKE - start = jiffies; - while (1) { - ret = time_after(jiffies, start + ARM_WAIT_SHAKE); - if (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2) == 0) - break; - if (ret) { - printk(KERN_ERR "dvb-ttpci: %s: timeout waiting for HANDSHAKE_REG\n", - __func__); - mutex_unlock(&av7110->dcomlock); - return -ETIMEDOUT; - } - msleep(1); - } -#endif - for (i = 0; i < length / 2; i++) - wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, - swab16(*(u16 *)(buf + 2 * i)), 2); - if (length & 1) - wdebi(av7110, DEBINOSWAP, BUFF1_BASE + i * 2, 0, 2); - ret = __av7110_send_fw_cmd(av7110, cbuf, 5); - mutex_unlock(&av7110->dcomlock); - if (ret && ret!=-ERESTARTSYS) - printk(KERN_ERR "dvb-ttpci: WriteText error %d\n", ret); - return ret; -} - -static inline int DrawLine(struct av7110 *av7110, u8 windownr, - u16 x, u16 y, u16 dx, u16 dy, u16 color) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, DLine, 6, - windownr, x, y, dx, dy, color); -} - -static inline int DrawBlock(struct av7110 *av7110, u8 windownr, - u16 x, u16 y, u16 dx, u16 dy, u16 color) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, DBox, 6, - windownr, x, y, dx, dy, color); -} - -static inline int HideWindow(struct av7110 *av7110, u8 windownr) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, WHide, 1, windownr); -} - -static inline int MoveWindowRel(struct av7110 *av7110, u8 windownr, u16 x, u16 y) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveD, 3, windownr, x, y); -} - -static inline int MoveWindowAbs(struct av7110 *av7110, u8 windownr, u16 x, u16 y) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, WMoveA, 3, windownr, x, y); -} - -static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, WDestroy, 1, windownr); -} - -static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, - osd_raw_window_t disptype, - u16 width, u16 height) -{ - return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4, - windownr, disptype, width, height); -} - - -static enum av7110_osd_palette_type bpp2pal[8] = { - Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit -}; -static osd_raw_window_t bpp2bit[8] = { - OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8 -}; - -static inline int WaitUntilBmpLoaded(struct av7110 *av7110) -{ - int ret = wait_event_timeout(av7110->bmpq, - av7110->bmp_state != BMP_LOADING, 10*HZ); - if (ret == 0) { - printk("dvb-ttpci: warning: timeout waiting in LoadBitmap: %d, %d\n", - ret, av7110->bmp_state); - av7110->bmp_state = BMP_NONE; - return -ETIMEDOUT; - } - return 0; -} - -static inline int LoadBitmap(struct av7110 *av7110, - u16 dx, u16 dy, int inc, u8 __user * data) -{ - u16 format; - int bpp; - int i; - int d, delta; - u8 c; - int ret; - - dprintk(4, "%p\n", av7110); - - format = bpp2bit[av7110->osdbpp[av7110->osdwin]]; - - av7110->bmp_state = BMP_LOADING; - if (format == OSD_BITMAP8) { - bpp=8; delta = 1; - } else if (format == OSD_BITMAP4) { - bpp=4; delta = 2; - } else if (format == OSD_BITMAP2) { - bpp=2; delta = 4; - } else if (format == OSD_BITMAP1) { - bpp=1; delta = 8; - } else { - av7110->bmp_state = BMP_NONE; - return -EINVAL; - } - av7110->bmplen = ((dx * dy * bpp + 7) & ~7) / 8; - av7110->bmpp = 0; - if (av7110->bmplen > 32768) { - av7110->bmp_state = BMP_NONE; - return -EINVAL; - } - for (i = 0; i < dy; i++) { - if (copy_from_user(av7110->bmpbuf + 1024 + i * dx, data + i * inc, dx)) { - av7110->bmp_state = BMP_NONE; - return -EINVAL; - } - } - if (format != OSD_BITMAP8) { - for (i = 0; i < dx * dy / delta; i++) { - c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1]; - for (d = delta - 2; d >= 0; d--) { - c |= (((u8 *)av7110->bmpbuf)[1024 + i * delta + d] - << ((delta - d - 1) * bpp)); - ((u8 *)av7110->bmpbuf)[1024 + i] = c; - } - } - } - av7110->bmplen += 1024; - dprintk(4, "av7110_fw_cmd: LoadBmp size %d\n", av7110->bmplen); - ret = av7110_fw_cmd(av7110, COMTYPE_OSD, LoadBmp, 3, format, dx, dy); - if (!ret) - ret = WaitUntilBmpLoaded(av7110); - return ret; -} - -static int BlitBitmap(struct av7110 *av7110, u16 x, u16 y) -{ - dprintk(4, "%p\n", av7110); - - return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, av7110->osdwin, x, y, 0); -} - -static inline int ReleaseBitmap(struct av7110 *av7110) -{ - dprintk(4, "%p\n", av7110); - - if (av7110->bmp_state != BMP_LOADED && FW_VERSION(av7110->arm_app) < 0x261e) - return -1; - if (av7110->bmp_state == BMP_LOADING) - dprintk(1,"ReleaseBitmap called while BMP_LOADING\n"); - av7110->bmp_state = BMP_NONE; - return av7110_fw_cmd(av7110, COMTYPE_OSD, ReleaseBmp, 0); -} - -static u32 RGB2YUV(u16 R, u16 G, u16 B) -{ - u16 y, u, v; - u16 Y, Cr, Cb; - - y = R * 77 + G * 150 + B * 29; /* Luma=0.299R+0.587G+0.114B 0..65535 */ - u = 2048 + B * 8 -(y >> 5); /* Cr 0..4095 */ - v = 2048 + R * 8 -(y >> 5); /* Cb 0..4095 */ - - Y = y / 256; - Cb = u / 16; - Cr = v / 16; - - return Cr | (Cb << 16) | (Y << 8); -} - -static int OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 blend) -{ - int ret; - - u16 ch, cl; - u32 yuv; - - yuv = blend ? RGB2YUV(r,g,b) : 0; - cl = (yuv & 0xffff); - ch = ((yuv >> 16) & 0xffff); - ret = SetColor_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], - color, ch, cl); - if (!ret) - ret = SetBlend_(av7110, av7110->osdwin, bpp2pal[av7110->osdbpp[av7110->osdwin]], - color, ((blend >> 4) & 0x0f)); - return ret; -} - -static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last) -{ - int i; - int length = last - first + 1; - - if (length * 4 > DATA_BUFF3_SIZE) - return -EINVAL; - - for (i = 0; i < length; i++) { - u32 color, blend, yuv; - - if (get_user(color, colors + i)) - return -EFAULT; - blend = (color & 0xF0000000) >> 4; - yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF, - (color >> 16) & 0xFF) | blend : 0; - yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); - wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4); - } - return av7110_fw_cmd(av7110, COMTYPE_OSD, Set_Palette, 4, - av7110->osdwin, - bpp2pal[av7110->osdbpp[av7110->osdwin]], - first, last); -} - -static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, - int x1, int y1, int inc, u8 __user * data) -{ - uint w, h, bpp, bpl, size, lpb, bnum, brest; - int i; - int rc,release_rc; - - w = x1 - x0 + 1; - h = y1 - y0 + 1; - if (inc <= 0) - inc = w; - if (w <= 0 || w > 720 || h <= 0 || h > 576) - return -EINVAL; - bpp = av7110->osdbpp[av7110->osdwin] + 1; - bpl = ((w * bpp + 7) & ~7) / 8; - size = h * bpl; - lpb = (32 * 1024) / bpl; - bnum = size / (lpb * bpl); - brest = size - bnum * lpb * bpl; - - if (av7110->bmp_state == BMP_LOADING) { - /* possible if syscall is repeated by -ERESTARTSYS and if firmware cannot abort */ - BUG_ON (FW_VERSION(av7110->arm_app) >= 0x261e); - rc = WaitUntilBmpLoaded(av7110); - if (rc) - return rc; - /* just continue. This should work for all fw versions - * if bnum==1 && !brest && LoadBitmap was successful - */ - } - - rc = 0; - for (i = 0; i < bnum; i++) { - rc = LoadBitmap(av7110, w, lpb, inc, data); - if (rc) - break; - rc = BlitBitmap(av7110, x0, y0 + i * lpb); - if (rc) - break; - data += lpb * inc; - } - if (!rc && brest) { - rc = LoadBitmap(av7110, w, brest / bpl, inc, data); - if (!rc) - rc = BlitBitmap(av7110, x0, y0 + bnum * lpb); - } - release_rc = ReleaseBitmap(av7110); - if (!rc) - rc = release_rc; - if (rc) - dprintk(1,"returns %d\n",rc); - return rc; -} - -int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) -{ - int ret; - - if (mutex_lock_interruptible(&av7110->osd_mutex)) - return -ERESTARTSYS; - - switch (dc->cmd) { - case OSD_Close: - ret = DestroyOSDWindow(av7110, av7110->osdwin); - break; - case OSD_Open: - av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7; - ret = CreateOSDWindow(av7110, av7110->osdwin, - bpp2bit[av7110->osdbpp[av7110->osdwin]], - dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); - if (ret) - break; - if (!dc->data) { - ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); - if (ret) - break; - ret = SetColorBlend(av7110, av7110->osdwin); - } - break; - case OSD_Show: - ret = MoveWindowRel(av7110, av7110->osdwin, 0, 0); - break; - case OSD_Hide: - ret = HideWindow(av7110, av7110->osdwin); - break; - case OSD_Clear: - ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); - break; - case OSD_Fill: - ret = DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); - break; - case OSD_SetColor: - ret = OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); - break; - case OSD_SetPalette: - if (FW_VERSION(av7110->arm_app) >= 0x2618) - ret = OSDSetPalette(av7110, dc->data, dc->color, dc->x0); - else { - int i, len = dc->x0-dc->color+1; - u8 __user *colors = (u8 __user *)dc->data; - u8 r, g, b, blend; - ret = 0; - for (i = 0; i<len; i++) { - if (get_user(r, colors + i * 4) || - get_user(g, colors + i * 4 + 1) || - get_user(b, colors + i * 4 + 2) || - get_user(blend, colors + i * 4 + 3)) { - ret = -EFAULT; - break; - } - ret = OSDSetColor(av7110, dc->color + i, r, g, b, blend); - if (ret) - break; - } - } - break; - case OSD_SetPixel: - ret = DrawLine(av7110, av7110->osdwin, - dc->x0, dc->y0, 0, 0, dc->color); - break; - case OSD_SetRow: - dc->y1 = dc->y0; - /* fall through */ - case OSD_SetBlock: - ret = OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); - break; - case OSD_FillRow: - ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, - dc->x1-dc->x0+1, dc->y1, dc->color); - break; - case OSD_FillBlock: - ret = DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, - dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color); - break; - case OSD_Line: - ret = DrawLine(av7110, av7110->osdwin, - dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color); - break; - case OSD_Text: - { - char textbuf[240]; - - if (strncpy_from_user(textbuf, dc->data, 240) < 0) { - ret = -EFAULT; - break; - } - textbuf[239] = 0; - if (dc->x1 > 3) - dc->x1 = 3; - ret = SetFont(av7110, av7110->osdwin, dc->x1, - (u16) (dc->color & 0xffff), (u16) (dc->color >> 16)); - if (!ret) - ret = FlushText(av7110); - if (!ret) - ret = WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); - break; - } - case OSD_SetWindow: - if (dc->x0 < 1 || dc->x0 > 7) - ret = -EINVAL; - else { - av7110->osdwin = dc->x0; - ret = 0; - } - break; - case OSD_MoveWindow: - ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); - if (!ret) - ret = SetColorBlend(av7110, av7110->osdwin); - break; - case OSD_OpenRaw: - if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) { - ret = -EINVAL; - break; - } - if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) - av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1; - else - av7110->osdbpp[av7110->osdwin] = 0; - ret = CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color, - dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1); - if (ret) - break; - if (!dc->data) { - ret = MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); - if (!ret) - ret = SetColorBlend(av7110, av7110->osdwin); - } - break; - default: - ret = -EINVAL; - break; - } - - mutex_unlock(&av7110->osd_mutex); - if (ret==-ERESTARTSYS) - dprintk(1, "av7110_osd_cmd(%d) returns with -ERESTARTSYS\n",dc->cmd); - else if (ret) - dprintk(1, "av7110_osd_cmd(%d) returns with %d\n",dc->cmd,ret); - - return ret; -} - -int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap) -{ - switch (cap->cmd) { - case OSD_CAP_MEMSIZE: - if (FW_4M_SDRAM(av7110->arm_app)) - cap->val = 1000000; - else - cap->val = 92000; - return 0; - default: - return -EINVAL; - } -} -#endif /* CONFIG_DVB_AV7110_OSD */ diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h deleted file mode 100644 index ca99e5c1fc8..00000000000 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ /dev/null @@ -1,494 +0,0 @@ -#ifndef _AV7110_HW_H_ -#define _AV7110_HW_H_ - -#include "av7110.h" - -/* DEBI transfer mode defs */ - -#define DEBINOSWAP 0x000e0000 -#define DEBISWAB 0x001e0000 -#define DEBISWAP 0x002e0000 - -#define ARM_WAIT_FREE (HZ) -#define ARM_WAIT_SHAKE (HZ/5) -#define ARM_WAIT_OSD (HZ) - - -enum av7110_bootstate -{ - BOOTSTATE_BUFFER_EMPTY = 0, - BOOTSTATE_BUFFER_FULL = 1, - BOOTSTATE_AV7110_BOOT_COMPLETE = 2 -}; - -enum av7110_type_rec_play_format -{ RP_None, - AudioPES, - AudioMp2, - AudioPCM, - VideoPES, - AV_PES -}; - -enum av7110_osd_palette_type -{ - NoPalet = 0, /* No palette */ - Pal1Bit = 2, /* 2 colors for 1 Bit Palette */ - Pal2Bit = 4, /* 4 colors for 2 bit palette */ - Pal4Bit = 16, /* 16 colors for 4 bit palette */ - Pal8Bit = 256 /* 256 colors for 16 bit palette */ -}; - -/* switch defines */ -#define SB_GPIO 3 -#define SB_OFF SAA7146_GPIO_OUTLO /* SlowBlank off (TV-Mode) */ -#define SB_ON SAA7146_GPIO_INPUT /* SlowBlank on (AV-Mode) */ -#define SB_WIDE SAA7146_GPIO_OUTHI /* SlowBlank 6V (16/9-Mode) (not implemented) */ - -#define FB_GPIO 1 -#define FB_OFF SAA7146_GPIO_LO /* FastBlank off (CVBS-Mode) */ -#define FB_ON SAA7146_GPIO_OUTHI /* FastBlank on (RGB-Mode) */ -#define FB_LOOP SAA7146_GPIO_INPUT /* FastBlank loop-through (PC graphics ???) */ - -enum av7110_video_output_mode -{ - NO_OUT = 0, /* disable analog output */ - CVBS_RGB_OUT = 1, - CVBS_YC_OUT = 2, - YC_OUT = 3 -}; - -/* firmware internal msg q status: */ -#define GPMQFull 0x0001 /* Main Message Queue Full */ -#define GPMQOver 0x0002 /* Main Message Queue Overflow */ -#define HPQFull 0x0004 /* High Priority Msg Queue Full */ -#define HPQOver 0x0008 -#define OSDQFull 0x0010 /* OSD Queue Full */ -#define OSDQOver 0x0020 -#define GPMQBusy 0x0040 /* Queue not empty, FW >= 261d */ -#define HPQBusy 0x0080 -#define OSDQBusy 0x0100 - -/* hw section filter flags */ -#define SECTION_EIT 0x01 -#define SECTION_SINGLE 0x00 -#define SECTION_CYCLE 0x02 -#define SECTION_CONTINUOS 0x04 -#define SECTION_MODE 0x06 -#define SECTION_IPMPE 0x0C /* size up to 4k */ -#define SECTION_HIGH_SPEED 0x1C /* larger buffer */ -#define DATA_PIPING_FLAG 0x20 /* for Data Piping Filter */ - -#define PBUFSIZE_NONE 0x0000 -#define PBUFSIZE_1P 0x0100 -#define PBUFSIZE_2P 0x0200 -#define PBUFSIZE_1K 0x0300 -#define PBUFSIZE_2K 0x0400 -#define PBUFSIZE_4K 0x0500 -#define PBUFSIZE_8K 0x0600 -#define PBUFSIZE_16K 0x0700 -#define PBUFSIZE_32K 0x0800 - - -/* firmware command codes */ -enum av7110_osd_command { - WCreate, - WDestroy, - WMoveD, - WMoveA, - WHide, - WTop, - DBox, - DLine, - DText, - Set_Font, - SetColor, - SetBlend, - SetWBlend, - SetCBlend, - SetNonBlend, - LoadBmp, - BlitBmp, - ReleaseBmp, - SetWTrans, - SetWNoTrans, - Set_Palette -}; - -enum av7110_pid_command { - MultiPID, - VideoPID, - AudioPID, - InitFilt, - FiltError, - NewVersion, - CacheError, - AddPIDFilter, - DelPIDFilter, - Scan, - SetDescr, - SetIR, - FlushTSQueue -}; - -enum av7110_mpeg_command { - SelAudChannels -}; - -enum av7110_audio_command { - AudioDAC, - CabADAC, - ON22K, - OFF22K, - MainSwitch, - ADSwitch, - SendDiSEqC, - SetRegister, - SpdifSwitch -}; - -enum av7110_request_command { - AudioState, - AudioBuffState, - VideoState1, - VideoState2, - VideoState3, - CrashCounter, - ReqVersion, - ReqVCXO, - ReqRegister, - ReqSecFilterError, - ReqSTC -}; - -enum av7110_encoder_command { - SetVidMode, - SetTestMode, - LoadVidCode, - SetMonitorType, - SetPanScanType, - SetFreezeMode, - SetWSSConfig -}; - -enum av7110_rec_play_state { - __Record, - __Stop, - __Play, - __Pause, - __Slow, - __FF_IP, - __Scan_I, - __Continue -}; - -enum av7110_fw_cmd_misc { - AV7110_FW_VIDEO_ZOOM = 1, - AV7110_FW_VIDEO_COMMAND, - AV7110_FW_AUDIO_COMMAND -}; - -enum av7110_command_type { - COMTYPE_NOCOM, - COMTYPE_PIDFILTER, - COMTYPE_MPEGDECODER, - COMTYPE_OSD, - COMTYPE_BMP, - COMTYPE_ENCODER, - COMTYPE_AUDIODAC, - COMTYPE_REQUEST, - COMTYPE_SYSTEM, - COMTYPE_REC_PLAY, - COMTYPE_COMMON_IF, - COMTYPE_PID_FILTER, - COMTYPE_PES, - COMTYPE_TS, - COMTYPE_VIDEO, - COMTYPE_AUDIO, - COMTYPE_CI_LL, - COMTYPE_MISC = 0x80 -}; - -#define VID_NONE_PREF 0x00 /* No aspect ration processing preferred */ -#define VID_PAN_SCAN_PREF 0x01 /* Pan and Scan Display preferred */ -#define VID_VERT_COMP_PREF 0x02 /* Vertical compression display preferred */ -#define VID_VC_AND_PS_PREF 0x03 /* PanScan and vertical Compression if allowed */ -#define VID_CENTRE_CUT_PREF 0x05 /* PanScan with zero vector */ - -/* MPEG video decoder commands */ -#define AV_VIDEO_CMD_STOP 0x000e -#define AV_VIDEO_CMD_PLAY 0x000d -#define AV_VIDEO_CMD_FREEZE 0x0102 -#define AV_VIDEO_CMD_FFWD 0x0016 -#define AV_VIDEO_CMD_SLOW 0x0022 - -/* MPEG audio decoder commands */ -#define AUDIO_CMD_MUTE 0x0001 -#define AUDIO_CMD_UNMUTE 0x0002 -#define AUDIO_CMD_PCM16 0x0010 -#define AUDIO_CMD_STEREO 0x0080 -#define AUDIO_CMD_MONO_L 0x0100 -#define AUDIO_CMD_MONO_R 0x0200 -#define AUDIO_CMD_SYNC_OFF 0x000e -#define AUDIO_CMD_SYNC_ON 0x000f - -/* firmware data interface codes */ -#define DATA_NONE 0x00 -#define DATA_FSECTION 0x01 -#define DATA_IPMPE 0x02 -#define DATA_MPEG_RECORD 0x03 -#define DATA_DEBUG_MESSAGE 0x04 -#define DATA_COMMON_INTERFACE 0x05 -#define DATA_MPEG_PLAY 0x06 -#define DATA_BMP_LOAD 0x07 -#define DATA_IRCOMMAND 0x08 -#define DATA_PIPING 0x09 -#define DATA_STREAMING 0x0a -#define DATA_CI_GET 0x0b -#define DATA_CI_PUT 0x0c -#define DATA_MPEG_VIDEO_EVENT 0x0d - -#define DATA_PES_RECORD 0x10 -#define DATA_PES_PLAY 0x11 -#define DATA_TS_RECORD 0x12 -#define DATA_TS_PLAY 0x13 - -/* ancient CI command codes, only two are actually still used - * by the link level CI firmware */ -#define CI_CMD_ERROR 0x00 -#define CI_CMD_ACK 0x01 -#define CI_CMD_SYSTEM_READY 0x02 -#define CI_CMD_KEYPRESS 0x03 -#define CI_CMD_ON_TUNED 0x04 -#define CI_CMD_ON_SWITCH_PROGRAM 0x05 -#define CI_CMD_SECTION_ARRIVED 0x06 -#define CI_CMD_SECTION_TIMEOUT 0x07 -#define CI_CMD_TIME 0x08 -#define CI_CMD_ENTER_MENU 0x09 -#define CI_CMD_FAST_PSI 0x0a -#define CI_CMD_GET_SLOT_INFO 0x0b - -#define CI_MSG_NONE 0x00 -#define CI_MSG_CI_INFO 0x01 -#define CI_MSG_MENU 0x02 -#define CI_MSG_LIST 0x03 -#define CI_MSG_TEXT 0x04 -#define CI_MSG_REQUEST_INPUT 0x05 -#define CI_MSG_INPUT_COMPLETE 0x06 -#define CI_MSG_LIST_MORE 0x07 -#define CI_MSG_MENU_MORE 0x08 -#define CI_MSG_CLOSE_MMI_IMM 0x09 -#define CI_MSG_SECTION_REQUEST 0x0a -#define CI_MSG_CLOSE_FILTER 0x0b -#define CI_PSI_COMPLETE 0x0c -#define CI_MODULE_READY 0x0d -#define CI_SWITCH_PRG_REPLY 0x0e -#define CI_MSG_TEXT_MORE 0x0f - -#define CI_MSG_CA_PMT 0xe0 -#define CI_MSG_ERROR 0xf0 - - -/* base address of the dual ported RAM which serves as communication - * area between PCI bus and av7110, - * as seen by the DEBI bus of the saa7146 */ -#define DPRAM_BASE 0x4000 - -/* boot protocol area */ -#define AV7110_BOOT_STATE (DPRAM_BASE + 0x3F8) -#define AV7110_BOOT_SIZE (DPRAM_BASE + 0x3FA) -#define AV7110_BOOT_BASE (DPRAM_BASE + 0x3FC) -#define AV7110_BOOT_BLOCK (DPRAM_BASE + 0x400) -#define AV7110_BOOT_MAX_SIZE 0xc00 - -/* firmware command protocol area */ -#define IRQ_STATE (DPRAM_BASE + 0x0F4) -#define IRQ_STATE_EXT (DPRAM_BASE + 0x0F6) -#define MSGSTATE (DPRAM_BASE + 0x0F8) -#define COMMAND (DPRAM_BASE + 0x0FC) -#define COM_BUFF (DPRAM_BASE + 0x100) -#define COM_BUFF_SIZE 0x20 - -/* various data buffers */ -#define BUFF1_BASE (DPRAM_BASE + 0x120) -#define BUFF1_SIZE 0xE0 - -#define DATA_BUFF0_BASE (DPRAM_BASE + 0x200) -#define DATA_BUFF0_SIZE 0x0800 - -#define DATA_BUFF1_BASE (DATA_BUFF0_BASE+DATA_BUFF0_SIZE) -#define DATA_BUFF1_SIZE 0x0800 - -#define DATA_BUFF2_BASE (DATA_BUFF1_BASE+DATA_BUFF1_SIZE) -#define DATA_BUFF2_SIZE 0x0800 - -#define DATA_BUFF3_BASE (DATA_BUFF2_BASE+DATA_BUFF2_SIZE) -#define DATA_BUFF3_SIZE 0x0400 - -#define Reserved (DPRAM_BASE + 0x1E00) -#define Reserved_SIZE 0x1C0 - - -/* firmware status area */ -#define STATUS_BASE (DPRAM_BASE + 0x1FC0) -#define STATUS_LOOPS (STATUS_BASE + 0x08) - -#define STATUS_MPEG_WIDTH (STATUS_BASE + 0x0C) -/* ((aspect_ratio & 0xf) << 12) | (height & 0xfff) */ -#define STATUS_MPEG_HEIGHT_AR (STATUS_BASE + 0x0E) - -/* firmware data protocol area */ -#define RX_TYPE (DPRAM_BASE + 0x1FE8) -#define RX_LEN (DPRAM_BASE + 0x1FEA) -#define TX_TYPE (DPRAM_BASE + 0x1FEC) -#define TX_LEN (DPRAM_BASE + 0x1FEE) - -#define RX_BUFF (DPRAM_BASE + 0x1FF4) -#define TX_BUFF (DPRAM_BASE + 0x1FF6) - -#define HANDSHAKE_REG (DPRAM_BASE + 0x1FF8) -#define COM_IF_LOCK (DPRAM_BASE + 0x1FFA) - -#define IRQ_RX (DPRAM_BASE + 0x1FFC) -#define IRQ_TX (DPRAM_BASE + 0x1FFE) - -/* used by boot protocol to load firmware into av7110 DRAM */ -#define DRAM_START_CODE 0x2e000404 -#define DRAM_MAX_CODE_SIZE 0x00100000 - -/* saa7146 gpio lines */ -#define RESET_LINE 2 -#define DEBI_DONE_LINE 1 -#define ARM_IRQ_LINE 0 - - - -extern int av7110_bootarm(struct av7110 *av7110); -extern int av7110_firmversion(struct av7110 *av7110); -#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000) -#define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000) -#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF) - -extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags); -extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...); -extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, - int request_buf_len, u16 *reply_buf, int reply_buf_len); - - -/* DEBI (saa7146 data extension bus interface) access */ -extern int av7110_debiwrite(struct av7110 *av7110, u32 config, - int addr, u32 val, int count); -extern u32 av7110_debiread(struct av7110 *av7110, u32 config, - int addr, int count); - - -/* DEBI during interrupt */ -/* single word writes */ -static inline void iwdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - av7110_debiwrite(av7110, config, addr, val, count); -} - -/* buffer writes */ -static inline void mwdebi(struct av7110 *av7110, u32 config, int addr, u8 *val, int count) -{ - memcpy(av7110->debi_virt, val, count); - av7110_debiwrite(av7110, config, addr, 0, count); -} - -static inline u32 irdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - u32 res; - - res=av7110_debiread(av7110, config, addr, count); - if (count<=4) - memcpy(av7110->debi_virt, (char *) &res, count); - return res; -} - -/* DEBI outside interrupts, only for count <= 4! */ -static inline void wdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - unsigned long flags; - - spin_lock_irqsave(&av7110->debilock, flags); - av7110_debiwrite(av7110, config, addr, val, count); - spin_unlock_irqrestore(&av7110->debilock, flags); -} - -static inline u32 rdebi(struct av7110 *av7110, u32 config, int addr, u32 val, int count) -{ - unsigned long flags; - u32 res; - - spin_lock_irqsave(&av7110->debilock, flags); - res=av7110_debiread(av7110, config, addr, count); - spin_unlock_irqrestore(&av7110->debilock, flags); - return res; -} - -/* handle mailbox registers of the dual ported RAM */ -static inline void ARM_ResetMailBox(struct av7110 *av7110) -{ - unsigned long flags; - - spin_lock_irqsave(&av7110->debilock, flags); - av7110_debiread(av7110, DEBINOSWAP, IRQ_RX, 2); - av7110_debiwrite(av7110, DEBINOSWAP, IRQ_RX, 0, 2); - spin_unlock_irqrestore(&av7110->debilock, flags); -} - -static inline void ARM_ClearMailBox(struct av7110 *av7110) -{ - iwdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); -} - -static inline void ARM_ClearIrq(struct av7110 *av7110) -{ - irdebi(av7110, DEBINOSWAP, IRQ_RX, 0, 2); -} - -/**************************************************************************** - * Firmware commands - ****************************************************************************/ - -static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data) -{ - return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data); -} - -static inline int av7710_set_video_mode(struct av7110 *av7110, int mode) -{ - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode); -} - -static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg) -{ - return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4, - (com>>16), (com&0xffff), - (arg>>16), (arg&0xffff)); -} - -static inline int audcom(struct av7110 *av7110, u32 com) -{ - return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2, - (com>>16), (com&0xffff)); -} - -static inline int Set22K(struct av7110 *av7110, int state) -{ - return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); -} - - -extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned long burst); - - -#ifdef CONFIG_DVB_AV7110_OSD -extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc); -extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap); -#endif /* CONFIG_DVB_AV7110_OSD */ - - - -#endif /* _AV7110_HW_H_ */ diff --git a/drivers/media/dvb/ttpci/av7110_ipack.c b/drivers/media/dvb/ttpci/av7110_ipack.c deleted file mode 100644 index 699ef8b5b99..00000000000 --- a/drivers/media/dvb/ttpci/av7110_ipack.c +++ /dev/null @@ -1,403 +0,0 @@ -#include "dvb_filter.h" -#include "av7110_ipack.h" -#include <linux/string.h> /* for memcpy() */ -#include <linux/vmalloc.h> - - -void av7110_ipack_reset(struct ipack *p) -{ - p->found = 0; - p->cid = 0; - p->plength = 0; - p->flag1 = 0; - p->flag2 = 0; - p->hlength = 0; - p->mpeg = 0; - p->check = 0; - p->which = 0; - p->done = 0; - p->count = 0; -} - - -int av7110_ipack_init(struct ipack *p, int size, - void (*func)(u8 *buf, int size, void *priv)) -{ - if (!(p->buf = vmalloc(size*sizeof(u8)))) { - printk(KERN_WARNING "Couldn't allocate memory for ipack\n"); - return -ENOMEM; - } - p->size = size; - p->func = func; - p->repack_subids = 0; - av7110_ipack_reset(p); - return 0; -} - - -void av7110_ipack_free(struct ipack *p) -{ - vfree(p->buf); -} - - -static void send_ipack(struct ipack *p) -{ - int off; - struct dvb_audio_info ai; - int ac3_off = 0; - int streamid = 0; - int nframes = 0; - int f = 0; - - switch (p->mpeg) { - case 2: - if (p->count < 10) - return; - p->buf[3] = p->cid; - p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); - p->buf[5] = (u8)((p->count - 6) & 0x00ff); - if (p->repack_subids && p->cid == PRIVATE_STREAM1) { - off = 9 + p->buf[8]; - streamid = p->buf[off]; - if ((streamid & 0xf8) == 0x80) { - ai.off = 0; - ac3_off = ((p->buf[off + 2] << 8)| - p->buf[off + 3]); - if (ac3_off < p->count) - f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off, - p->count - ac3_off, &ai, 0); - if (!f) { - nframes = (p->count - off - 3 - ac3_off) / - ai.framesize + 1; - p->buf[off + 2] = (ac3_off >> 8) & 0xff; - p->buf[off + 3] = (ac3_off) & 0xff; - p->buf[off + 1] = nframes; - ac3_off += nframes * ai.framesize - p->count; - } - } - } - p->func(p->buf, p->count, p->data); - - p->buf[6] = 0x80; - p->buf[7] = 0x00; - p->buf[8] = 0x00; - p->count = 9; - if (p->repack_subids && p->cid == PRIVATE_STREAM1 - && (streamid & 0xf8) == 0x80) { - p->count += 4; - p->buf[9] = streamid; - p->buf[10] = (ac3_off >> 8) & 0xff; - p->buf[11] = (ac3_off) & 0xff; - p->buf[12] = 0; - } - break; - - case 1: - if (p->count < 8) - return; - p->buf[3] = p->cid; - p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); - p->buf[5] = (u8)((p->count - 6) & 0x00ff); - p->func(p->buf, p->count, p->data); - - p->buf[6] = 0x0f; - p->count = 7; - break; - } -} - - -void av7110_ipack_flush(struct ipack *p) -{ - if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6) - return; - p->plength = p->found - 6; - p->found = 0; - send_ipack(p); - av7110_ipack_reset(p); -} - - -static void write_ipack(struct ipack *p, const u8 *data, int count) -{ - u8 headr[3] = { 0x00, 0x00, 0x01 }; - - if (p->count < 6) { - memcpy(p->buf, headr, 3); - p->count = 6; - } - - if (p->count + count < p->size){ - memcpy(p->buf+p->count, data, count); - p->count += count; - } else { - int rest = p->size - p->count; - memcpy(p->buf+p->count, data, rest); - p->count += rest; - send_ipack(p); - if (count - rest > 0) - write_ipack(p, data + rest, count - rest); - } -} - - -int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p) -{ - int l; - int c = 0; - - while (c < count && (p->mpeg == 0 || - (p->mpeg == 1 && p->found < 7) || - (p->mpeg == 2 && p->found < 9)) - && (p->found < 5 || !p->done)) { - switch (p->found) { - case 0: - case 1: - if (buf[c] == 0x00) - p->found++; - else - p->found = 0; - c++; - break; - case 2: - if (buf[c] == 0x01) - p->found++; - else if (buf[c] == 0) - p->found = 2; - else - p->found = 0; - c++; - break; - case 3: - p->cid = 0; - switch (buf[c]) { - case PROG_STREAM_MAP: - case PRIVATE_STREAM2: - case PROG_STREAM_DIR: - case ECM_STREAM : - case EMM_STREAM : - case PADDING_STREAM : - case DSM_CC_STREAM : - case ISO13522_STREAM: - p->done = 1; - /* fall through */ - case PRIVATE_STREAM1: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - p->found++; - p->cid = buf[c]; - c++; - break; - default: - p->found = 0; - break; - } - break; - - case 4: - if (count-c > 1) { - p->plen[0] = buf[c]; - c++; - p->plen[1] = buf[c]; - c++; - p->found += 2; - p->plength = (p->plen[0] << 8) | p->plen[1]; - } else { - p->plen[0] = buf[c]; - p->found++; - return count; - } - break; - case 5: - p->plen[1] = buf[c]; - c++; - p->found++; - p->plength = (p->plen[0] << 8) | p->plen[1]; - break; - case 6: - if (!p->done) { - p->flag1 = buf[c]; - c++; - p->found++; - if ((p->flag1 & 0xc0) == 0x80) - p->mpeg = 2; - else { - p->hlength = 0; - p->which = 0; - p->mpeg = 1; - p->flag2 = 0; - } - } - break; - - case 7: - if (!p->done && p->mpeg == 2) { - p->flag2 = buf[c]; - c++; - p->found++; - } - break; - - case 8: - if (!p->done && p->mpeg == 2) { - p->hlength = buf[c]; - c++; - p->found++; - } - break; - } - } - - if (c == count) - return count; - - if (!p->plength) - p->plength = MMAX_PLENGTH - 6; - - if (p->done || ((p->mpeg == 2 && p->found >= 9) || - (p->mpeg == 1 && p->found >= 7))) { - switch (p->cid) { - case AUDIO_STREAM_S ... AUDIO_STREAM_E: - case VIDEO_STREAM_S ... VIDEO_STREAM_E: - case PRIVATE_STREAM1: - if (p->mpeg == 2 && p->found == 9) { - write_ipack(p, &p->flag1, 1); - write_ipack(p, &p->flag2, 1); - write_ipack(p, &p->hlength, 1); - } - - if (p->mpeg == 1 && p->found == 7) - write_ipack(p, &p->flag1, 1); - - if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && - p->found < 14) { - while (c < count && p->found < 14) { - p->pts[p->found - 9] = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - } - if (c == count) - return count; - } - - if (p->mpeg == 1 && p->which < 2000) { - - if (p->found == 7) { - p->check = p->flag1; - p->hlength = 1; - } - - while (!p->which && c < count && - p->check == 0xff){ - p->check = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - p->hlength++; - } - - if (c == count) - return count; - - if ((p->check & 0xc0) == 0x40 && !p->which) { - p->check = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - p->hlength++; - - p->which = 1; - if (c == count) - return count; - p->check = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - p->hlength++; - p->which = 2; - if (c == count) - return count; - } - - if (p->which == 1) { - p->check = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - p->hlength++; - p->which = 2; - if (c == count) - return count; - } - - if ((p->check & 0x30) && p->check != 0xff) { - p->flag2 = (p->check & 0xf0) << 2; - p->pts[0] = p->check; - p->which = 3; - } - - if (c == count) - return count; - if (p->which > 2){ - if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) { - while (c < count && p->which < 7) { - p->pts[p->which - 2] = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - p->which++; - p->hlength++; - } - if (c == count) - return count; - } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) { - while (c < count && p->which < 12) { - if (p->which < 7) - p->pts[p->which - 2] = buf[c]; - write_ipack(p, buf + c, 1); - c++; - p->found++; - p->which++; - p->hlength++; - } - if (c == count) - return count; - } - p->which = 2000; - } - - } - - while (c < count && p->found < p->plength + 6) { - l = count - c; - if (l + p->found > p->plength + 6) - l = p->plength + 6 - p->found; - write_ipack(p, buf + c, l); - p->found += l; - c += l; - } - break; - } - - - if (p->done) { - if (p->found + count - c < p->plength + 6) { - p->found += count - c; - c = count; - } else { - c += p->plength + 6 - p->found; - p->found = p->plength + 6; - } - } - - if (p->plength && p->found == p->plength + 6) { - send_ipack(p); - av7110_ipack_reset(p); - if (c < count) - av7110_ipack_instant_repack(buf + c, count - c, p); - } - } - return count; -} diff --git a/drivers/media/dvb/ttpci/av7110_ipack.h b/drivers/media/dvb/ttpci/av7110_ipack.h deleted file mode 100644 index becf94d3fdf..00000000000 --- a/drivers/media/dvb/ttpci/av7110_ipack.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _AV7110_IPACK_H_ -#define _AV7110_IPACK_H_ - -extern int av7110_ipack_init(struct ipack *p, int size, - void (*func)(u8 *buf, int size, void *priv)); - -extern void av7110_ipack_reset(struct ipack *p); -extern int av7110_ipack_instant_repack(const u8 *buf, int count, struct ipack *p); -extern void av7110_ipack_free(struct ipack * p); -extern void av7110_ipack_flush(struct ipack *p); - -#endif diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c deleted file mode 100644 index 23a1c6380d3..00000000000 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Driver for the remote control of SAA7146 based AV7110 cards - * - * Copyright (C) 1999-2003 Holger Waechtler <holger@convergence.de> - * Copyright (C) 2003-2007 Oliver Endriss <o.endriss@gmx.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - */ - - -#include <linux/types.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/proc_fs.h> -#include <linux/kernel.h> -#include <linux/bitops.h> - -#include "av7110.h" -#include "av7110_hw.h" - - -#define AV_CNT 4 - -#define IR_RC5 0 -#define IR_RCMM 1 -#define IR_RC5_EXT 2 /* internal only */ - -#define IR_ALL 0xffffffff - -#define UP_TIMEOUT (HZ*7/25) - - -/* Note: enable ir debugging by or'ing debug with 16 */ - -static int ir_protocol[AV_CNT] = { IR_RCMM, IR_RCMM, IR_RCMM, IR_RCMM}; -module_param_array(ir_protocol, int, NULL, 0644); -MODULE_PARM_DESC(ir_protocol, "Infrared protocol: 0 RC5, 1 RCMM (default)"); - -static int ir_inversion[AV_CNT]; -module_param_array(ir_inversion, int, NULL, 0644); -MODULE_PARM_DESC(ir_inversion, "Inversion of infrared signal: 0 not inverted (default), 1 inverted"); - -static uint ir_device_mask[AV_CNT] = { IR_ALL, IR_ALL, IR_ALL, IR_ALL }; -module_param_array(ir_device_mask, uint, NULL, 0644); -MODULE_PARM_DESC(ir_device_mask, "Bitmask of infrared devices: bit 0..31 = device 0..31 (default: all)"); - - -static int av_cnt; -static struct av7110 *av_list[AV_CNT]; - -static u16 default_key_map [256] = { - KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, - KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, - KEY_VOLUMEUP, KEY_VOLUMEDOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - KEY_CHANNELUP, KEY_CHANNELDOWN, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, KEY_TEXT, 0, 0, KEY_TV, 0, 0, 0, 0, 0, KEY_SETUP, 0, 0, - 0, 0, 0, KEY_SUBTITLE, 0, 0, KEY_LANGUAGE, 0, - KEY_RADIO, 0, 0, 0, 0, KEY_EXIT, 0, 0, - KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_OK, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_RED, KEY_GREEN, KEY_YELLOW, - KEY_BLUE, 0, 0, 0, 0, 0, 0, 0, KEY_MENU, KEY_LIST, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, KEY_UP, KEY_UP, KEY_DOWN, KEY_DOWN, - 0, 0, 0, 0, KEY_EPG, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_VCR -}; - - -/* key-up timer */ -static void av7110_emit_keyup(unsigned long parm) -{ - struct infrared *ir = (struct infrared *) parm; - - if (!ir || !test_bit(ir->last_key, ir->input_dev->key)) - return; - - input_report_key(ir->input_dev, ir->last_key, 0); - input_sync(ir->input_dev); -} - - -/* tasklet */ -static void av7110_emit_key(unsigned long parm) -{ - struct infrared *ir = (struct infrared *) parm; - u32 ircom = ir->ir_command; - u8 data; - u8 addr; - u16 toggle; - u16 keycode; - - /* extract device address and data */ - switch (ir->protocol) { - case IR_RC5: /* RC5: 5 bits device address, 6 bits data */ - data = ircom & 0x3f; - addr = (ircom >> 6) & 0x1f; - toggle = ircom & 0x0800; - break; - - case IR_RCMM: /* RCMM: ? bits device address, ? bits data */ - data = ircom & 0xff; - addr = (ircom >> 8) & 0x1f; - toggle = ircom & 0x8000; - break; - - case IR_RC5_EXT: /* extended RC5: 5 bits device address, 7 bits data */ - data = ircom & 0x3f; - addr = (ircom >> 6) & 0x1f; - /* invert 7th data bit for backward compatibility with RC5 keymaps */ - if (!(ircom & 0x1000)) - data |= 0x40; - toggle = ircom & 0x0800; - break; - - default: - printk("%s invalid protocol %x\n", __func__, ir->protocol); - return; - } - - input_event(ir->input_dev, EV_MSC, MSC_RAW, (addr << 16) | data); - input_event(ir->input_dev, EV_MSC, MSC_SCAN, data); - - keycode = ir->key_map[data]; - - dprintk(16, "%s: code %08x -> addr %i data 0x%02x -> keycode %i\n", - __func__, ircom, addr, data, keycode); - - /* check device address */ - if (!(ir->device_mask & (1 << addr))) - return; - - if (!keycode) { - printk ("%s: code %08x -> addr %i data 0x%02x -> unknown key!\n", - __func__, ircom, addr, data); - return; - } - - if (timer_pending(&ir->keyup_timer)) { - del_timer(&ir->keyup_timer); - if (ir->last_key != keycode || toggle != ir->last_toggle) { - ir->delay_timer_finished = 0; - input_event(ir->input_dev, EV_KEY, ir->last_key, 0); - input_event(ir->input_dev, EV_KEY, keycode, 1); - input_sync(ir->input_dev); - } else if (ir->delay_timer_finished) { - input_event(ir->input_dev, EV_KEY, keycode, 2); - input_sync(ir->input_dev); - } - } else { - ir->delay_timer_finished = 0; - input_event(ir->input_dev, EV_KEY, keycode, 1); - input_sync(ir->input_dev); - } - - ir->last_key = keycode; - ir->last_toggle = toggle; - - ir->keyup_timer.expires = jiffies + UP_TIMEOUT; - add_timer(&ir->keyup_timer); - -} - - -/* register with input layer */ -static void input_register_keys(struct infrared *ir) -{ - int i; - - set_bit(EV_KEY, ir->input_dev->evbit); - set_bit(EV_REP, ir->input_dev->evbit); - set_bit(EV_MSC, ir->input_dev->evbit); - - set_bit(MSC_RAW, ir->input_dev->mscbit); - set_bit(MSC_SCAN, ir->input_dev->mscbit); - - memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit)); - - for (i = 0; i < ARRAY_SIZE(ir->key_map); i++) { - if (ir->key_map[i] > KEY_MAX) - ir->key_map[i] = 0; - else if (ir->key_map[i] > KEY_RESERVED) - set_bit(ir->key_map[i], ir->input_dev->keybit); - } - - ir->input_dev->keycode = ir->key_map; - ir->input_dev->keycodesize = sizeof(ir->key_map[0]); - ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map); -} - - -/* called by the input driver after rep[REP_DELAY] ms */ -static void input_repeat_key(unsigned long parm) -{ - struct infrared *ir = (struct infrared *) parm; - - ir->delay_timer_finished = 1; -} - - -/* check for configuration changes */ -int av7110_check_ir_config(struct av7110 *av7110, int force) -{ - int i; - int modified = force; - int ret = -ENODEV; - - for (i = 0; i < av_cnt; i++) - if (av7110 == av_list[i]) - break; - - if (i < av_cnt && av7110) { - if ((av7110->ir.protocol & 1) != ir_protocol[i] || - av7110->ir.inversion != ir_inversion[i]) - modified = true; - - if (modified) { - /* protocol */ - if (ir_protocol[i]) { - ir_protocol[i] = 1; - av7110->ir.protocol = IR_RCMM; - av7110->ir.ir_config = 0x0001; - } else if (FW_VERSION(av7110->arm_app) >= 0x2620) { - av7110->ir.protocol = IR_RC5_EXT; - av7110->ir.ir_config = 0x0002; - } else { - av7110->ir.protocol = IR_RC5; - av7110->ir.ir_config = 0x0000; - } - /* inversion */ - if (ir_inversion[i]) { - ir_inversion[i] = 1; - av7110->ir.ir_config |= 0x8000; - } - av7110->ir.inversion = ir_inversion[i]; - /* update ARM */ - ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, - av7110->ir.ir_config); - } else - ret = 0; - - /* address */ - if (av7110->ir.device_mask != ir_device_mask[i]) - av7110->ir.device_mask = ir_device_mask[i]; - } - - return ret; -} - - -/* /proc/av7110_ir interface */ -static int av7110_ir_write_proc(struct file *file, const char __user *buffer, - unsigned long count, void *data) -{ - char *page; - u32 ir_config; - int size = sizeof ir_config + sizeof av_list[0]->ir.key_map; - int i; - - if (count < size) - return -EINVAL; - - page = vmalloc(size); - if (!page) - return -ENOMEM; - - if (copy_from_user(page, buffer, size)) { - vfree(page); - return -EFAULT; - } - - memcpy(&ir_config, page, sizeof ir_config); - - for (i = 0; i < av_cnt; i++) { - /* keymap */ - memcpy(av_list[i]->ir.key_map, page + sizeof ir_config, - sizeof(av_list[i]->ir.key_map)); - /* protocol, inversion, address */ - ir_protocol[i] = ir_config & 0x0001; - ir_inversion[i] = ir_config & 0x8000 ? 1 : 0; - if (ir_config & 0x4000) - ir_device_mask[i] = 1 << ((ir_config >> 16) & 0x1f); - else - ir_device_mask[i] = IR_ALL; - /* update configuration */ - av7110_check_ir_config(av_list[i], false); - input_register_keys(&av_list[i]->ir); - } - vfree(page); - return count; -} - - -/* interrupt handler */ -static void ir_handler(struct av7110 *av7110, u32 ircom) -{ - dprintk(4, "ir command = %08x\n", ircom); - av7110->ir.ir_command = ircom; - tasklet_schedule(&av7110->ir.ir_tasklet); -} - - -int __devinit av7110_ir_init(struct av7110 *av7110) -{ - struct input_dev *input_dev; - static struct proc_dir_entry *e; - int err; - - if (av_cnt >= ARRAY_SIZE(av_list)) - return -ENOSPC; - - av_list[av_cnt++] = av7110; - av7110_check_ir_config(av7110, true); - - init_timer(&av7110->ir.keyup_timer); - av7110->ir.keyup_timer.function = av7110_emit_keyup; - av7110->ir.keyup_timer.data = (unsigned long) &av7110->ir; - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - av7110->ir.input_dev = input_dev; - snprintf(av7110->ir.input_phys, sizeof(av7110->ir.input_phys), - "pci-%s/ir0", pci_name(av7110->dev->pci)); - - input_dev->name = "DVB on-card IR receiver"; - - input_dev->phys = av7110->ir.input_phys; - input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 2; - if (av7110->dev->pci->subsystem_vendor) { - input_dev->id.vendor = av7110->dev->pci->subsystem_vendor; - input_dev->id.product = av7110->dev->pci->subsystem_device; - } else { - input_dev->id.vendor = av7110->dev->pci->vendor; - input_dev->id.product = av7110->dev->pci->device; - } - input_dev->dev.parent = &av7110->dev->pci->dev; - /* initial keymap */ - memcpy(av7110->ir.key_map, default_key_map, sizeof av7110->ir.key_map); - input_register_keys(&av7110->ir); - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; - } - input_dev->timer.function = input_repeat_key; - input_dev->timer.data = (unsigned long) &av7110->ir; - - if (av_cnt == 1) { - e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL); - if (e) { - e->write_proc = av7110_ir_write_proc; - e->size = 4 + 256 * sizeof(u16); - } - } - - tasklet_init(&av7110->ir.ir_tasklet, av7110_emit_key, (unsigned long) &av7110->ir); - av7110->ir.ir_handler = ir_handler; - - return 0; -} - - -void __devexit av7110_ir_exit(struct av7110 *av7110) -{ - int i; - - if (av_cnt == 0) - return; - - del_timer_sync(&av7110->ir.keyup_timer); - av7110->ir.ir_handler = NULL; - tasklet_kill(&av7110->ir.ir_tasklet); - - for (i = 0; i < av_cnt; i++) - if (av_list[i] == av7110) { - av_list[i] = av_list[av_cnt-1]; - av_list[av_cnt-1] = NULL; - break; - } - - if (av_cnt == 1) - remove_proc_entry("av7110_ir", NULL); - - input_unregister_device(av7110->ir.input_dev); - - av_cnt--; -} - -//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>, Oliver Endriss <o.endriss@gmx.de>"); -//MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c deleted file mode 100644 index c5b9c70563d..00000000000 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ /dev/null @@ -1,928 +0,0 @@ -/* - * av7110_v4l.c: av7110 video4linux interface for DVB and Siemens DVB-C analog module - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * originally based on code by: - * Copyright (C) 1998,1999 Christian Theiss <mistert@rz.fh-augsburg.de> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/delay.h> -#include <linux/fs.h> -#include <linux/timer.h> -#include <linux/poll.h> - -#include "av7110.h" -#include "av7110_hw.h" -#include "av7110_av.h" - -int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) -{ - u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; - struct i2c_msg msgs = { .flags = 0, .len = 5, .buf = msg }; - - switch (av7110->adac_type) { - case DVB_ADAC_MSP34x0: - msgs.addr = 0x40; - break; - case DVB_ADAC_MSP34x5: - msgs.addr = 0x42; - break; - default: - return 0; - } - - if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { - dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", - av7110->dvb_adapter.num, reg, val); - return -EIO; - } - return 0; -} - -static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) -{ - u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; - u8 msg2[2]; - struct i2c_msg msgs[2] = { - { .flags = 0 , .len = 3, .buf = msg1 }, - { .flags = I2C_M_RD, .len = 2, .buf = msg2 } - }; - - switch (av7110->adac_type) { - case DVB_ADAC_MSP34x0: - msgs[0].addr = 0x40; - msgs[1].addr = 0x40; - break; - case DVB_ADAC_MSP34x5: - msgs[0].addr = 0x42; - msgs[1].addr = 0x42; - break; - default: - return 0; - } - - if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { - dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", - av7110->dvb_adapter.num, reg); - return -EIO; - } - *val = (msg2[0] << 8) | msg2[1]; - return 0; -} - -static struct v4l2_input inputs[4] = { - { - .index = 0, - .name = "DVB", - .type = V4L2_INPUT_TYPE_CAMERA, - .audioset = 1, - .tuner = 0, /* ignored */ - .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, - .status = 0, - }, { - .index = 1, - .name = "Television", - .type = V4L2_INPUT_TYPE_TUNER, - .audioset = 2, - .tuner = 0, - .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, - .status = 0, - }, { - .index = 2, - .name = "Video", - .type = V4L2_INPUT_TYPE_CAMERA, - .audioset = 0, - .tuner = 0, - .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, - .status = 0, - }, { - .index = 3, - .name = "Y/C", - .type = V4L2_INPUT_TYPE_CAMERA, - .audioset = 0, - .tuner = 0, - .std = V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, - .status = 0, - } -}; - -static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) -{ - struct av7110 *av7110 = dev->ext_priv; - u8 buf[] = { 0x00, reg, data }; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; - - dprintk(4, "dev: %p\n", dev); - - if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1)) - return -1; - return 0; -} - -static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) -{ - struct av7110 *av7110 = dev->ext_priv; - struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; - - dprintk(4, "dev: %p\n", dev); - - if (1 != i2c_transfer(&av7110->i2c_adap, &msg, 1)) - return -1; - return 0; -} - -static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq) -{ - u32 div; - u8 config; - u8 buf[4]; - - dprintk(4, "freq: 0x%08x\n", freq); - - /* magic number: 614. tuning with the frequency given by v4l2 - is always off by 614*62.5 = 38375 kHz...*/ - div = freq + 614; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x8e; - - if (freq < (u32) (16 * 168.25)) - config = 0xa0; - else if (freq < (u32) (16 * 447.25)) - config = 0x90; - else - config = 0x30; - config &= ~0x02; - - buf[3] = config; - - return tuner_write(dev, 0x61, buf); -} - -static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) -{ - struct av7110 *av7110 = (struct av7110*)dev->ext_priv; - u32 div; - u8 data[4]; - - div = (freq + 38900000 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0xce; - - if (freq < 45000000) - return -EINVAL; - else if (freq < 137000000) - data[3] = 0x01; - else if (freq < 403000000) - data[3] = 0x02; - else if (freq < 860000000) - data[3] = 0x04; - else - return -EINVAL; - - if (av7110->fe->ops.i2c_gate_ctrl) - av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1); - return tuner_write(dev, 0x63, data); -} - - - -static struct saa7146_standard analog_standard[]; -static struct saa7146_standard dvb_standard[]; -static struct saa7146_standard standard[]; - -static struct v4l2_audio msp3400_v4l2_audio = { - .index = 0, - .name = "Television", - .capability = V4L2_AUDCAP_STEREO -}; - -static int av7110_dvb_c_switch(struct saa7146_fh *fh) -{ - struct saa7146_dev *dev = fh->dev; - struct saa7146_vv *vv = dev->vv_data; - struct av7110 *av7110 = (struct av7110*)dev->ext_priv; - u16 adswitch; - int source, sync, err; - - dprintk(4, "%p\n", av7110); - - if ((vv->video_status & STATUS_OVERLAY) != 0) { - vv->ov_suspend = vv->video_fh; - err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ - if (err != 0) { - dprintk(2, "suspending video failed\n"); - vv->ov_suspend = NULL; - } - } - - if (0 != av7110->current_input) { - dprintk(1, "switching to analog TV:\n"); - adswitch = 1; - source = SAA7146_HPS_SOURCE_PORT_B; - sync = SAA7146_HPS_SYNC_PORT_B; - memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2); - - switch (av7110->current_input) { - case 1: - 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 - msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume - - if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { - if (ves1820_writereg(dev, 0x09, 0x0f, 0x60)) - 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) - } - if (i2c_writereg(av7110, 0x48, 0x02, 0xd0) != 1) - dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); - break; - case 2: - 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"); - 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"); - } - } else { - adswitch = 0; - source = SAA7146_HPS_SOURCE_PORT_A; - sync = SAA7146_HPS_SYNC_PORT_A; - memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2); - dprintk(1, "switching DVB mode\n"); - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source - msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source - msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source - msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume - - if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { - if (ves1820_writereg(dev, 0x09, 0x0f, 0x20)) - 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) - } - } - - /* hmm, this does not do anything!? */ - if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch)) - dprintk(1, "ADSwitch error\n"); - - saa7146_set_hps_source_and_sync(dev, source, sync); - - if (vv->ov_suspend != NULL) { - saa7146_start_preview(vv->ov_suspend); - vv->ov_suspend = NULL; - } - - return 0; -} - -static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) -{ - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - dprintk(4, "saa7146_dev: %p\n", dev); - - switch (cmd) { - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *t = arg; - u16 stereo_det; - s8 stereo; - - dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index); - - if (!av7110->analog_tuner_flags || t->index != 0) - return -EINVAL; - - memset(t, 0, sizeof(*t)); - strcpy((char *)t->name, "Television"); - - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */ - t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */ - /* FIXME: add the real signal strength here */ - t->signal = 0xffff; - t->afc = 0; - - // FIXME: standard / stereo detection is still broken - msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det); - dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det); - msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det); - dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det); - stereo = (s8)(stereo_det >> 8); - if (stereo > 0x10) { - /* stereo */ - t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; - t->audmode = V4L2_TUNER_MODE_STEREO; - } - else if (stereo < -0x10) { - /* bilingual */ - t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - t->audmode = V4L2_TUNER_MODE_LANG1; - } - else /* mono */ - t->rxsubchans = V4L2_TUNER_SUB_MONO; - - return 0; - } - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *t = arg; - u16 fm_matrix, src; - dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index); - - if (!av7110->analog_tuner_flags || av7110->current_input != 1) - return -EINVAL; - - switch (t->audmode) { - case V4L2_TUNER_MODE_STEREO: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n"); - fm_matrix = 0x3001; // stereo - src = 0x0020; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1_LANG2\n"); - fm_matrix = 0x3000; // bilingual - src = 0x0020; - break; - case V4L2_TUNER_MODE_LANG1: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG1\n"); - fm_matrix = 0x3000; // mono - src = 0x0000; - break; - case V4L2_TUNER_MODE_LANG2: - dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n"); - fm_matrix = 0x3000; // mono - src = 0x0010; - break; - default: /* case V4L2_TUNER_MODE_MONO: */ - dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n"); - fm_matrix = 0x3000; // mono - src = 0x0030; - break; - } - msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix); - msp_writereg(av7110, MSP_WR_DSP, 0x0008, src); - msp_writereg(av7110, MSP_WR_DSP, 0x0009, src); - msp_writereg(av7110, MSP_WR_DSP, 0x000a, src); - return 0; - } - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency); - - if (!av7110->analog_tuner_flags || av7110->current_input != 1) - return -EINVAL; - - memset(f, 0, sizeof(*f)); - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = av7110->current_freq; - return 0; - } - case VIDIOC_S_FREQUENCY: - { - struct v4l2_frequency *f = arg; - - dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency); - - if (!av7110->analog_tuner_flags || av7110->current_input != 1) - return -EINVAL; - - if (V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; - - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); - - /* tune in desired frequency */ - if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { - ves1820_set_tv_freq(dev, f->frequency); - } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { - stv0297_set_tv_freq(dev, f->frequency); - } - av7110->current_freq = f->frequency; - - msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection - msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume - return 0; - } - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - - dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); - - if (av7110->analog_tuner_flags) { - if (i->index < 0 || i->index >= 4) - return -EINVAL; - } else { - if (i->index != 0) - return -EINVAL; - } - - memcpy(i, &inputs[i->index], sizeof(struct v4l2_input)); - - return 0; - } - case VIDIOC_G_INPUT: - { - int *input = (int *)arg; - *input = av7110->current_input; - dprintk(2, "VIDIOC_G_INPUT: %d\n", *input); - return 0; - } - case VIDIOC_S_INPUT: - { - int input = *(int *)arg; - - dprintk(2, "VIDIOC_S_INPUT: %d\n", input); - - if (!av7110->analog_tuner_flags) - return 0; - - if (input < 0 || input >= 4) - return -EINVAL; - - av7110->current_input = input; - return av7110_dvb_c_switch(fh); - } - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; - - dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index); - if (a->index != 0) - return -EINVAL; - memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio)); - break; - } - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *a = arg; - dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); - break; - } - case VIDIOC_G_SLICED_VBI_CAP: - { - struct v4l2_sliced_vbi_cap *cap = arg; - dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); - memset(cap, 0, sizeof *cap); - if (FW_VERSION(av7110->arm_app) >= 0x2623) { - cap->service_set = V4L2_SLICED_WSS_625; - cap->service_lines[0][23] = V4L2_SLICED_WSS_625; - } - break; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - dprintk(2, "VIDIOC_G_FMT:\n"); - if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || - FW_VERSION(av7110->arm_app) < 0x2623) - return -EAGAIN; /* handled by core driver */ - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - if (av7110->wssMode) { - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); - } - break; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - dprintk(2, "VIDIOC_S_FMT\n"); - if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || - FW_VERSION(av7110->arm_app) < 0x2623) - return -EAGAIN; /* handled by core driver */ - if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && - f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - /* WSS controlled by firmware */ - av7110->wssMode = 0; - av7110->wssData = 0; - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, - SetWSSConfig, 1, 0); - } else { - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); - /* WSS controlled by userspace */ - av7110->wssMode = 1; - av7110->wssData = 0; - } - break; - } - default: - printk("no such ioctl\n"); - return -ENOIOCTLCMD; - } - return 0; -} - -static int av7110_vbi_reset(struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - - dprintk(2, "%s\n", __func__); - av7110->wssMode = 0; - av7110->wssData = 0; - if (FW_VERSION(av7110->arm_app) < 0x2623) - return 0; - else - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); -} - -static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - struct v4l2_sliced_vbi_data d; - int rc; - - dprintk(2, "%s\n", __func__); - if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d) - return -EINVAL; - if (copy_from_user(&d, data, count)) - return -EFAULT; - if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) - return -EINVAL; - if (d.id) - av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; - else - av7110->wssData = 0x8000; - rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 2, 1, av7110->wssData); - return (rc < 0) ? rc : count; -} - -/**************************************************************************** - * INITIALIZATION - ****************************************************************************/ - -static struct saa7146_extension_ioctls ioctls[] = { - { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE }, - { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE }, - { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE }, - { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, - { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, - { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, - { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE }, - { VIDIOC_G_FMT, SAA7146_BEFORE }, - { VIDIOC_S_FMT, SAA7146_BEFORE }, - { 0, 0 } -}; - -static u8 saa7113_init_regs[] = { - 0x02, 0xd0, - 0x03, 0x23, - 0x04, 0x00, - 0x05, 0x00, - 0x06, 0xe9, - 0x07, 0x0d, - 0x08, 0x98, - 0x09, 0x02, - 0x0a, 0x80, - 0x0b, 0x40, - 0x0c, 0x40, - 0x0d, 0x00, - 0x0e, 0x01, - 0x0f, 0x7c, - 0x10, 0x48, - 0x11, 0x0c, - 0x12, 0x8b, - 0x13, 0x1a, - 0x14, 0x00, - 0x15, 0x00, - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1b, 0x00, - 0x1c, 0x00, - 0x1d, 0x00, - 0x1e, 0x00, - - 0x41, 0x77, - 0x42, 0x77, - 0x43, 0x77, - 0x44, 0x77, - 0x45, 0x77, - 0x46, 0x77, - 0x47, 0x77, - 0x48, 0x77, - 0x49, 0x77, - 0x4a, 0x77, - 0x4b, 0x77, - 0x4c, 0x77, - 0x4d, 0x77, - 0x4e, 0x77, - 0x4f, 0x77, - 0x50, 0x77, - 0x51, 0x77, - 0x52, 0x77, - 0x53, 0x77, - 0x54, 0x77, - 0x55, 0x77, - 0x56, 0x77, - 0x57, 0xff, - - 0xff -}; - - -static struct saa7146_ext_vv av7110_vv_data_st; -static struct saa7146_ext_vv av7110_vv_data_c; - -int av7110_init_analog_module(struct av7110 *av7110) -{ - u16 version1, version2; - - 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", - 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", - av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_MSP34x5; - } else - return -ENODEV; - - msleep(100); // the probing above resets the msp... - msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); - msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); - dprintk(1, "dvb-ttpci: @ card %d MSP34xx version 0x%04x 0x%04x\n", - av7110->dvb_adapter.num, version1, version2); - msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); - msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone - msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source - msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0220); // headphone source - msp_writereg(av7110, MSP_WR_DSP, 0x0004, 0x7f00); // loudspeaker volume - msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0220); // SCART 1 source - msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume - msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART - - if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { - INFO(("saa7113 not accessible.\n")); - } else { - u8 *i = saa7113_init_regs; - - if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { - /* Fujitsu/Siemens DVB-Cable */ - av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820; - } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) { - /* Hauppauge/TT DVB-C premium */ - av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820; - } else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) { - /* Hauppauge/TT DVB-C premium */ - av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297; - } - - /* 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"); - } 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) - } - - /* init the saa7113 */ - while (*i != 0xff) { - if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) { - dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num); - break; - } - i += 2; - } - /* setup msp for analog sound: B/G Dual-FM */ - msp_writereg(av7110, MSP_WR_DEM, 0x00bb, 0x02d0); // AD_CV - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 3); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 18); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 27); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 48); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 66); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0001, 72); // FIR1 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 4); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 64); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 0); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 3); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 18); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 27); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 48); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 66); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0005, 72); // FIR2 - msp_writereg(av7110, MSP_WR_DEM, 0x0083, 0xa000); // MODE_REG - msp_writereg(av7110, MSP_WR_DEM, 0x0093, 0x00aa); // DCO1_LO 5.74MHz - msp_writereg(av7110, MSP_WR_DEM, 0x009b, 0x04fc); // DCO1_HI - msp_writereg(av7110, MSP_WR_DEM, 0x00a3, 0x038e); // DCO2_LO 5.5MHz - msp_writereg(av7110, MSP_WR_DEM, 0x00ab, 0x04c6); // DCO2_HI - msp_writereg(av7110, MSP_WR_DEM, 0x0056, 0); // LOAD_REG 1/2 - } - - memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2); - /* set dd1 stream a & b */ - saa7146_write(av7110->dev, DD1_STREAM_B, 0x00000000); - saa7146_write(av7110->dev, DD1_INIT, 0x03000700); - saa7146_write(av7110->dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - return 0; -} - -int av7110_init_v4l(struct av7110 *av7110) -{ - struct saa7146_dev* dev = av7110->dev; - int ret; - - /* special case DVB-C: these cards have an analog tuner - plus need some special handling, so we have separate - saa7146_ext_vv data for these... */ - if (av7110->analog_tuner_flags) - ret = saa7146_vv_init(dev, &av7110_vv_data_c); - else - ret = saa7146_vv_init(dev, &av7110_vv_data_st); - - if (ret) { - ERR(("cannot init capture device. skipping.\n")); - return -ENODEV; - } - - if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { - 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")); - return 0; -} - -int av7110_exit_v4l(struct av7110 *av7110) -{ - struct saa7146_dev* dev = av7110->dev; - - saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); - saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); - - saa7146_vv_release(dev); - - return 0; -} - - - -/* FIXME: these values are experimental values that look better than the - values from the latest "official" driver -- at least for me... (MiHu) */ -static struct saa7146_standard standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL_BG, - .v_offset = 0x15, .v_field = 288, - .h_offset = 0x48, .h_pixels = 708, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x10, .v_field = 244, - .h_offset = 0x40, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - } -}; - -static struct saa7146_standard analog_standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL_BG, - .v_offset = 0x1b, .v_field = 288, - .h_offset = 0x08, .h_pixels = 708, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x10, .v_field = 244, - .h_offset = 0x40, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - } -}; - -static struct saa7146_standard dvb_standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL_BG, - .v_offset = 0x14, .v_field = 288, - .h_offset = 0x48, .h_pixels = 708, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x10, .v_field = 244, - .h_offset = 0x40, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - } -}; - -static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) -{ - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - - if (std->id & V4L2_STD_PAL) { - av7110->vidmode = AV7110_VIDEO_MODE_PAL; - av7110_set_vidmode(av7110, av7110->vidmode); - } - else if (std->id & V4L2_STD_NTSC) { - av7110->vidmode = AV7110_VIDEO_MODE_NTSC; - av7110_set_vidmode(av7110, av7110->vidmode); - } - else - return -1; - - return 0; -} - - -static struct saa7146_ext_vv av7110_vv_data_st = { - .inputs = 1, - .audios = 1, - .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT, - .flags = 0, - - .stds = &standard[0], - .num_stds = ARRAY_SIZE(standard), - .std_callback = &std_callback, - - .ioctls = &ioctls[0], - .ioctl = av7110_ioctl, - - .vbi_fops.open = av7110_vbi_reset, - .vbi_fops.release = av7110_vbi_reset, - .vbi_fops.write = av7110_vbi_write, -}; - -static struct saa7146_ext_vv av7110_vv_data_c = { - .inputs = 1, - .audios = 1, - .capabilities = V4L2_CAP_TUNER | V4L2_CAP_SLICED_VBI_OUTPUT, - .flags = SAA7146_USE_PORT_B_FOR_VBI, - - .stds = &standard[0], - .num_stds = ARRAY_SIZE(standard), - .std_callback = &std_callback, - - .ioctls = &ioctls[0], - .ioctl = av7110_ioctl, - - .vbi_fops.open = av7110_vbi_reset, - .vbi_fops.release = av7110_vbi_reset, - .vbi_fops.write = av7110_vbi_write, -}; - diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c deleted file mode 100644 index 4182121d7e5..00000000000 --- a/drivers/media/dvb/ttpci/budget-av.c +++ /dev/null @@ -1,1645 +0,0 @@ -/* - * budget-av.c: driver for the SAA7146 based Budget DVB cards - * with analog video in - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & - * Andrew de Quincey <adq_dvb@lidskialf.net> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include "budget.h" -#include "stv0299.h" -#include "stb0899_drv.h" -#include "stb0899_reg.h" -#include "stb0899_cfg.h" -#include "tda8261.h" -#include "tda8261_cfg.h" -#include "tda1002x.h" -#include "tda1004x.h" -#include "tua6100.h" -#include "dvb-pll.h" -#include <media/saa7146_vv.h> -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/spinlock.h> - -#include "dvb_ca_en50221.h" - -#define DEBICICAM 0x02420000 - -#define SLOTSTATUS_NONE 1 -#define SLOTSTATUS_PRESENT 2 -#define SLOTSTATUS_RESET 4 -#define SLOTSTATUS_READY 8 -#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct budget_av { - struct budget budget; - struct video_device *vd; - int cur_input; - int has_saa7113; - struct tasklet_struct ciintf_irq_tasklet; - int slot_status; - struct dvb_ca_en50221 ca; - u8 reinitialise_demod:1; -}; - -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); - - -/* GPIO Connections: - * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! - * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory - * 2 - CI Card Enable (Active Low) - * 3 - CI Card Detect - */ - -/**************************************************************************** - * INITIALIZATION - ****************************************************************************/ - -static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg) -{ - u8 mm1[] = { 0x00 }; - u8 mm2[] = { 0x00 }; - struct i2c_msg msgs[2]; - - msgs[0].flags = 0; - msgs[1].flags = I2C_M_RD; - msgs[0].addr = msgs[1].addr = id / 2; - mm1[0] = reg; - msgs[0].len = 1; - msgs[1].len = 1; - msgs[0].buf = mm1; - msgs[1].buf = mm2; - - i2c_transfer(i2c, msgs, 2); - - return mm2[0]; -} - -static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len) -{ - u8 mm1[] = { reg }; - struct i2c_msg msgs[2] = { - {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1}, - {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len} - }; - - if (i2c_transfer(i2c, msgs, 2) != 2) - return -EIO; - - return 0; -} - -static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val) -{ - u8 msg[2] = { reg, val }; - struct i2c_msg msgs; - - msgs.flags = 0; - msgs.addr = id / 2; - msgs.len = 2; - msgs.buf = msg; - return i2c_transfer(i2c, &msgs, 1); -} - -static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); - udelay(1); - - 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"); - } - return result; -} - -static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); - udelay(1); - - 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"); - } - return result; -} - -static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - udelay(1); - - 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"); - return -ETIMEDOUT; - } - return result; -} - -static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - int result; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - udelay(1); - - 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"); - } - return result; -} - -static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - - if (slot != 0) - return -EINVAL; - - dprintk(1, "ciintf_slot_reset\n"); - budget_av->slot_status = SLOTSTATUS_RESET; - - saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ - - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ - msleep(2); - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */ - msleep(20); /* 20 ms Vcc settling time */ - - saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - msleep(20); - - /* reinitialise the frontend if necessary */ - if (budget_av->reinitialise_demod) - dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); - - return 0; -} - -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - - if (slot != 0) - return -EINVAL; - - dprintk(1, "ciintf_slot_shutdown\n"); - - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - budget_av->slot_status = SLOTSTATUS_NONE; - - return 0; -} - -static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - - if (slot != 0) - return -EINVAL; - - dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); - - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); - - return 0; -} - -static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) -{ - struct budget_av *budget_av = (struct budget_av *) ca->data; - struct saa7146_dev *saa = budget_av->budget.dev; - int result; - - if (slot != 0) - return -EINVAL; - - /* test the card detect line - needs to be done carefully - * since it never goes high for some CAMs on this interface (e.g. topuptv) */ - if (budget_av->slot_status == SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - udelay(1); - 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"); - } - } - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - } - - /* We also try and read from IO memory to work round the above detection bug. If - * there is no CAM, we will get a timeout. Only done if there is no cam - * present, since this test actually breaks some cams :( - * - * if the CI interface is not open, we also do the above test since we - * don't care if the cam has problems - we'll be resetting it on open() anyway */ - if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - 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"); - } 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"); - return 0; - } - } - } - - /* read from attribute memory in reset/ready state to know when the CAM is ready */ - if (budget_av->slot_status == SLOTSTATUS_RESET) { - result = ciintf_read_attribute_mem(ca, slot, 0); - if (result == 0x1d) { - budget_av->slot_status = SLOTSTATUS_READY; - } - } - - /* work out correct return code */ - if (budget_av->slot_status != SLOTSTATUS_NONE) { - if (budget_av->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } - return DVB_CA_EN50221_POLL_CAM_PRESENT; - } - return 0; -} - -static int ciintf_init(struct budget_av *budget_av) -{ - struct saa7146_dev *saa = budget_av->budget.dev; - int result; - - memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); - - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); - saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - - /* Enable DEBI pins */ - saa7146_write(saa, MC1, MASK_27 | MASK_11); - - /* register CI interface */ - budget_av->ca.owner = THIS_MODULE; - budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem; - budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem; - budget_av->ca.read_cam_control = ciintf_read_cam_control; - budget_av->ca.write_cam_control = ciintf_write_cam_control; - budget_av->ca.slot_reset = ciintf_slot_reset; - budget_av->ca.slot_shutdown = ciintf_slot_shutdown; - budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; - budget_av->ca.poll_slot_status = ciintf_poll_slot_status; - budget_av->ca.data = budget_av; - budget_av->budget.ci_present = 1; - budget_av->slot_status = SLOTSTATUS_NONE; - - 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"); - goto error; - } - - printk(KERN_INFO "budget-av: ci interface initialised.\n"); - return 0; - -error: - saa7146_write(saa, MC1, MASK_27); - return result; -} - -static void ciintf_deinit(struct budget_av *budget_av) -{ - struct saa7146_dev *saa = budget_av->budget.dev; - - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); - saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - - /* release the CA device */ - dvb_ca_en50221_release(&budget_av->ca); - - /* disable DEBI pins */ - saa7146_write(saa, MC1, MASK_27); -} - - -static const u8 saa7113_tab[] = { - 0x01, 0x08, - 0x02, 0xc0, - 0x03, 0x33, - 0x04, 0x00, - 0x05, 0x00, - 0x06, 0xeb, - 0x07, 0xe0, - 0x08, 0x28, - 0x09, 0x00, - 0x0a, 0x80, - 0x0b, 0x47, - 0x0c, 0x40, - 0x0d, 0x00, - 0x0e, 0x01, - 0x0f, 0x44, - - 0x10, 0x08, - 0x11, 0x0c, - 0x12, 0x7b, - 0x13, 0x00, - 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, - - 0x57, 0xff, - 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07, - 0x5b, 0x83, 0x5e, 0x00, - 0xff -}; - -static int saa7113_init(struct budget_av *budget_av) -{ - struct budget *budget = &budget_av->budget; - struct saa7146_dev *saa = budget->dev; - const u8 *data = saa7113_tab; - - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); - msleep(200); - - if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { - dprintk(1, "saa7113 not found on KNC card\n"); - return -ENODEV; - } - - dprintk(1, "saa7113 detected and initializing\n"); - - while (*data != 0xff) { - i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1)); - data += 2; - } - - dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f)); - - return 0; -} - -static int saa7113_setinput(struct budget_av *budget_av, int input) -{ - struct budget *budget = &budget_av->budget; - - if (1 != budget_av->has_saa7113) - return -ENODEV; - - if (input == 1) { - i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7); - i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80); - } else if (input == 0) { - i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0); - i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00); - } else - return -EINVAL; - - budget_av->cur_input = input; - return 0; -} - - -static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - u8 m1; - - aclk = 0xb5; - if (srate < 2000000) - bclk = 0x86; - else if (srate < 5000000) - bclk = 0x89; - else if (srate < 15000000) - bclk = 0x8f; - else if (srate < 45000000) - bclk = 0x95; - - m1 = 0x14; - if (srate < 4000000) - m1 = 0x10; - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - stv0299_writereg(fe, 0x0f, 0x80 | m1); - - return 0; -} - -static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - u32 div; - u8 buf[4]; - struct budget *budget = (struct budget *) fe->dvb->priv; - struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - buf[3] = 0x20; - - if (params->u.qpsk.symbol_rate < 4000000) - buf[3] |= 1; - - if (params->frequency < 1250000) - buf[3] |= 0; - else if (params->frequency < 1550000) - buf[3] |= 0x40; - else if (params->frequency < 2050000) - buf[3] |= 0x80; - else if (params->frequency < 2150000) - buf[3] |= 0xC0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static u8 typhoon_cinergy1200s_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x92, - 0xff, 0xff -}; - -static struct stv0299_config typhoon_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, -}; - - -static struct stv0299_config cinergy_1200s_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_0, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, -}; - -static struct stv0299_config cinergy_1200s_1894_0010_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, -}; - -static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - u8 buf[6]; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; - int i; - -#define CU1216_IF 36125000 -#define TUNER_MUL 62500 - - u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0xce; - buf[3] = (params->frequency < 150000000 ? 0x01 : - params->frequency < 445000000 ? 0x02 : 0x04); - buf[4] = 0xde; - buf[5] = 0x20; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - - /* wait for the pll lock */ - msg.flags = I2C_M_RD; - msg.len = 1; - for (i = 0; i < 20; i++) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40)) - break; - msleep(10); - } - - /* switch the charge pump to the lower current */ - msg.flags = 0; - msg.len = 2; - msg.buf = &buf[2]; - buf[2] &= ~0x40; - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - - return 0; -} - -static struct tda1002x_config philips_cu1216_config = { - .demod_address = 0x0c, - .invert = 1, -}; - -static struct tda1002x_config philips_cu1216_config_altaddress = { - .demod_address = 0x0d, - .invert = 0, -}; - -static struct tda10023_config philips_cu1216_tda10023_config = { - .demod_address = 0x0c, - .invert = 1, -}; - -static int philips_tu1216_tuner_init(struct dvb_frontend *fe) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; - struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; - - // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - msleep(1); - - return 0; -} - -static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = - sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = params->frequency + 36166000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) - cp = 3; - else if (tuner_frequency < 160000000) - cp = 5; - else if (tuner_frequency < 200000000) - cp = 6; - else if (tuner_frequency < 290000000) - cp = 3; - else if (tuner_frequency < 420000000) - cp = 5; - else if (tuner_frequency < 480000000) - cp = 6; - else if (tuner_frequency < 620000000) - cp = 3; - else if (tuner_frequency < 830000000) - cp = 5; - else if (tuner_frequency < 895000000) - cp = 7; - else - return -EINVAL; - - // determine band - if (params->frequency < 49000000) - return -EINVAL; - else if (params->frequency < 161000000) - band = 1; - else if (params->frequency < 444000000) - band = 2; - else if (params->frequency < 861000000) - band = 4; - else - return -EINVAL; - - // setup PLL filter - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: - filter = 0; - break; - - case BANDWIDTH_7_MHZ: - filter = 0; - break; - - case BANDWIDTH_8_MHZ: - filter = 1; - break; - - default: - return -EINVAL; - } - - // calculate divisor - // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000; - - // setup tuner buffer - tuner_buf[0] = (tuner_frequency >> 8) & 0x7f; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xca; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - return 0; -} - -static int philips_tu1216_request_firmware(struct dvb_frontend *fe, - const struct firmware **fw, char *name) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - - return request_firmware(fw, name, &budget->dev->pci->dev); -} - -static struct tda1004x_config philips_tu1216_config = { - - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 1, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tu1216_request_firmware, -}; - -static u8 philips_sd1878_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, - 0x05, 0x35, - 0x06, 0x40, - 0x07, 0x00, - 0x08, 0x43, - 0x09, 0x02, - 0x0C, 0x51, - 0x0D, 0x82, - 0x0E, 0x23, - 0x10, 0x3f, - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, - 0x16, 0x19, - 0x17, 0x8c, - 0x18, 0x59, - 0x19, 0xf8, - 0x1a, 0xfe, - 0x1c, 0x7f, - 0x1d, 0x00, - 0x1e, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, - 0x29, 0x28, - 0x2a, 0x14, - 0x2b, 0x0f, - 0x2c, 0x09, - 0x2d, 0x09, - 0x31, 0x1f, - 0x32, 0x19, - 0x33, 0xfc, - 0x34, 0x93, - 0xff, 0xff -}; - -static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, - u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - u8 m1; - - aclk = 0xb5; - if (srate < 2000000) - bclk = 0x86; - else if (srate < 5000000) - bclk = 0x89; - else if (srate < 15000000) - bclk = 0x8f; - else if (srate < 45000000) - bclk = 0x95; - - m1 = 0x14; - if (srate < 4000000) - m1 = 0x10; - - stv0299_writereg(fe, 0x0e, 0x23); - stv0299_writereg(fe, 0x0f, 0x94); - stv0299_writereg(fe, 0x10, 0x39); - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x15, 0xc9); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - stv0299_writereg(fe, 0x0f, 0x80 | m1); - - return 0; -} - -static struct stv0299_config philips_sd1878_config = { - .demod_address = 0x68, - .inittab = philips_sd1878_inittab, - .mclk = 88000000UL, - .invert = 0, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_sd1878_ci_set_symbol_rate, -}; - -/* KNC1 DVB-S (STB0899) Inittab */ -static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = { - - { STB0899_DEV_ID , 0x81 }, - { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, - { STB0899_DISFIFO , 0x00 }, - { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, - { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, - { STB0899_IRQSTATUS_3 , 0x30 }, - { STB0899_IRQSTATUS_2 , 0x00 }, - { STB0899_IRQSTATUS_1 , 0x00 }, - { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, - { STB0899_IRQMSK_0 , 0xff }, - { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */ - { STB0899_IOPVALUE5 , 0x00 }, - { STB0899_IOPVALUE4 , 0x20 }, - { STB0899_IOPVALUE3 , 0xc9 }, - { STB0899_IOPVALUE2 , 0x90 }, - { STB0899_IOPVALUE1 , 0x40 }, - { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, - { STB0899_GPIO32CFG , 0x82 }, - { STB0899_GPIO33CFG , 0x82 }, - { STB0899_GPIO34CFG , 0x82 }, - { STB0899_GPIO35CFG , 0x82 }, - { STB0899_GPIO36CFG , 0x82 }, - { STB0899_GPIO37CFG , 0x82 }, - { STB0899_GPIO38CFG , 0x82 }, - { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, - { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, - { 0xffff , 0xff }, -}; - -static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x08 }, - { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x33 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xee }, - { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, - { STB0899_IDCCOMP , 0xfb }, - { STB0899_QDCCOMP , 0x03 }, - { STB0899_POWERI , 0x3b }, - { STB0899_POWERQ , 0x3d }, - { STB0899_RCOMP , 0x81 }, - { STB0899_AGCIQIN , 0x80 }, - { STB0899_AGC2I1 , 0x04 }, - { STB0899_AGC2I2 , 0xf5 }, - { STB0899_TLIR , 0x25 }, - { STB0899_RTF , 0x80 }, - { STB0899_DSTATUS , 0x00 }, - { STB0899_LDI , 0xca }, - { STB0899_CFRM , 0xf1 }, - { STB0899_CFRL , 0xf3 }, - { STB0899_NIRM , 0x2a }, - { STB0899_NIRL , 0x05 }, - { STB0899_ISYMB , 0x17 }, - { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, - { STB0899_EQUAI1 , 0xfd }, - { STB0899_EQUAQ1 , 0x04 }, - { STB0899_EQUAI2 , 0x0f }, - { STB0899_EQUAQ2 , 0xff }, - { STB0899_EQUAI3 , 0xdf }, - { STB0899_EQUAQ3 , 0xfa }, - { STB0899_EQUAI4 , 0x37 }, - { STB0899_EQUAQ4 , 0x0d }, - { STB0899_EQUAI5 , 0xbd }, - { STB0899_EQUAQ5 , 0xf7 }, - { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, - { STB0899_VERROR , 0xff }, - { STB0899_IQSWAP , 0x2a }, - { STB0899_ECNT1M , 0x00 }, - { STB0899_ECNT1L , 0x00 }, - { STB0899_ECNT2M , 0x00 }, - { STB0899_ECNT2L , 0x00 }, - { STB0899_ECNT3M , 0x00 }, - { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, - { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, - { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, - { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, - { STB0899_TSINHDELM , 0x00 }, - { STB0899_TSINHDELL , 0x00 }, - { STB0899_TSLLSTKM , 0x00 }, - { STB0899_TSLLSTKL , 0x00 }, - { STB0899_TSULSTKM , 0x00 }, - { STB0899_TSULSTKL , 0xab }, - { STB0899_PCKLENUL , 0x00 }, - { STB0899_PCKLENLL , 0xcc }, - { STB0899_RSPCKLEN , 0xcc }, - { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, - { STB0899_DMONMSK1 , 0x27 }, - { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, - { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, - { STB0899_MATCSTM , 0x00 }, - { STB0899_MATCSTL , 0x00 }, - { STB0899_UPLCSTM , 0x00 }, - { STB0899_UPLCSTL , 0x00 }, - { STB0899_DFLCSTM , 0x00 }, - { STB0899_DFLCSTL , 0x00 }, - { STB0899_SYNCCST , 0x00 }, - { STB0899_SYNCDCSTM , 0x00 }, - { STB0899_SYNCDCSTL , 0x00 }, - { STB0899_ISI_ENTRY , 0x00 }, - { STB0899_ISI_BIT_EN , 0x00 }, - { STB0899_MATSTRM , 0x00 }, - { STB0899_MATSTRL , 0x00 }, - { STB0899_UPLSTRM , 0x00 }, - { STB0899_UPLSTRL , 0x00 }, - { STB0899_DFLSTRM , 0x00 }, - { STB0899_DFLSTRL , 0x00 }, - { STB0899_SYNCSTR , 0x00 }, - { STB0899_SYNCDSTRM , 0x00 }, - { STB0899_SYNCDSTRL , 0x00 }, - { STB0899_CFGPDELSTATUS1 , 0x10 }, - { STB0899_CFGPDELSTATUS2 , 0x00 }, - { STB0899_BBFERRORM , 0x00 }, - { STB0899_BBFERRORL , 0x00 }, - { STB0899_UPKTERRORM , 0x00 }, - { STB0899_UPKTERRORL , 0x00 }, - { 0xffff , 0xff }, -}; - -/* STB0899 demodulator config for the KNC1 and clones */ -static struct stb0899_config knc1_dvbs2_config = { - .init_dev = knc1_stb0899_s1_init_1, - .init_s2_demod = stb0899_s2_init_2, - .init_s1_demod = knc1_stb0899_s1_init_3, - .init_s2_fec = stb0899_s2_init_4, - .init_tst = stb0899_s1_init_5, - - .postproc = NULL, - - .demod_address = 0x68, -// .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */ - .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */ -// .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */ - - .xtal_freq = 27000000, - .inversion = IQ_SWAP_OFF, /* 1 */ - - .lo_clk = 76500000, - .hi_clk = 90000000, - - .esno_ave = STB0899_DVBS2_ESNO_AVE, - .esno_quant = STB0899_DVBS2_ESNO_QUANT, - .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, - .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, - .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, - .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, - .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, - .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, - .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, - - .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, - .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, - .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, - .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, - - .tuner_get_frequency = tda8261_get_frequency, - .tuner_set_frequency = tda8261_set_frequency, - .tuner_set_bandwidth = NULL, - .tuner_get_bandwidth = tda8261_get_bandwidth, - .tuner_set_rfsiggain = NULL -}; - -/* - * SD1878/SHA tuner config - * 1F, Single I/P, Horizontal mount, High Sensitivity - */ -static const struct tda8261_config sd1878c_config = { -// .name = "SD1878/SHA", - .addr = 0x60, - .step_size = TDA8261_STEP_1000 /* kHz */ -}; - -static u8 read_pwm(struct budget_av *budget_av) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1}, - {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} - }; - - if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2) - || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - -#define SUBID_DVBS_KNC1 0x0010 -#define SUBID_DVBS_KNC1_PLUS 0x0011 -#define SUBID_DVBS_TYPHOON 0x4f56 -#define SUBID_DVBS_CINERGY1200 0x1154 -#define SUBID_DVBS_CYNERGY1200N 0x1155 -#define SUBID_DVBS_TV_STAR 0x0014 -#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015 -#define SUBID_DVBS_TV_STAR_CI 0x0016 -#define SUBID_DVBS2_KNC1 0x0018 -#define SUBID_DVBS2_KNC1_OEM 0x0019 -#define SUBID_DVBS_EASYWATCH_1 0x001a -#define SUBID_DVBS_EASYWATCH_2 0x001b -#define SUBID_DVBS2_EASYWATCH 0x001d -#define SUBID_DVBS_EASYWATCH 0x001e - -#define SUBID_DVBC_EASYWATCH 0x002a -#define SUBID_DVBC_EASYWATCH_MK3 0x002c -#define SUBID_DVBC_KNC1 0x0020 -#define SUBID_DVBC_KNC1_PLUS 0x0021 -#define SUBID_DVBC_KNC1_MK3 0x0022 -#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023 -#define SUBID_DVBC_CINERGY1200 0x1156 -#define SUBID_DVBC_CINERGY1200_MK3 0x1176 - -#define SUBID_DVBT_EASYWATCH 0x003a -#define SUBID_DVBT_KNC1_PLUS 0x0031 -#define SUBID_DVBT_KNC1 0x0030 -#define SUBID_DVBT_CINERGY1200 0x1157 - -static void frontend_init(struct budget_av *budget_av) -{ - struct saa7146_dev * saa = budget_av->budget.dev; - struct dvb_frontend * fe = NULL; - - /* Enable / PowerON Frontend */ - saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); - - /* Wait for PowerON */ - msleep(100); - - /* additional setup necessary for the PLUS cards */ - switch (saa->pci->subsystem_device) { - case SUBID_DVBS_KNC1_PLUS: - case SUBID_DVBC_KNC1_PLUS: - case SUBID_DVBT_KNC1_PLUS: - case SUBID_DVBC_EASYWATCH: - case SUBID_DVBC_KNC1_PLUS_MK3: - case SUBID_DVBS2_KNC1: - case SUBID_DVBS2_KNC1_OEM: - case SUBID_DVBS2_EASYWATCH: - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); - break; - } - - switch (saa->pci->subsystem_device) { - - case SUBID_DVBS_KNC1: - /* - * maybe that setting is needed for other dvb-s cards as well, - * but so far it has been only confirmed for this type - */ - budget_av->reinitialise_demod = 1; - /* fall through */ - case SUBID_DVBS_KNC1_PLUS: - case SUBID_DVBS_EASYWATCH_1: - if (saa->pci->subsystem_vendor == 0x1894) { - fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config, - &budget_av->budget.i2c_adap); - if (fe) { - dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap); - } - } else { - fe = dvb_attach(stv0299_attach, &typhoon_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } - } - break; - - case SUBID_DVBS_TV_STAR: - case SUBID_DVBS_TV_STAR_PLUS_X4: - case SUBID_DVBS_TV_STAR_CI: - case SUBID_DVBS_CYNERGY1200N: - case SUBID_DVBS_EASYWATCH: - case SUBID_DVBS_EASYWATCH_2: - fe = dvb_attach(stv0299_attach, &philips_sd1878_config, - &budget_av->budget.i2c_adap); - if (fe) { - dvb_attach(dvb_pll_attach, fe, 0x60, - &budget_av->budget.i2c_adap, - DVB_PLL_PHILIPS_SD1878_TDA8261); - } - break; - - case SUBID_DVBS_TYPHOON: - fe = dvb_attach(stv0299_attach, &typhoon_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } - break; - case SUBID_DVBS2_KNC1: - case SUBID_DVBS2_KNC1_OEM: - case SUBID_DVBS2_EASYWATCH: - budget_av->reinitialise_demod = 1; - if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap))) - dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap); - - break; - case SUBID_DVBS_CINERGY1200: - fe = dvb_attach(stv0299_attach, &cinergy_1200s_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; - } - break; - - case SUBID_DVBC_KNC1: - case SUBID_DVBC_KNC1_PLUS: - case SUBID_DVBC_CINERGY1200: - case SUBID_DVBC_EASYWATCH: - budget_av->reinitialise_demod = 1; - budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - fe = dvb_attach(tda10021_attach, &philips_cu1216_config, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - if (fe == NULL) - fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - if (fe) { - fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } - break; - - case SUBID_DVBC_EASYWATCH_MK3: - case SUBID_DVBC_CINERGY1200_MK3: - case SUBID_DVBC_KNC1_MK3: - case SUBID_DVBC_KNC1_PLUS_MK3: - budget_av->reinitialise_demod = 1; - budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; - fe = dvb_attach(tda10023_attach, - &philips_cu1216_tda10023_config, - &budget_av->budget.i2c_adap, - read_pwm(budget_av)); - if (fe) { - fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; - } - break; - - case SUBID_DVBT_EASYWATCH: - case SUBID_DVBT_KNC1: - case SUBID_DVBT_KNC1_PLUS: - case SUBID_DVBT_CINERGY1200: - budget_av->reinitialise_demod = 1; - fe = dvb_attach(tda10046_attach, &philips_tu1216_config, - &budget_av->budget.i2c_adap); - if (fe) { - fe->ops.tuner_ops.init = philips_tu1216_tuner_init; - fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; - } - break; - } - - if (fe == NULL) { - printk(KERN_ERR "budget-av: A frontend driver was not found " - "for device [%04x:%04x] subsystem [%04x:%04x]\n", - saa->pci->vendor, - saa->pci->device, - saa->pci->subsystem_vendor, - saa->pci->subsystem_device); - return; - } - - budget_av->budget.dvb_frontend = fe; - - if (dvb_register_frontend(&budget_av->budget.dvb_adapter, - budget_av->budget.dvb_frontend)) { - printk(KERN_ERR "budget-av: Frontend registration failed!\n"); - dvb_frontend_detach(budget_av->budget.dvb_frontend); - budget_av->budget.dvb_frontend = NULL; - } -} - - -static void budget_av_irq(struct saa7146_dev *dev, u32 * isr) -{ - struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; - - dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av); - - if (*isr & MASK_10) - ttpci_budget_irq10_handler(dev, isr); -} - -static int budget_av_detach(struct saa7146_dev *dev) -{ - struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; - int err; - - dprintk(2, "dev: %p\n", dev); - - if (1 == budget_av->has_saa7113) { - saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); - - msleep(200); - - saa7146_unregister_device(&budget_av->vd, dev); - - saa7146_vv_release(dev); - } - - if (budget_av->budget.ci_present) - ciintf_deinit(budget_av); - - if (budget_av->budget.dvb_frontend != NULL) { - dvb_unregister_frontend(budget_av->budget.dvb_frontend); - dvb_frontend_detach(budget_av->budget.dvb_frontend); - } - err = ttpci_budget_deinit(&budget_av->budget); - - kfree(budget_av); - - return err; -} - -static struct saa7146_ext_vv vv_data; - -static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct budget_av *budget_av; - u8 *mac; - int err; - - dprintk(2, "dev: %p\n", dev); - - if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL))) - return -ENOMEM; - - budget_av->has_saa7113 = 0; - budget_av->budget.ci_present = 0; - - dev->ext_priv = budget_av; - - err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE, - adapter_nr); - if (err) { - kfree(budget_av); - return err; - } - - /* knc1 initialization */ - saa7146_write(dev, DD1_STREAM_B, 0x04000000); - saa7146_write(dev, DD1_INIT, 0x07000600); - saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); - - if (saa7113_init(budget_av) == 0) { - budget_av->has_saa7113 = 1; - - if (0 != saa7146_vv_init(dev, &vv_data)) { - /* fixme: proper cleanup here */ - ERR(("cannot init vv subsystem.\n")); - return err; - } - - if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { - /* fixme: proper cleanup here */ - ERR(("cannot register capture v4l2 device.\n")); - saa7146_vv_release(dev); - return err; - } - - /* beware: this modifies dev->vv ... */ - saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A, - SAA7146_HPS_SYNC_PORT_A); - - saa7113_setinput(budget_av, 0); - } - - /* fixme: find some sane values here... */ - saa7146_write(dev, PCI_BT_V1, 0x1c00101f); - - 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", - 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]); - } - - budget_av->budget.dvb_adapter.priv = budget_av; - frontend_init(budget_av); - ciintf_init(budget_av); - - ttpci_budget_init_hooks(&budget_av->budget); - - return 0; -} - -#define KNC1_INPUTS 2 -static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { - {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, - {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, -}; - -static struct saa7146_extension_ioctls ioctls[] = { - {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE}, - {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE}, - {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE}, - {0, 0} -}; - -static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) -{ - struct saa7146_dev *dev = fh->dev; - struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; - - switch (cmd) { - case VIDIOC_ENUMINPUT:{ - struct v4l2_input *i = arg; - - dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); - if (i->index < 0 || i->index >= KNC1_INPUTS) { - return -EINVAL; - } - memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); - return 0; - } - case VIDIOC_G_INPUT:{ - int *input = (int *) arg; - - *input = budget_av->cur_input; - - dprintk(1, "VIDIOC_G_INPUT %d.\n", *input); - return 0; - } - case VIDIOC_S_INPUT:{ - int input = *(int *) arg; - dprintk(1, "VIDIOC_S_INPUT %d.\n", input); - return saa7113_setinput(budget_av, input); - } - default: - return -ENOIOCTLCMD; - } - return 0; -} - -static struct saa7146_standard standard[] = { - {.name = "PAL",.id = V4L2_STD_PAL, - .v_offset = 0x17,.v_field = 288, - .h_offset = 0x14,.h_pixels = 680, - .v_max_out = 576,.h_max_out = 768 }, - - {.name = "NTSC",.id = V4L2_STD_NTSC, - .v_offset = 0x16,.v_field = 240, - .h_offset = 0x06,.h_pixels = 708, - .v_max_out = 480,.h_max_out = 640, }, -}; - -static struct saa7146_ext_vv vv_data = { - .inputs = 2, - .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113 - .flags = 0, - .stds = &standard[0], - .num_stds = ARRAY_SIZE(standard), - .ioctls = &ioctls[0], - .ioctl = av_ioctl, -}; - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); -MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2); -MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2); -MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); -MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); -MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); -MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); -MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); -MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); -MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); -MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); -MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T); -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(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); -MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); -MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); -MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3); -MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); - -static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), - MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), - MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), - MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), - MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011), - MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), - MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), - MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), - MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018), - MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019), - MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d), - MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), - MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), - MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), - MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), - MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), - MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a), - MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), - MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), - MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), - MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023), - MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), - MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), - MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), - MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), - MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), - MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176), - MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_extension budget_extension = { - .name = "budget_av", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = pci_tbl, - - .module = THIS_MODULE, - .attach = budget_av_attach, - .detach = budget_av_detach, - - .irq_mask = MASK_10, - .irq_func = budget_av_irq, -}; - -static int __init budget_av_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_av_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -module_init(budget_av_init); -module_exit(budget_av_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called " - "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c deleted file mode 100644 index bcbc5d41a0f..00000000000 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ /dev/null @@ -1,1602 +0,0 @@ -/* - * budget-ci.c: driver for the SAA7146 based Budget DVB cards - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM> - * partially based on the Siemens DVB driver by Ralph+Marcus Metzler - * - * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/input.h> -#include <linux/spinlock.h> -#include <media/ir-common.h> - -#include "budget.h" - -#include "dvb_ca_en50221.h" -#include "stv0299.h" -#include "stv0297.h" -#include "tda1004x.h" -#include "stb0899_drv.h" -#include "stb0899_reg.h" -#include "stb0899_cfg.h" -#include "stb6100.h" -#include "stb6100_cfg.h" -#include "lnbp21.h" -#include "bsbe1.h" -#include "bsru6.h" -#include "tda1002x.h" -#include "tda827x.h" - -/* - * Regarding DEBIADDR_IR: - * Some CI modules hang if random addresses are read. - * Using address 0x4000 for the IR read means that we - * use the same address as for CI version, which should - * be a safe default. - */ -#define DEBIADDR_IR 0x4000 -#define DEBIADDR_CICONTROL 0x0000 -#define DEBIADDR_CIVERSION 0x4000 -#define DEBIADDR_IO 0x1000 -#define DEBIADDR_ATTR 0x3000 - -#define CICONTROL_RESET 0x01 -#define CICONTROL_ENABLETS 0x02 -#define CICONTROL_CAMDETECT 0x08 - -#define DEBICICTL 0x00420000 -#define DEBICICAM 0x02420000 - -#define SLOTSTATUS_NONE 1 -#define SLOTSTATUS_PRESENT 2 -#define SLOTSTATUS_RESET 4 -#define SLOTSTATUS_READY 8 -#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) - -/* - * Milliseconds during which a key is regarded as pressed. - * If an identical command arrives within this time, the timer will start over. - */ -#define IR_KEYPRESS_TIMEOUT 250 - -/* RC5 device wildcard */ -#define IR_DEVICE_ANY 255 - -static int rc5_device = -1; -module_param(rc5_device, int, 0644); -MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)"); - -static int ir_debug; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -struct budget_ci_ir { - struct input_dev *dev; - struct tasklet_struct msp430_irq_tasklet; - struct timer_list timer_keyup; - char name[72]; /* 40 + 32 for (struct saa7146_dev).name */ - char phys[32]; - struct ir_input_state state; - int rc5_device; - u32 last_raw; - u32 ir_key; - bool have_command; -}; - -struct budget_ci { - struct budget budget; - struct tasklet_struct ciintf_irq_tasklet; - int slot_status; - int ci_irq; - struct dvb_ca_en50221 ca; - struct budget_ci_ir ir; - u8 tuner_pll_address; /* used for philips_tdm1316l configs */ -}; - -static void msp430_ir_keyup(unsigned long data) -{ - struct budget_ci_ir *ir = (struct budget_ci_ir *) data; - ir_input_nokey(ir->dev, &ir->state); -} - -static void msp430_ir_interrupt(unsigned long data) -{ - struct budget_ci *budget_ci = (struct budget_ci *) data; - struct input_dev *dev = budget_ci->ir.dev; - u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8; - u32 raw; - - /* - * The msp430 chip can generate two different bytes, command and device - * - * type1: X1CCCCCC, C = command bits (0 - 63) - * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit - * - * Each signal from the remote control can generate one or more command - * bytes and one or more device bytes. For the repeated bytes, the - * highest bit (X) is set. The first command byte is always generated - * before the first device byte. Other than that, no specific order - * seems to apply. To make life interesting, bytes can also be lost. - * - * Only when we have a command and device byte, a keypress is - * generated. - */ - - if (ir_debug) - printk("budget_ci: received byte 0x%02x\n", command); - - /* Remove repeat bit, we use every command */ - command = command & 0x7f; - - /* Is this a RC5 command byte? */ - if (command & 0x40) { - budget_ci->ir.have_command = true; - budget_ci->ir.ir_key = command & 0x3f; - return; - } - - /* It's a RC5 device byte */ - if (!budget_ci->ir.have_command) - return; - budget_ci->ir.have_command = false; - - if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && - budget_ci->ir.rc5_device != (command & 0x1f)) - return; - - /* Is this a repeated key sequence? (same device, command, toggle) */ - raw = budget_ci->ir.ir_key | (command << 8); - if (budget_ci->ir.last_raw != raw || !timer_pending(&budget_ci->ir.timer_keyup)) { - ir_input_nokey(dev, &budget_ci->ir.state); - ir_input_keydown(dev, &budget_ci->ir.state, - budget_ci->ir.ir_key, raw); - budget_ci->ir.last_raw = raw; - } - - mod_timer(&budget_ci->ir.timer_keyup, jiffies + msecs_to_jiffies(IR_KEYPRESS_TIMEOUT)); -} - -static int msp430_ir_init(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - struct input_dev *input_dev = budget_ci->ir.dev; - int error; - - budget_ci->ir.dev = input_dev = input_allocate_device(); - if (!input_dev) { - printk(KERN_ERR "budget_ci: IR interface initialisation failed\n"); - error = -ENOMEM; - goto out1; - } - - snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), - "Budget-CI dvb ir receiver %s", saa->name); - snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys), - "pci-%s/ir0", pci_name(saa->pci)); - - input_dev->name = budget_ci->ir.name; - - input_dev->phys = budget_ci->ir.phys; - input_dev->id.bustype = BUS_PCI; - input_dev->id.version = 1; - if (saa->pci->subsystem_vendor) { - input_dev->id.vendor = saa->pci->subsystem_vendor; - input_dev->id.product = saa->pci->subsystem_device; - } else { - input_dev->id.vendor = saa->pci->vendor; - input_dev->id.product = saa->pci->device; - } - input_dev->dev.parent = &saa->pci->dev; - - /* Select keymap and address */ - switch (budget_ci->budget.dev->pci->subsystem_device) { - case 0x100c: - case 0x100f: - case 0x1011: - case 0x1012: - /* The hauppauge keymap is a superset of these remotes */ - ir_input_init(input_dev, &budget_ci->ir.state, - IR_TYPE_RC5, ir_codes_hauppauge_new); - - if (rc5_device < 0) - budget_ci->ir.rc5_device = 0x1f; - else - budget_ci->ir.rc5_device = rc5_device; - break; - case 0x1010: - case 0x1017: - case 0x101a: - /* for the Technotrend 1500 bundled remote */ - ir_input_init(input_dev, &budget_ci->ir.state, - IR_TYPE_RC5, ir_codes_tt_1500); - - if (rc5_device < 0) - budget_ci->ir.rc5_device = IR_DEVICE_ANY; - else - budget_ci->ir.rc5_device = rc5_device; - break; - default: - /* unknown remote */ - ir_input_init(input_dev, &budget_ci->ir.state, - IR_TYPE_RC5, ir_codes_budget_ci_old); - - if (rc5_device < 0) - budget_ci->ir.rc5_device = IR_DEVICE_ANY; - else - budget_ci->ir.rc5_device = rc5_device; - break; - } - - /* initialise the key-up timeout handler */ - init_timer(&budget_ci->ir.timer_keyup); - budget_ci->ir.timer_keyup.function = msp430_ir_keyup; - budget_ci->ir.timer_keyup.data = (unsigned long) &budget_ci->ir; - budget_ci->ir.last_raw = 0xffff; /* An impossible value */ - error = input_register_device(input_dev); - if (error) { - printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error); - goto out2; - } - - /* note: these must be after input_register_device */ - input_dev->rep[REP_DELAY] = 400; - input_dev->rep[REP_PERIOD] = 250; - - tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, - (unsigned long) budget_ci); - - SAA7146_IER_ENABLE(saa, MASK_06); - saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); - - return 0; - -out2: - input_free_device(input_dev); -out1: - return error; -} - -static void msp430_ir_deinit(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - struct input_dev *dev = budget_ci->ir.dev; - - SAA7146_IER_DISABLE(saa, MASK_06); - saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ir.msp430_irq_tasklet); - - del_timer_sync(&dev->timer); - ir_input_nokey(dev, &budget_ci->ir.state); - - input_unregister_device(dev); -} - -static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM, - DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0); -} - -static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM, - DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0); -} - -static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM, - DEBIADDR_IO | (address & 3), 1, 1, 0); -} - -static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - - if (slot != 0) - return -EINVAL; - - return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM, - DEBIADDR_IO | (address & 3), 1, value, 1, 0); -} - -static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - struct saa7146_dev *saa = budget_ci->budget.dev; - - if (slot != 0) - return -EINVAL; - - if (budget_ci->ci_irq) { - // trigger on RISING edge during reset so we know when READY is re-asserted - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } - budget_ci->slot_status = SLOTSTATUS_RESET; - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); - msleep(1); - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - CICONTROL_RESET, 1, 0); - - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - return 0; -} - -static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - struct saa7146_dev *saa = budget_ci->budget.dev; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); - return 0; -} - -static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - struct saa7146_dev *saa = budget_ci->budget.dev; - int tmp; - - if (slot != 0) - return -EINVAL; - - saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); - - tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - tmp | CICONTROL_ENABLETS, 1, 0); - - ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); - return 0; -} - -static void ciintf_interrupt(unsigned long data) -{ - struct budget_ci *budget_ci = (struct budget_ci *) data; - struct saa7146_dev *saa = budget_ci->budget.dev; - unsigned int flags; - - // ensure we don't get spurious IRQs during initialisation - if (!budget_ci->budget.ci_present) - return; - - // read the CAM status - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - if (flags & CICONTROL_CAMDETECT) { - - // GPIO should be set to trigger on falling edge if a CAM is present - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - - if (budget_ci->slot_status & SLOTSTATUS_NONE) { - // CAM insertion IRQ - budget_ci->slot_status = SLOTSTATUS_PRESENT; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, - DVB_CA_EN50221_CAMCHANGE_INSERTED); - - } else if (budget_ci->slot_status & SLOTSTATUS_RESET) { - // CAM ready (reset completed) - budget_ci->slot_status = SLOTSTATUS_READY; - dvb_ca_en50221_camready_irq(&budget_ci->ca, 0); - - } else if (budget_ci->slot_status & SLOTSTATUS_READY) { - // FR/DA IRQ - dvb_ca_en50221_frda_irq(&budget_ci->ca, 0); - } - } else { - - // trigger on rising edge if a CAM is not present - when a CAM is inserted, we - // only want to get the IRQ when it sets READY. If we trigger on the falling edge, - // the CAM might not actually be ready yet. - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - - // generate a CAM removal IRQ if we haven't already - if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) { - // CAM removal IRQ - budget_ci->slot_status = SLOTSTATUS_NONE; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, - DVB_CA_EN50221_CAMCHANGE_REMOVED); - } - } -} - -static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) -{ - struct budget_ci *budget_ci = (struct budget_ci *) ca->data; - unsigned int flags; - - // ensure we don't get spurious IRQs during initialisation - if (!budget_ci->budget.ci_present) - return -EINVAL; - - // read the CAM status - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - if (flags & CICONTROL_CAMDETECT) { - // mark it as present if it wasn't before - if (budget_ci->slot_status & SLOTSTATUS_NONE) { - budget_ci->slot_status = SLOTSTATUS_PRESENT; - } - - // during a RESET, we check if we can read from IO memory to see when CAM is ready - if (budget_ci->slot_status & SLOTSTATUS_RESET) { - if (ciintf_read_attribute_mem(ca, slot, 0) == 0x1d) { - budget_ci->slot_status = SLOTSTATUS_READY; - } - } - } else { - budget_ci->slot_status = SLOTSTATUS_NONE; - } - - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - if (budget_ci->slot_status & SLOTSTATUS_READY) { - return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; - } - return DVB_CA_EN50221_POLL_CAM_PRESENT; - } - - return 0; -} - -static int ciintf_init(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - int flags; - int result; - int ci_version; - int ca_flags; - - memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221)); - - // enable DEBI pins - saa7146_write(saa, MC1, MASK_27 | MASK_11); - - // test if it is there - ci_version = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0); - if ((ci_version & 0xa0) != 0xa0) { - result = -ENODEV; - goto error; - } - - // determine whether a CAM is present or not - flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0); - budget_ci->slot_status = SLOTSTATUS_NONE; - if (flags & CICONTROL_CAMDETECT) - budget_ci->slot_status = SLOTSTATUS_PRESENT; - - // version 0xa2 of the CI firmware doesn't generate interrupts - if (ci_version == 0xa2) { - ca_flags = 0; - budget_ci->ci_irq = 0; - } else { - ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | - DVB_CA_EN50221_FLAG_IRQ_FR | - DVB_CA_EN50221_FLAG_IRQ_DA; - budget_ci->ci_irq = 1; - } - - // register CI interface - budget_ci->ca.owner = THIS_MODULE; - budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem; - budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem; - budget_ci->ca.read_cam_control = ciintf_read_cam_control; - budget_ci->ca.write_cam_control = ciintf_write_cam_control; - budget_ci->ca.slot_reset = ciintf_slot_reset; - budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; - budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; - budget_ci->ca.poll_slot_status = ciintf_poll_slot_status; - budget_ci->ca.data = budget_ci; - if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, - &budget_ci->ca, - ca_flags, 1)) != 0) { - printk("budget_ci: CI interface detected, but initialisation failed.\n"); - goto error; - } - - // Setup CI slot IRQ - if (budget_ci->ci_irq) { - tasklet_init(&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); - if (budget_ci->slot_status != SLOTSTATUS_NONE) { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); - } else { - saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); - } - SAA7146_IER_ENABLE(saa, MASK_03); - } - - // enable interface - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - CICONTROL_RESET, 1, 0); - - // success! - printk("budget_ci: CI interface initialised\n"); - budget_ci->budget.ci_present = 1; - - // forge a fake CI IRQ so the CAM state is setup correctly - if (budget_ci->ci_irq) { - flags = DVB_CA_EN50221_CAMCHANGE_REMOVED; - if (budget_ci->slot_status != SLOTSTATUS_NONE) - flags = DVB_CA_EN50221_CAMCHANGE_INSERTED; - dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags); - } - - return 0; - -error: - saa7146_write(saa, MC1, MASK_27); - return result; -} - -static void ciintf_deinit(struct budget_ci *budget_ci) -{ - struct saa7146_dev *saa = budget_ci->budget.dev; - - // disable CI interrupts - if (budget_ci->ci_irq) { - SAA7146_IER_DISABLE(saa, MASK_03); - saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); - tasklet_kill(&budget_ci->ciintf_irq_tasklet); - } - - // reset interface - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0); - msleep(1); - ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, - CICONTROL_RESET, 1, 0); - - // disable TS data stream to CI interface - saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); - - // release the CA device - dvb_ca_en50221_release(&budget_ci->ca); - - // disable DEBI pins - saa7146_write(saa, MC1, MASK_27); -} - -static void budget_ci_irq(struct saa7146_dev *dev, u32 * isr) -{ - struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv; - - dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci); - - if (*isr & MASK_06) - tasklet_schedule(&budget_ci->ir.msp430_irq_tasklet); - - if (*isr & MASK_10) - ttpci_budget_irq10_handler(dev, isr); - - if ((*isr & MASK_03) && (budget_ci->budget.ci_present) && (budget_ci->ci_irq)) - tasklet_schedule(&budget_ci->ciintf_irq_tasklet); -} - -static u8 philips_su1278_tt_inittab[] = { - 0x01, 0x0f, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x5b, - 0x05, 0x85, - 0x06, 0x02, - 0x07, 0x00, - 0x08, 0x02, - 0x09, 0x00, - 0x0C, 0x01, - 0x0D, 0x81, - 0x0E, 0x44, - 0x0f, 0x14, - 0x10, 0x3c, - 0x11, 0x84, - 0x12, 0xda, - 0x13, 0x97, - 0x14, 0x95, - 0x15, 0xc9, - 0x16, 0x19, - 0x17, 0x8c, - 0x18, 0x59, - 0x19, 0xf8, - 0x1a, 0xfe, - 0x1c, 0x7f, - 0x1d, 0x00, - 0x1e, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, - 0x29, 0x28, - 0x2a, 0x14, - 0x2b, 0x0f, - 0x2c, 0x09, - 0x2d, 0x09, - 0x31, 0x1f, - 0x32, 0x19, - 0x33, 0xfc, - 0x34, 0x93, - 0xff, 0xff -}; - -static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - stv0299_writereg(fe, 0x0e, 0x44); - if (srate >= 10000000) { - stv0299_writereg(fe, 0x13, 0x97); - stv0299_writereg(fe, 0x14, 0x95); - stv0299_writereg(fe, 0x15, 0xc9); - stv0299_writereg(fe, 0x17, 0x8c); - stv0299_writereg(fe, 0x1a, 0xfe); - stv0299_writereg(fe, 0x1c, 0x7f); - stv0299_writereg(fe, 0x2d, 0x09); - } else { - stv0299_writereg(fe, 0x13, 0x99); - stv0299_writereg(fe, 0x14, 0x8d); - stv0299_writereg(fe, 0x15, 0xce); - stv0299_writereg(fe, 0x17, 0x43); - stv0299_writereg(fe, 0x1a, 0x1d); - stv0299_writereg(fe, 0x1c, 0x12); - stv0299_writereg(fe, 0x2d, 0x05); - } - stv0299_writereg(fe, 0x0e, 0x23); - stv0299_writereg(fe, 0x0f, 0x94); - stv0299_writereg(fe, 0x10, 0x39); - stv0299_writereg(fe, 0x15, 0xc9); - - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - - return 0; -} - -static int philips_su1278_tt_tuner_set_params(struct dvb_frontend *fe, - struct dvb_frontend_parameters *params) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - u32 div; - u8 buf[4]; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (500 - 1)) / 500; // round correctly - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2; - buf[3] = 0x20; - - if (params->u.qpsk.symbol_rate < 4000000) - buf[3] |= 1; - - if (params->frequency < 1250000) - buf[3] |= 0; - else if (params->frequency < 1550000) - buf[3] |= 0x40; - else if (params->frequency < 2050000) - buf[3] |= 0x80; - else if (params->frequency < 2150000) - buf[3] |= 0xC0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct stv0299_config philips_su1278_tt_config = { - - .demod_address = 0x68, - .inittab = philips_su1278_tt_inittab, - .mclk = 64000000UL, - .invert = 0, - .skip_reinit = 1, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 50, - .set_symbol_rate = philips_su1278_tt_set_symbol_rate, -}; - - - -static int philips_tdm1316l_tuner_init(struct dvb_frontend *fe) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; - static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = td1316_init,.len = - sizeof(td1316_init) }; - - // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - msleep(1); - - // disable the mc44BC374c (do not check for errors) - tuner_msg.addr = 0x65; - tuner_msg.buf = disable_mc44BC374c; - tuner_msg.len = sizeof(disable_mc44BC374c); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1); - } - - return 0; -} - -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = params->frequency + 36130000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) - cp = 3; - else if (tuner_frequency < 160000000) - cp = 5; - else if (tuner_frequency < 200000000) - cp = 6; - else if (tuner_frequency < 290000000) - cp = 3; - else if (tuner_frequency < 420000000) - cp = 5; - else if (tuner_frequency < 480000000) - cp = 6; - else if (tuner_frequency < 620000000) - cp = 3; - else if (tuner_frequency < 830000000) - cp = 5; - else if (tuner_frequency < 895000000) - cp = 7; - else - return -EINVAL; - - // determine band - if (params->frequency < 49000000) - return -EINVAL; - else if (params->frequency < 159000000) - band = 1; - else if (params->frequency < 444000000) - band = 2; - else if (params->frequency < 861000000) - band = 4; - else - return -EINVAL; - - // setup PLL filter and TDA9889 - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: - tda1004x_writereg(fe, 0x0C, 0x14); - filter = 0; - break; - - case BANDWIDTH_7_MHZ: - tda1004x_writereg(fe, 0x0C, 0x80); - filter = 0; - break; - - case BANDWIDTH_8_MHZ: - tda1004x_writereg(fe, 0x0C, 0x14); - filter = 1; - break; - - default: - return -EINVAL; - } - - // calculate divisor - // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000; - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xca; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - return 0; -} - -static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe, - const struct firmware **fw, char *name) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - - return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev); -} - -static struct tda1004x_config philips_tdm1316l_config = { - - .demod_address = 0x8, - .invert = 0, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tdm1316l_request_firmware, -}; - -static struct tda1004x_config philips_tdm1316l_config_invert = { - - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 0, - .xtal_freq = TDA10046_XTAL_4M, - .agc_config = TDA10046_AGC_DEFAULT, - .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tdm1316l_request_firmware, -}; - -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv; - u8 tuner_buf[5]; - struct i2c_msg tuner_msg = {.addr = budget_ci->tuner_pll_address, - .flags = 0, - .buf = tuner_buf, - .len = sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = params->frequency + 36125000; - if (tuner_frequency < 87000000) - return -EINVAL; - else if (tuner_frequency < 130000000) { - cp = 3; - band = 1; - } else if (tuner_frequency < 160000000) { - cp = 5; - band = 1; - } else if (tuner_frequency < 200000000) { - cp = 6; - band = 1; - } else if (tuner_frequency < 290000000) { - cp = 3; - band = 2; - } else if (tuner_frequency < 420000000) { - cp = 5; - band = 2; - } else if (tuner_frequency < 480000000) { - cp = 6; - band = 2; - } else if (tuner_frequency < 620000000) { - cp = 3; - band = 4; - } else if (tuner_frequency < 830000000) { - cp = 5; - band = 4; - } else if (tuner_frequency < 895000000) { - cp = 7; - band = 4; - } else - return -EINVAL; - - // assume PLL filter should always be 8MHz for the moment. - filter = 1; - - // calculate divisor - tuner_frequency = (params->frequency + 36125000 + (62500/2)) / 62500; - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xc8; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - tuner_buf[4] = 0x80; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(50); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - - return 0; -} - -static u8 dvbc_philips_tdm1316l_inittab[] = { - 0x80, 0x01, - 0x80, 0x00, - 0x81, 0x01, - 0x81, 0x00, - 0x00, 0x09, - 0x01, 0x69, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x20, 0x00, - 0x21, 0x40, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x40, - 0x25, 0x88, - 0x30, 0xff, - 0x31, 0x00, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x50, - 0x35, 0x7f, - 0x36, 0x00, - 0x37, 0x20, - 0x38, 0x00, - 0x40, 0x1c, - 0x41, 0xff, - 0x42, 0x29, - 0x43, 0x20, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0x00, - 0x4b, 0x7b, - 0x52, 0x30, - 0x55, 0xae, - 0x56, 0x47, - 0x57, 0xe1, - 0x58, 0x3a, - 0x5a, 0x1e, - 0x5b, 0x34, - 0x60, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x02, - 0x6b, 0x00, - 0x70, 0xff, - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x00, - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x80, - 0x86, 0x24, - 0x87, 0x78, - 0x88, 0x10, - 0x89, 0x00, - 0x90, 0x01, - 0x91, 0x01, - 0xa0, 0x04, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x53, - 0xc1, 0x70, - 0xc2, 0x12, - 0xd0, 0x00, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x00, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x00, - 0x61, 0x38, - 0x62, 0x0a, - 0x53, 0x13, - 0x59, 0x08, - 0xff, 0xff, -}; - -static struct stv0297_config dvbc_philips_tdm1316l_config = { - .demod_address = 0x1c, - .inittab = dvbc_philips_tdm1316l_inittab, - .invert = 0, - .stop_during_read = 1, -}; - -static struct tda10023_config tda10023_config = { - .demod_address = 0xc, - .invert = 0, - .xtal = 16000000, - .pll_m = 11, - .pll_p = 3, - .pll_n = 1, - .deltaf = 0xa511, -}; - -/* TT S2-3200 DVB-S (STB0899) Inittab */ -static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { - - { STB0899_DEV_ID , 0x81 }, - { STB0899_DISCNTRL1 , 0x32 }, - { STB0899_DISCNTRL2 , 0x80 }, - { STB0899_DISRX_ST0 , 0x04 }, - { STB0899_DISRX_ST1 , 0x00 }, - { STB0899_DISPARITY , 0x00 }, - { STB0899_DISFIFO , 0x00 }, - { STB0899_DISSTATUS , 0x20 }, - { STB0899_DISF22 , 0x8c }, - { STB0899_DISF22RX , 0x9a }, - { STB0899_SYSREG , 0x0b }, - { STB0899_ACRPRESC , 0x11 }, - { STB0899_ACRDIV1 , 0x0a }, - { STB0899_ACRDIV2 , 0x05 }, - { STB0899_DACR1 , 0x00 }, - { STB0899_DACR2 , 0x00 }, - { STB0899_OUTCFG , 0x00 }, - { STB0899_MODECFG , 0x00 }, - { STB0899_IRQSTATUS_3 , 0x30 }, - { STB0899_IRQSTATUS_2 , 0x00 }, - { STB0899_IRQSTATUS_1 , 0x00 }, - { STB0899_IRQSTATUS_0 , 0x00 }, - { STB0899_IRQMSK_3 , 0xf3 }, - { STB0899_IRQMSK_2 , 0xfc }, - { STB0899_IRQMSK_1 , 0xff }, - { STB0899_IRQMSK_0 , 0xff }, - { STB0899_IRQCFG , 0x00 }, - { STB0899_I2CCFG , 0x88 }, - { STB0899_I2CRPT , 0x48 }, /* 12k Pullup, Repeater=16, Stop=disabled */ - { STB0899_IOPVALUE5 , 0x00 }, - { STB0899_IOPVALUE4 , 0x20 }, - { STB0899_IOPVALUE3 , 0xc9 }, - { STB0899_IOPVALUE2 , 0x90 }, - { STB0899_IOPVALUE1 , 0x40 }, - { STB0899_IOPVALUE0 , 0x00 }, - { STB0899_GPIO00CFG , 0x82 }, - { STB0899_GPIO01CFG , 0x82 }, - { STB0899_GPIO02CFG , 0x82 }, - { STB0899_GPIO03CFG , 0x82 }, - { STB0899_GPIO04CFG , 0x82 }, - { STB0899_GPIO05CFG , 0x82 }, - { STB0899_GPIO06CFG , 0x82 }, - { STB0899_GPIO07CFG , 0x82 }, - { STB0899_GPIO08CFG , 0x82 }, - { STB0899_GPIO09CFG , 0x82 }, - { STB0899_GPIO10CFG , 0x82 }, - { STB0899_GPIO11CFG , 0x82 }, - { STB0899_GPIO12CFG , 0x82 }, - { STB0899_GPIO13CFG , 0x82 }, - { STB0899_GPIO14CFG , 0x82 }, - { STB0899_GPIO15CFG , 0x82 }, - { STB0899_GPIO16CFG , 0x82 }, - { STB0899_GPIO17CFG , 0x82 }, - { STB0899_GPIO18CFG , 0x82 }, - { STB0899_GPIO19CFG , 0x82 }, - { STB0899_GPIO20CFG , 0x82 }, - { STB0899_SDATCFG , 0xb8 }, - { STB0899_SCLTCFG , 0xba }, - { STB0899_AGCRFCFG , 0x1c }, /* 0x11 */ - { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */ - { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */ - { STB0899_DIRCLKCFG , 0x82 }, - { STB0899_CLKOUT27CFG , 0x7e }, - { STB0899_STDBYCFG , 0x82 }, - { STB0899_CS0CFG , 0x82 }, - { STB0899_CS1CFG , 0x82 }, - { STB0899_DISEQCOCFG , 0x20 }, - { STB0899_GPIO32CFG , 0x82 }, - { STB0899_GPIO33CFG , 0x82 }, - { STB0899_GPIO34CFG , 0x82 }, - { STB0899_GPIO35CFG , 0x82 }, - { STB0899_GPIO36CFG , 0x82 }, - { STB0899_GPIO37CFG , 0x82 }, - { STB0899_GPIO38CFG , 0x82 }, - { STB0899_GPIO39CFG , 0x82 }, - { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ - { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ - { STB0899_FILTCTRL , 0x00 }, - { STB0899_SYSCTRL , 0x00 }, - { STB0899_STOPCLK1 , 0x20 }, - { STB0899_STOPCLK2 , 0x00 }, - { STB0899_INTBUFSTATUS , 0x00 }, - { STB0899_INTBUFCTRL , 0x0a }, - { 0xffff , 0xff }, -}; - -static const struct stb0899_s1_reg tt3200_stb0899_s1_init_3[] = { - { STB0899_DEMOD , 0x00 }, - { STB0899_RCOMPC , 0xc9 }, - { STB0899_AGC1CN , 0x41 }, - { STB0899_AGC1REF , 0x10 }, - { STB0899_RTC , 0x7a }, - { STB0899_TMGCFG , 0x4e }, - { STB0899_AGC2REF , 0x34 }, - { STB0899_TLSR , 0x84 }, - { STB0899_CFD , 0xc7 }, - { STB0899_ACLC , 0x87 }, - { STB0899_BCLC , 0x94 }, - { STB0899_EQON , 0x41 }, - { STB0899_LDT , 0xdd }, - { STB0899_LDT2 , 0xc9 }, - { STB0899_EQUALREF , 0xb4 }, - { STB0899_TMGRAMP , 0x10 }, - { STB0899_TMGTHD , 0x30 }, - { STB0899_IDCCOMP , 0xfb }, - { STB0899_QDCCOMP , 0x03 }, - { STB0899_POWERI , 0x3b }, - { STB0899_POWERQ , 0x3d }, - { STB0899_RCOMP , 0x81 }, - { STB0899_AGCIQIN , 0x80 }, - { STB0899_AGC2I1 , 0x04 }, - { STB0899_AGC2I2 , 0xf5 }, - { STB0899_TLIR , 0x25 }, - { STB0899_RTF , 0x80 }, - { STB0899_DSTATUS , 0x00 }, - { STB0899_LDI , 0xca }, - { STB0899_CFRM , 0xf1 }, - { STB0899_CFRL , 0xf3 }, - { STB0899_NIRM , 0x2a }, - { STB0899_NIRL , 0x05 }, - { STB0899_ISYMB , 0x17 }, - { STB0899_QSYMB , 0xfa }, - { STB0899_SFRH , 0x2f }, - { STB0899_SFRM , 0x68 }, - { STB0899_SFRL , 0x40 }, - { STB0899_SFRUPH , 0x2f }, - { STB0899_SFRUPM , 0x68 }, - { STB0899_SFRUPL , 0x40 }, - { STB0899_EQUAI1 , 0xfd }, - { STB0899_EQUAQ1 , 0x04 }, - { STB0899_EQUAI2 , 0x0f }, - { STB0899_EQUAQ2 , 0xff }, - { STB0899_EQUAI3 , 0xdf }, - { STB0899_EQUAQ3 , 0xfa }, - { STB0899_EQUAI4 , 0x37 }, - { STB0899_EQUAQ4 , 0x0d }, - { STB0899_EQUAI5 , 0xbd }, - { STB0899_EQUAQ5 , 0xf7 }, - { STB0899_DSTATUS2 , 0x00 }, - { STB0899_VSTATUS , 0x00 }, - { STB0899_VERROR , 0xff }, - { STB0899_IQSWAP , 0x2a }, - { STB0899_ECNT1M , 0x00 }, - { STB0899_ECNT1L , 0x00 }, - { STB0899_ECNT2M , 0x00 }, - { STB0899_ECNT2L , 0x00 }, - { STB0899_ECNT3M , 0x00 }, - { STB0899_ECNT3L , 0x00 }, - { STB0899_FECAUTO1 , 0x06 }, - { STB0899_FECM , 0x01 }, - { STB0899_VTH12 , 0xf0 }, - { STB0899_VTH23 , 0xa0 }, - { STB0899_VTH34 , 0x78 }, - { STB0899_VTH56 , 0x4e }, - { STB0899_VTH67 , 0x48 }, - { STB0899_VTH78 , 0x38 }, - { STB0899_PRVIT , 0xff }, - { STB0899_VITSYNC , 0x19 }, - { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ - { STB0899_TSULC , 0x42 }, - { STB0899_RSLLC , 0x40 }, - { STB0899_TSLPL , 0x12 }, - { STB0899_TSCFGH , 0x0c }, - { STB0899_TSCFGM , 0x00 }, - { STB0899_TSCFGL , 0x0c }, - { STB0899_TSOUT , 0x0d }, /* 0x0d for CAM */ - { STB0899_RSSYNCDEL , 0x00 }, - { STB0899_TSINHDELH , 0x02 }, - { STB0899_TSINHDELM , 0x00 }, - { STB0899_TSINHDELL , 0x00 }, - { STB0899_TSLLSTKM , 0x00 }, - { STB0899_TSLLSTKL , 0x00 }, - { STB0899_TSULSTKM , 0x00 }, - { STB0899_TSULSTKL , 0xab }, - { STB0899_PCKLENUL , 0x00 }, - { STB0899_PCKLENLL , 0xcc }, - { STB0899_RSPCKLEN , 0xcc }, - { STB0899_TSSTATUS , 0x80 }, - { STB0899_ERRCTRL1 , 0xb6 }, - { STB0899_ERRCTRL2 , 0x96 }, - { STB0899_ERRCTRL3 , 0x89 }, - { STB0899_DMONMSK1 , 0x27 }, - { STB0899_DMONMSK0 , 0x03 }, - { STB0899_DEMAPVIT , 0x5c }, - { STB0899_PLPARM , 0x1f }, - { STB0899_PDELCTRL , 0x48 }, - { STB0899_PDELCTRL2 , 0x00 }, - { STB0899_BBHCTRL1 , 0x00 }, - { STB0899_BBHCTRL2 , 0x00 }, - { STB0899_HYSTTHRESH , 0x77 }, - { STB0899_MATCSTM , 0x00 }, - { STB0899_MATCSTL , 0x00 }, - { STB0899_UPLCSTM , 0x00 }, - { STB0899_UPLCSTL , 0x00 }, - { STB0899_DFLCSTM , 0x00 }, - { STB0899_DFLCSTL , 0x00 }, - { STB0899_SYNCCST , 0x00 }, - { STB0899_SYNCDCSTM , 0x00 }, - { STB0899_SYNCDCSTL , 0x00 }, - { STB0899_ISI_ENTRY , 0x00 }, - { STB0899_ISI_BIT_EN , 0x00 }, - { STB0899_MATSTRM , 0x00 }, - { STB0899_MATSTRL , 0x00 }, - { STB0899_UPLSTRM , 0x00 }, - { STB0899_UPLSTRL , 0x00 }, - { STB0899_DFLSTRM , 0x00 }, - { STB0899_DFLSTRL , 0x00 }, - { STB0899_SYNCSTR , 0x00 }, - { STB0899_SYNCDSTRM , 0x00 }, - { STB0899_SYNCDSTRL , 0x00 }, - { STB0899_CFGPDELSTATUS1 , 0x10 }, - { STB0899_CFGPDELSTATUS2 , 0x00 }, - { STB0899_BBFERRORM , 0x00 }, - { STB0899_BBFERRORL , 0x00 }, - { STB0899_UPKTERRORM , 0x00 }, - { STB0899_UPKTERRORL , 0x00 }, - { 0xffff , 0xff }, -}; - -static struct stb0899_config tt3200_config = { - .init_dev = tt3200_stb0899_s1_init_1, - .init_s2_demod = stb0899_s2_init_2, - .init_s1_demod = tt3200_stb0899_s1_init_3, - .init_s2_fec = stb0899_s2_init_4, - .init_tst = stb0899_s1_init_5, - - .postproc = NULL, - - .demod_address = 0x68, - - .xtal_freq = 27000000, - .inversion = IQ_SWAP_ON, /* 1 */ - - .lo_clk = 76500000, - .hi_clk = 99000000, - - .esno_ave = STB0899_DVBS2_ESNO_AVE, - .esno_quant = STB0899_DVBS2_ESNO_QUANT, - .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE, - .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE, - .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD, - .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ, - .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK, - .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF, - .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT, - - .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS, - .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, - .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS, - .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER, - - .tuner_get_frequency = stb6100_get_frequency, - .tuner_set_frequency = stb6100_set_frequency, - .tuner_set_bandwidth = stb6100_set_bandwidth, - .tuner_get_bandwidth = stb6100_get_bandwidth, - .tuner_set_rfsiggain = NULL -}; - -static struct stb6100_config tt3200_stb6100_config = { - .tuner_address = 0x60, - .refclock = 27000000, -}; - -static void frontend_init(struct budget_ci *budget_ci) -{ - switch (budget_ci->budget.dev->pci->subsystem_device) { - case 0x100c: // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059)) - budget_ci->budget.dvb_frontend = - dvb_attach(stv0299_attach, &alps_bsru6_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; - break; - } - break; - - case 0x100f: // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059)) - budget_ci->budget.dvb_frontend = - dvb_attach(stv0299_attach, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_su1278_tt_tuner_set_params; - break; - } - break; - - case 0x1010: // TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt)) - budget_ci->tuner_pll_address = 0x61; - budget_ci->budget.dvb_frontend = - dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1011: // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889) - budget_ci->tuner_pll_address = 0x63; - budget_ci->budget.dvb_frontend = - dvb_attach(tda10045_attach, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1012: // TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt)) - budget_ci->tuner_pll_address = 0x60; - budget_ci->budget.dvb_frontend = - dvb_attach(tda10046_attach, &philips_tdm1316l_config_invert, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1017: // TT S-1500 PCI - budget_ci->budget.dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - budget_ci->budget.dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - budget_ci->budget.dvb_frontend->tuner_priv = &budget_ci->budget.i2c_adap; - - budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */ - budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48); - if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) { - printk(KERN_ERR "%s: No tda827x found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - case 0x1019: // TT S2-3200 PCI - /* - * NOTE! on some STB0899 versions, the internal PLL takes a longer time - * to settle, aka LOCK. On the older revisions of the chip, we don't see - * this, as a result on the newer chips the entire clock tree, will not - * be stable after a freshly POWER 'ed up situation. - * In this case, we should RESET the STB0899 (Active LOW) and wait for - * PLL stabilization. - * - * On the TT S2 3200 and clones, the STB0899 demodulator's RESETB is - * connected to the SAA7146 GPIO, GPIO2, Pin 142 - */ - /* Reset Demodulator */ - saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTLO); - /* Wait for everything to die */ - msleep(50); - /* Pull it up out of Reset state */ - saa7146_setgpio(budget_ci->budget.dev, 2, SAA7146_GPIO_OUTHI); - /* Wait for PLL to stabilize */ - msleep(250); - /* - * PLL state should be stable now. Ideally, we should check - * for PLL LOCK status. But well, never mind! - */ - budget_ci->budget.dvb_frontend = dvb_attach(stb0899_attach, &tt3200_config, &budget_ci->budget.i2c_adap); - if (budget_ci->budget.dvb_frontend) { - if (dvb_attach(stb6100_attach, budget_ci->budget.dvb_frontend, &tt3200_stb6100_config, &budget_ci->budget.i2c_adap)) { - if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) { - printk("%s: No LNBP21 found!\n", __func__); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } else { - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } - break; - - } - - if (budget_ci->budget.dvb_frontend == NULL) { - printk("budget-ci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - budget_ci->budget.dev->pci->vendor, - budget_ci->budget.dev->pci->device, - budget_ci->budget.dev->pci->subsystem_vendor, - budget_ci->budget.dev->pci->subsystem_device); - } else { - if (dvb_register_frontend - (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { - printk("budget-ci: Frontend registration failed!\n"); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - budget_ci->budget.dvb_frontend = NULL; - } - } -} - -static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) -{ - struct budget_ci *budget_ci; - int err; - - budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL); - if (!budget_ci) { - err = -ENOMEM; - goto out1; - } - - dprintk(2, "budget_ci: %p\n", budget_ci); - - dev->ext_priv = budget_ci; - - err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE, - adapter_nr); - if (err) - goto out2; - - err = msp430_ir_init(budget_ci); - if (err) - goto out3; - - ciintf_init(budget_ci); - - budget_ci->budget.dvb_adapter.priv = budget_ci; - frontend_init(budget_ci); - - ttpci_budget_init_hooks(&budget_ci->budget); - - return 0; - -out3: - ttpci_budget_deinit(&budget_ci->budget); -out2: - kfree(budget_ci); -out1: - return err; -} - -static int budget_ci_detach(struct saa7146_dev *dev) -{ - struct budget_ci *budget_ci = (struct budget_ci *) dev->ext_priv; - struct saa7146_dev *saa = budget_ci->budget.dev; - int err; - - if (budget_ci->budget.ci_present) - ciintf_deinit(budget_ci); - msp430_ir_deinit(budget_ci); - if (budget_ci->budget.dvb_frontend) { - dvb_unregister_frontend(budget_ci->budget.dvb_frontend); - dvb_frontend_detach(budget_ci->budget.dvb_frontend); - } - err = ttpci_budget_deinit(&budget_ci->budget); - - // disable frontend and CI interface - saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); - - kfree(budget_ci); - - return err; -} - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(ttbs2, "TT-Budget/S-1500 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI", BUDGET_TT_HW_DISEQC); -MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbtci, "TT-Budget-T-CI PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT); - -static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c), - MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f), - MAKE_EXTENSION_PCI(ttbcci, 0x13c2, 0x1010), - MAKE_EXTENSION_PCI(ttbt2, 0x13c2, 0x1011), - MAKE_EXTENSION_PCI(ttbtci, 0x13c2, 0x1012), - MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017), - MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a), - MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_extension budget_extension = { - .name = "budget_ci dvb", - .flags = SAA7146_USE_I2C_IRQ, - - .module = THIS_MODULE, - .pci_tbl = &pci_tbl[0], - .attach = budget_ci_attach, - .detach = budget_ci_detach, - - .irq_mask = MASK_03 | MASK_06 | MASK_10, - .irq_func = budget_ci_irq, -}; - -static int __init budget_ci_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_ci_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -module_init(budget_ci_init); -module_exit(budget_ci_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called " - "budget PCI DVB cards w/ CI-module produced by " - "Siemens, Technotrend, Hauppauge"); diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c deleted file mode 100644 index ba18e56d5f1..00000000000 --- a/drivers/media/dvb/ttpci/budget-core.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * budget-core.c: driver for the SAA7146 based Budget DVB cards - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * 26feb2004 Support for FS Activy Card (Grundig tuner) by - * Michael Dreher <michael@5dot1.de>, - * Oliver Endriss <o.endriss@gmx.de>, - * Andreas 'randy' Weinberger - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - - -#include "budget.h" -#include "ttpci-eeprom.h" - -#define TS_WIDTH (2 * TS_SIZE) -#define TS_WIDTH_ACTIVY TS_SIZE -#define TS_WIDTH_DVBC TS_SIZE -#define TS_HEIGHT_MASK 0xf00 -#define TS_HEIGHT_MASK_ACTIVY 0xc00 -#define TS_HEIGHT_MASK_DVBC 0xe00 -#define TS_MIN_BUFSIZE_K 188 -#define TS_MAX_BUFSIZE_K 1410 -#define TS_MAX_BUFSIZE_K_ACTIVY 564 -#define TS_MAX_BUFSIZE_K_DVBC 1316 -#define BUFFER_WARNING_WAIT (30*HZ) - -int budget_debug; -static int dma_buffer_size = TS_MIN_BUFSIZE_K; -module_param_named(debug, budget_debug, int, 0644); -module_param_named(bufsize, dma_buffer_size, int, 0444); -MODULE_PARM_DESC(debug, "Turn on/off budget debugging (default:off)."); -MODULE_PARM_DESC(bufsize, "DMA buffer size in KB, default: 188, min: 188, max: 1410 (Activy: 564)"); - -/**************************************************************************** - * TT budget / WinTV Nova - ****************************************************************************/ - -static int stop_ts_capture(struct budget *budget) -{ - dprintk(2, "budget: %p\n", budget); - - saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off - SAA7146_IER_DISABLE(budget->dev, MASK_10); - return 0; -} - -static int start_ts_capture(struct budget *budget) -{ - struct saa7146_dev *dev = budget->dev; - - dprintk(2, "budget: %p\n", budget); - - if (!budget->feeding || !budget->fe_synced) - return 0; - - saa7146_write(dev, MC1, MASK_20); // DMA3 off - - memset(budget->grabbing, 0x00, budget->buffer_size); - - saa7146_write(dev, PCI_BT_V1, 0x001c0000 | (saa7146_read(dev, PCI_BT_V1) & ~0x001f0000)); - - budget->ttbp = 0; - - /* - * Signal path on the Activy: - * - * tuner -> SAA7146 port A -> SAA7146 BRS -> SAA7146 DMA3 -> memory - * - * Since the tuner feeds 204 bytes packets into the SAA7146, - * DMA3 is configured to strip the trailing 16 FEC bytes: - * Pitch: 188, NumBytes3: 188, NumLines3: 1024 - */ - - switch(budget->card->type) { - case BUDGET_FS_ACTIVY: - saa7146_write(dev, DD1_INIT, 0x04000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25)); - saa7146_write(dev, BRS_CTRL, 0x00000000); - break; - case BUDGET_PATCH: - saa7146_write(dev, DD1_INIT, 0x00000200); - saa7146_write(dev, MC2, (MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - break; - case BUDGET_CIN1200C_MK3: - case BUDGET_KNC1C_MK3: - case BUDGET_KNC1CP_MK3: - if (budget->video_port == BUDGET_VIDEO_PORTA) { - saa7146_write(dev, DD1_INIT, 0x06000200); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x00000000); - } else { - saa7146_write(dev, DD1_INIT, 0x00000600); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - } - break; - default: - if (budget->video_port == BUDGET_VIDEO_PORTA) { - saa7146_write(dev, DD1_INIT, 0x06000200); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x00000000); - } else { - saa7146_write(dev, DD1_INIT, 0x02000600); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - saa7146_write(dev, BRS_CTRL, 0x60000000); - } - } - - saa7146_write(dev, MC2, (MASK_08 | MASK_24)); - mdelay(10); - - saa7146_write(dev, BASE_ODD3, 0); - if (budget->buffer_size > budget->buffer_height * budget->buffer_width) { - // using odd/even buffers - saa7146_write(dev, BASE_EVEN3, budget->buffer_height * budget->buffer_width); - } else { - // using a single buffer - saa7146_write(dev, BASE_EVEN3, 0); - } - saa7146_write(dev, PROT_ADDR3, budget->buffer_size); - saa7146_write(dev, BASE_PAGE3, budget->pt.dma | ME1 | 0x90); - - saa7146_write(dev, PITCH3, budget->buffer_width); - saa7146_write(dev, NUM_LINE_BYTE3, - (budget->buffer_height << 16) | budget->buffer_width); - - saa7146_write(dev, MC2, (MASK_04 | MASK_20)); - - SAA7146_ISR_CLEAR(budget->dev, MASK_10); /* VPE */ - SAA7146_IER_ENABLE(budget->dev, MASK_10); /* VPE */ - saa7146_write(dev, MC1, (MASK_04 | MASK_20)); /* DMA3 on */ - - return 0; -} - -static int budget_read_fe_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct budget *budget = (struct budget *) fe->dvb->priv; - int synced; - int ret; - - if (budget->read_fe_status) - ret = budget->read_fe_status(fe, status); - else - ret = -EINVAL; - - if (!ret) { - synced = (*status & FE_HAS_LOCK); - if (synced != budget->fe_synced) { - budget->fe_synced = synced; - spin_lock(&budget->feedlock); - if (synced) - start_ts_capture(budget); - else - stop_ts_capture(budget); - spin_unlock(&budget->feedlock); - } - } - return ret; -} - -static void vpeirq(unsigned long data) -{ - struct budget *budget = (struct budget *) data; - u8 *mem = (u8 *) (budget->grabbing); - u32 olddma = budget->ttbp; - u32 newdma = saa7146_read(budget->dev, PCI_VDP3); - u32 count; - - /* Ensure streamed PCI data is synced to CPU */ - pci_dma_sync_sg_for_cpu(budget->dev->pci, budget->pt.slist, budget->pt.nents, PCI_DMA_FROMDEVICE); - - /* nearest lower position divisible by 188 */ - newdma -= newdma % 188; - - if (newdma >= budget->buffer_size) - return; - - budget->ttbp = newdma; - - if (budget->feeding == 0 || newdma == olddma) - return; - - if (newdma > olddma) { /* no wraparound, dump olddma..newdma */ - count = newdma - olddma; - dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); - } else { /* wraparound, dump olddma..buflen and 0..newdma */ - count = budget->buffer_size - olddma; - dvb_dmx_swfilter_packets(&budget->demux, mem + olddma, count / 188); - count += newdma; - dvb_dmx_swfilter_packets(&budget->demux, mem, newdma / 188); - } - - if (count > budget->buffer_warning_threshold) - budget->buffer_warnings++; - - if (budget->buffer_warnings && time_after(jiffies, budget->buffer_warning_time)) { - printk("%s %s: used %d times >80%% of buffer (%u bytes now)\n", - budget->dev->name, __func__, budget->buffer_warnings, count); - budget->buffer_warning_time = jiffies + BUFFER_WARNING_WAIT; - budget->buffer_warnings = 0; - } -} - - -int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, - int uselocks, int nobusyloop) -{ - struct saa7146_dev *saa = budget->dev; - int result = 0; - unsigned long flags = 0; - - if (count > 4 || count <= 0) - return 0; - - if (uselocks) - spin_lock_irqsave(&budget->debilock, flags); - - if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { - if (uselocks) - spin_unlock_irqrestore(&budget->debilock, flags); - return result; - } - - saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x10000 | (addr & 0xffff)); - saa7146_write(saa, DEBI_CONFIG, config); - saa7146_write(saa, DEBI_PAGE, 0); - saa7146_write(saa, MC2, (2 << 16) | 2); - - if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { - if (uselocks) - spin_unlock_irqrestore(&budget->debilock, flags); - return result; - } - - result = saa7146_read(saa, DEBI_AD); - result &= (0xffffffffUL >> ((4 - count) * 8)); - - if (uselocks) - spin_unlock_irqrestore(&budget->debilock, flags); - - return result; -} - -int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, - int count, u32 value, int uselocks, int nobusyloop) -{ - struct saa7146_dev *saa = budget->dev; - unsigned long flags = 0; - int result; - - if (count > 4 || count <= 0) - return 0; - - if (uselocks) - spin_lock_irqsave(&budget->debilock, flags); - - if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { - if (uselocks) - spin_unlock_irqrestore(&budget->debilock, flags); - return result; - } - - saa7146_write(saa, DEBI_COMMAND, (count << 17) | 0x00000 | (addr & 0xffff)); - saa7146_write(saa, DEBI_CONFIG, config); - saa7146_write(saa, DEBI_PAGE, 0); - saa7146_write(saa, DEBI_AD, value); - saa7146_write(saa, MC2, (2 << 16) | 2); - - if ((result = saa7146_wait_for_debi_done(saa, nobusyloop)) < 0) { - if (uselocks) - spin_unlock_irqrestore(&budget->debilock, flags); - return result; - } - - if (uselocks) - spin_unlock_irqrestore(&budget->debilock, flags); - return 0; -} - - -/**************************************************************************** - * DVB API SECTION - ****************************************************************************/ - -static int budget_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct budget *budget = (struct budget *) demux->priv; - int status = 0; - - dprintk(2, "budget: %p\n", budget); - - if (!demux->dmx.frontend) - return -EINVAL; - - spin_lock(&budget->feedlock); - feed->pusi_seen = 0; /* have a clean section start */ - if (budget->feeding++ == 0) - status = start_ts_capture(budget); - spin_unlock(&budget->feedlock); - return status; -} - -static int budget_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct budget *budget = (struct budget *) demux->priv; - int status = 0; - - dprintk(2, "budget: %p\n", budget); - - spin_lock(&budget->feedlock); - if (--budget->feeding == 0) - status = stop_ts_capture(budget); - spin_unlock(&budget->feedlock); - return status; -} - -static int budget_register(struct budget *budget) -{ - struct dvb_demux *dvbdemux = &budget->demux; - int ret; - - dprintk(2, "budget: %p\n", budget); - - dvbdemux->priv = (void *) budget; - - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = budget_start_feed; - dvbdemux->stop_feed = budget_stop_feed; - dvbdemux->write_to_decoder = NULL; - - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - - dvb_dmx_init(&budget->demux); - - budget->dmxdev.filternum = 256; - budget->dmxdev.demux = &dvbdemux->dmx; - budget->dmxdev.capabilities = 0; - - dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter); - - budget->hw_frontend.source = DMX_FRONTEND_0; - - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->hw_frontend); - - if (ret < 0) - return ret; - - budget->mem_frontend.source = DMX_MEMORY_FE; - ret = dvbdemux->dmx.add_frontend(&dvbdemux->dmx, &budget->mem_frontend); - if (ret < 0) - return ret; - - ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &budget->hw_frontend); - if (ret < 0) - return ret; - - dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx); - - return 0; -} - -static void budget_unregister(struct budget *budget) -{ - struct dvb_demux *dvbdemux = &budget->demux; - - dprintk(2, "budget: %p\n", budget); - - dvb_net_release(&budget->dvb_net); - - dvbdemux->dmx.close(&dvbdemux->dmx); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->hw_frontend); - dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &budget->mem_frontend); - - dvb_dmxdev_release(&budget->dmxdev); - dvb_dmx_release(&budget->demux); -} - -int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, - struct saa7146_pci_extension_data *info, - struct module *owner, short *adapter_nums) -{ - int ret = 0; - struct budget_info *bi = info->ext_priv; - int max_bufsize; - int height_mask; - - memset(budget, 0, sizeof(struct budget)); - - dprintk(2, "dev: %p, budget: %p\n", dev, budget); - - budget->card = bi; - budget->dev = (struct saa7146_dev *) dev; - - switch(budget->card->type) { - case BUDGET_FS_ACTIVY: - budget->buffer_width = TS_WIDTH_ACTIVY; - max_bufsize = TS_MAX_BUFSIZE_K_ACTIVY; - height_mask = TS_HEIGHT_MASK_ACTIVY; - break; - - case BUDGET_KNC1C: - case BUDGET_KNC1CP: - case BUDGET_CIN1200C: - case BUDGET_KNC1C_MK3: - case BUDGET_KNC1CP_MK3: - case BUDGET_CIN1200C_MK3: - budget->buffer_width = TS_WIDTH_DVBC; - max_bufsize = TS_MAX_BUFSIZE_K_DVBC; - height_mask = TS_HEIGHT_MASK_DVBC; - break; - - default: - budget->buffer_width = TS_WIDTH; - max_bufsize = TS_MAX_BUFSIZE_K; - height_mask = TS_HEIGHT_MASK; - } - - if (dma_buffer_size < TS_MIN_BUFSIZE_K) - dma_buffer_size = TS_MIN_BUFSIZE_K; - else if (dma_buffer_size > max_bufsize) - dma_buffer_size = max_bufsize; - - budget->buffer_height = dma_buffer_size * 1024 / budget->buffer_width; - if (budget->buffer_height > 0xfff) { - budget->buffer_height /= 2; - budget->buffer_height &= height_mask; - budget->buffer_size = 2 * budget->buffer_height * budget->buffer_width; - } else { - budget->buffer_height &= height_mask; - budget->buffer_size = budget->buffer_height * budget->buffer_width; - } - budget->buffer_warning_threshold = budget->buffer_size * 80/100; - budget->buffer_warnings = 0; - budget->buffer_warning_time = jiffies; - - dprintk(2, "%s: buffer type = %s, width = %d, height = %d\n", - budget->dev->name, - budget->buffer_size > budget->buffer_width * budget->buffer_height ? "odd/even" : "single", - budget->buffer_width, budget->buffer_height); - printk("%s: dma buffer size %u\n", budget->dev->name, budget->buffer_size); - - ret = dvb_register_adapter(&budget->dvb_adapter, budget->card->name, - owner, &budget->dev->pci->dev, adapter_nums); - if (ret < 0) - return ret; - - /* set dd1 stream a & b */ - saa7146_write(dev, DD1_STREAM_B, 0x00000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25)); - saa7146_write(dev, MC2, (MASK_10 | MASK_26)); - saa7146_write(dev, DD1_INIT, 0x02000000); - saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - if (bi->type != BUDGET_FS_ACTIVY) - budget->video_port = BUDGET_VIDEO_PORTB; - else - budget->video_port = BUDGET_VIDEO_PORTA; - spin_lock_init(&budget->feedlock); - spin_lock_init(&budget->debilock); - - /* the Siemens DVB needs this if you want to have the i2c chips - get recognized before the main driver is loaded */ - if (bi->type != BUDGET_FS_ACTIVY) - saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ - - budget->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - - strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name)); - - saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); - strcpy(budget->i2c_adap.name, budget->card->name); - - if (i2c_add_adapter(&budget->i2c_adap) < 0) { - ret = -ENOMEM; - goto err_dvb_unregister; - } - - ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); - - budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, budget->buffer_size, &budget->pt); - if (NULL == budget->grabbing) { - ret = -ENOMEM; - goto err_del_i2c; - } - - saa7146_write(dev, PCI_BT_V1, 0x001c0000); - /* upload all */ - saa7146_write(dev, GPIO_CTRL, 0x000000); - - tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); - - /* frontend power on */ - if (bi->type != BUDGET_FS_ACTIVY) - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - - if ((ret = budget_register(budget)) == 0) - return 0; /* Everything OK */ - - /* An error occurred, cleanup resources */ - saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); - -err_del_i2c: - i2c_del_adapter(&budget->i2c_adap); - -err_dvb_unregister: - dvb_unregister_adapter(&budget->dvb_adapter); - - return ret; -} - -void ttpci_budget_init_hooks(struct budget *budget) -{ - if (budget->dvb_frontend && !budget->read_fe_status) { - budget->read_fe_status = budget->dvb_frontend->ops.read_status; - budget->dvb_frontend->ops.read_status = budget_read_fe_status; - } -} - -int ttpci_budget_deinit(struct budget *budget) -{ - struct saa7146_dev *dev = budget->dev; - - dprintk(2, "budget: %p\n", budget); - - budget_unregister(budget); - - tasklet_kill(&budget->vpe_tasklet); - - saa7146_vfree_destroy_pgtable(dev->pci, budget->grabbing, &budget->pt); - - i2c_del_adapter(&budget->i2c_adap); - - dvb_unregister_adapter(&budget->dvb_adapter); - - return 0; -} - -void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr) -{ - struct budget *budget = (struct budget *) dev->ext_priv; - - dprintk(8, "dev: %p, budget: %p\n", dev, budget); - - if (*isr & MASK_10) - tasklet_schedule(&budget->vpe_tasklet); -} - -void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port) -{ - struct budget *budget = (struct budget *) dev->ext_priv; - - spin_lock(&budget->feedlock); - budget->video_port = video_port; - if (budget->feeding) { - stop_ts_capture(budget); - start_ts_capture(budget); - } - spin_unlock(&budget->feedlock); -} - -EXPORT_SYMBOL_GPL(ttpci_budget_debiread); -EXPORT_SYMBOL_GPL(ttpci_budget_debiwrite); -EXPORT_SYMBOL_GPL(ttpci_budget_init); -EXPORT_SYMBOL_GPL(ttpci_budget_init_hooks); -EXPORT_SYMBOL_GPL(ttpci_budget_deinit); -EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); -EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); -EXPORT_SYMBOL_GPL(budget_debug); - -MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c deleted file mode 100644 index 60136688a9a..00000000000 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * budget-patch.c: driver for Budget Patch, - * hardware modification of DVB-S cards enabling full TS - * - * Written by Emard <emard@softhome.net> - * - * Original idea by Roberto Deza <rdeza@unav.es> - * - * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic - * and Metzlerbros - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include "av7110.h" -#include "av7110_hw.h" -#include "budget.h" -#include "stv0299.h" -#include "ves1x93.h" -#include "tda8083.h" - -#include "bsru6.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define budget_patch budget - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH); -//MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC); - -static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000), -// MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), - { - .vendor = 0, - } -}; - -/* those lines are for budget-patch to be tried -** on a true budget card and observe the -** behaviour of VSYNC generated by rps1. -** this code was shamelessly copy/pasted from budget.c -*/ -static void gpio_Set22K (struct budget *budget, int state) -{ - struct saa7146_dev *dev=budget->dev; - dprintk(2, "budget: %p\n", budget); - saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); -} - -/* Diseqc functions only for TT Budget card */ -/* taken from the Skyvision DVB driver by - Ralph Metzler <rjkm@metzlerbros.de> */ - -static void DiseqcSendBit (struct budget *budget, int data) -{ - struct saa7146_dev *dev=budget->dev; - dprintk(2, "budget: %p\n", budget); - - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - udelay(data ? 500 : 1000); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - udelay(data ? 1000 : 500); -} - -static void DiseqcSendByte (struct budget *budget, int data) -{ - int i, par=1, d; - - dprintk(2, "budget: %p\n", budget); - - for (i=7; i>=0; i--) { - d = (data>>i)&1; - par ^= d; - DiseqcSendBit(budget, d); - } - - DiseqcSendBit(budget, par); -} - -static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) -{ - struct saa7146_dev *dev=budget->dev; - int i; - - dprintk(2, "budget: %p\n", budget); - - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - mdelay(16); - - for (i=0; i<len; i++) - DiseqcSendByte(budget, msg[i]); - - mdelay(16); - - if (burst!=-1) { - if (burst) - DiseqcSendByte(budget, 0xff); - else { - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - mdelay(12); - udelay(500); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - } - msleep(20); - } - - return 0; -} - -/* shamelessly copy/pasted from budget.c -*/ -static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - switch (tone) { - case SEC_TONE_ON: - gpio_Set22K (budget, 1); - break; - - case SEC_TONE_OFF: - gpio_Set22K (budget, 0); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); - - return 0; -} - -static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - SendDiSEqCMsg (budget, 0, NULL, minicmd); - - return 0; -} - -static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length) -{ - int i; - - dprintk(2, "budget: %p\n", budget); - - for (i = 2; i < length; i++) - { - ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0); - msleep(5); - } - if (length) - ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0); - else - ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0); - msleep(5); - ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0); - msleep(5); - return 0; -} - -static void av7110_set22k(struct budget_patch *budget, int state) -{ - u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0}; - - dprintk(2, "budget: %p\n", budget); - budget_av7110_send_fw_cmd(budget, buf, 2); -} - -static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst) -{ - int i; - u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC), - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - dprintk(2, "budget: %p\n", budget); - - if (len>10) - len=10; - - buf[1] = len+2; - buf[2] = len; - - if (burst != -1) - buf[3]=burst ? 0x01 : 0x00; - else - buf[3]=0xffff; - - for (i=0; i<len; i++) - buf[i+4]=msg[i]; - - budget_av7110_send_fw_cmd(budget, buf, 18); - return 0; -} - -static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; - - switch (tone) { - case SEC_TONE_ON: - av7110_set22k (budget, 1); - break; - - case SEC_TONE_OFF: - av7110_set22k (budget, 0); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) -{ - struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; - - av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0); - - return 0; -} - -static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; - - av7110_send_diseqc_msg (budget, 0, NULL, minicmd); - - return 0; -} - -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; - u8 pwr = 0; - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; - - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; - else pwr = 2; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = ((div & 0x18000) >> 10) | 0x95; - buf[3] = (pwr << 6) | 0x30; - - // NOTE: since we're using a prescaler of 2, we set the - // divisor frequency to 62.5kHz and divide by 125 above - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct ves1x93_config alps_bsrv2_config = { - .demod_address = 0x08, - .xin = 90100000UL, - .invert_pwm = 0, -}; - -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = params->frequency / 125; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = 0x00; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) - return -EIO; - return 0; -} - -static struct tda8083_config grundig_29504_451_config = { - .demod_address = 0x68, -}; - -static void frontend_init(struct budget_patch* budget) -{ - switch(budget->dev->pci->subsystem_device) { - case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X - case 0x1013: // SATELCO Multimedia PCI - - // try the ALPS BSRV2 first of all - budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_patch_set_tone; - break; - } - - // try the ALPS BSRU6 now - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - break; - } - - // Try the grundig 29504-451 - budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - break; - } - break; - } - - if (budget->dvb_frontend == NULL) { - printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - budget->dev->pci->vendor, - budget->dev->pci->device, - budget->dev->pci->subsystem_vendor, - budget->dev->pci->subsystem_device); - } else { - if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { - printk("budget-av: Frontend registration failed!\n"); - dvb_frontend_detach(budget->dvb_frontend); - budget->dvb_frontend = NULL; - } - } -} - -/* written by Emard */ -static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) -{ - struct budget_patch *budget; - int err; - int count = 0; - int detected = 0; - -#define PATCH_RESET 0 -#define RPS_IRQ 0 -#define HPS_SETUP 0 -#if PATCH_RESET - saa7146_write(dev, MC1, MASK_31); - msleep(40); -#endif -#if HPS_SETUP - // initialize registers. Better to have it like this - // than leaving something unconfigured - saa7146_write(dev, DD1_STREAM_B, 0); - // port B VSYNC at rising edge - saa7146_write(dev, DD1_INIT, 0x00000200); // have this in budget-core too! - saa7146_write(dev, BRS_CTRL, 0x00000000); // VBI - - // debi config - // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18); - - // zero all HPS registers - saa7146_write(dev, HPS_H_PRESCALE, 0); // r68 - saa7146_write(dev, HPS_H_SCALE, 0); // r6c - saa7146_write(dev, BCS_CTRL, 0); // r70 - saa7146_write(dev, HPS_V_SCALE, 0); // r60 - saa7146_write(dev, HPS_V_GAIN, 0); // r64 - saa7146_write(dev, CHROMA_KEY_RANGE, 0); // r74 - saa7146_write(dev, CLIP_FORMAT_CTRL, 0); // r78 - // Set HPS prescaler for port B input - saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) ); - saa7146_write(dev, MC2, - 0 * (MASK_08 | MASK_24) | // BRS control - 0 * (MASK_09 | MASK_25) | // a - 0 * (MASK_10 | MASK_26) | // b - 1 * (MASK_06 | MASK_22) | // HPS_CTRL1 - 1 * (MASK_05 | MASK_21) | // HPS_CTRL2 - 0 * (MASK_01 | MASK_15) // DEBI - ); -#endif - // Disable RPS1 and RPS0 - saa7146_write(dev, MC1, ( MASK_29 | MASK_28)); - // RPS1 timeout disable - saa7146_write(dev, RPS_TOV1, 0); - - // code for autodetection - // will wait for VBI_B event (vertical blank at port B) - // and will reset GPIO3 after VBI_B is detected. - // (GPIO3 should be raised high by CPU to - // test if GPIO3 will generate vertical blank signal - // in budget patch GPIO3 is connected to VSYNC_B - count = 0; -#if 0 - WRITE_RPS1(CMD_UPLOAD | - MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ); -#endif - WRITE_RPS1(CMD_PAUSE | EVT_VBI_B); - WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - WRITE_RPS1(GPIO3_MSK); - WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); -#if RPS_IRQ - // issue RPS1 interrupt to increment counter - WRITE_RPS1(CMD_INTERRUPT); - // at least a NOP is neede between two interrupts - WRITE_RPS1(CMD_NOP); - // interrupt again - WRITE_RPS1(CMD_INTERRUPT); -#endif - WRITE_RPS1(CMD_STOP); - -#if RPS_IRQ - // set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) - // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled - // use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called - saa7146_write(dev, EC1SSR, (0x03<<2) | 3 ); - // set event counter 1 treshold to maximum allowed value (rEC p55) - saa7146_write(dev, ECT1R, 0x3fff ); -#endif - // Fix VSYNC level - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - // Set RPS1 Address register to point to RPS code (r108 p42) - saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - // Enable RPS1, (rFC p33) - saa7146_write(dev, MC1, (MASK_13 | MASK_29 )); - - - mdelay(50); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - mdelay(150); - - - if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0) - detected = 1; - -#if RPS_IRQ - printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff ); -#endif - // Disable RPS1 - saa7146_write(dev, MC1, ( MASK_29 )); - - if(detected == 0) - printk("budget-patch not detected or saa7146 in non-default state.\n" - "try enabling ressetting of 7146 with MASK_31 in MC1 register\n"); - - else - printk("BUDGET-PATCH DETECTED.\n"); - - -/* OLD (Original design by Roberto Deza): -** This code will setup the SAA7146_RPS1 to generate a square -** wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of -** TS_WIDTH packets) has been acquired on SAA7146_D1B video port; -** then, this GPIO3 output which is connected to the D1B_VSYNC -** input, will trigger the acquisition of the alternate field -** and so on. -** Currently, the TT_budget / WinTV_Nova cards have two ICs -** (74HCT4040, LVC74) for the generation of this VSYNC signal, -** which seems that can be done perfectly without this :-)). -*/ - -/* New design (By Emard) -** this rps1 code will copy internal HS event to GPIO3 pin. -** GPIO3 is in budget-patch hardware connected to port B VSYNC - -** HS is an internal event of 7146, accessible with RPS -** and temporarily raised high every n lines -** (n in defined in the RPS_THRESH1 counter threshold) -** I think HS is raised high on the beginning of the n-th line -** and remains high until this n-th line that triggered -** it is completely received. When the reception of n-th line -** ends, HS is lowered. - -** To transmit data over DMA, 7146 needs changing state at -** port B VSYNC pin. Any changing of port B VSYNC will -** cause some DMA data transfer, with more or less packets loss. -** It depends on the phase and frequency of VSYNC and -** the way of 7146 is instructed to trigger on port B (defined -** in DD1_INIT register, 3rd nibble from the right valid -** numbers are 0-7, see datasheet) -** -** The correct triggering can minimize packet loss, -** dvbtraffic should give this stable bandwidths: -** 22k transponder = 33814 kbit/s -** 27.5k transponder = 38045 kbit/s -** by experiment it is found that the best results -** (stable bandwidths and almost no packet loss) -** are obtained using DD1_INIT triggering number 2 -** (Va at rising edge of VS Fa = HS x VS-failing forced toggle) -** and a VSYNC phase that occurs in the middle of DMA transfer -** (about byte 188*512=96256 in the DMA window). -** -** Phase of HS is still not clear to me how to control, -** It just happens to be so. It can be seen if one enables -** RPS_IRQ and print Event Counter 1 in vpeirq(). Every -** time RPS_INTERRUPT is called, the Event Counter 1 will -** increment. That's how the 7146 is programmed to do event -** counting in this budget-patch.c -** I *think* HPS setting has something to do with the phase -** of HS but I cant be 100% sure in that. - -** hardware debug note: a working budget card (including budget patch) -** with vpeirq() interrupt setup in mode "0x90" (every 64K) will -** generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes -** and that means 3*25=75 Hz of interrupt frequency, as seen by -** watch cat /proc/interrupts -** -** If this frequency is 3x lower (and data received in the DMA -** buffer don't start with 0x47, but in the middle of packets, -** whose lengths appear to be like 188 292 188 104 etc. -** this means VSYNC line is not connected in the hardware. -** (check soldering pcb and pins) -** The same behaviour of missing VSYNC can be duplicated on budget -** cards, by setting DD1_INIT trigger mode 7 in 3rd nibble. -*/ - - // Setup RPS1 "program" (p35) - count = 0; - - - // Wait Source Line Counter Threshold (p36) - WRITE_RPS1(CMD_PAUSE | EVT_HS); - // Set GPIO3=1 (p42) - WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - WRITE_RPS1(GPIO3_MSK); - WRITE_RPS1(SAA7146_GPIO_OUTHI<<24); -#if RPS_IRQ - // issue RPS1 interrupt - WRITE_RPS1(CMD_INTERRUPT); -#endif - // Wait reset Source Line Counter Threshold (p36) - WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS); - // Set GPIO3=0 (p42) - WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2)); - WRITE_RPS1(GPIO3_MSK); - WRITE_RPS1(SAA7146_GPIO_OUTLO<<24); -#if RPS_IRQ - // issue RPS1 interrupt - WRITE_RPS1(CMD_INTERRUPT); -#endif - // Jump to begin of RPS program (p37) - WRITE_RPS1(CMD_JUMP); - WRITE_RPS1(dev->d_rps1.dma_handle); - - // Fix VSYNC level - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - // Set RPS1 Address register to point to RPS code (r108 p42) - saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle); - - if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL))) - return -ENOMEM; - - dprintk(2, "budget: %p\n", budget); - - err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); - if (err) { - kfree(budget); - return err; - } - - // Set Source Line Counter Threshold, using BRS (rCC p43) - // It generates HS event every TS_HEIGHT lines - // this is related to TS_WIDTH set in register - // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE - // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188 - //,then RPS_THRESH1 - // should be set to trigger every TS_HEIGHT (512) lines. - // - saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 ); - - // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 ); - // Enable RPS1 (rFC p33) - saa7146_write(dev, MC1, (MASK_13 | MASK_29)); - - - dev->ext_priv = budget; - - budget->dvb_adapter.priv = budget; - frontend_init(budget); - - ttpci_budget_init_hooks(budget); - - return 0; -} - -static int budget_patch_detach (struct saa7146_dev* dev) -{ - struct budget_patch *budget = (struct budget_patch*) dev->ext_priv; - int err; - - if (budget->dvb_frontend) { - dvb_unregister_frontend(budget->dvb_frontend); - dvb_frontend_detach(budget->dvb_frontend); - } - err = ttpci_budget_deinit (budget); - - kfree (budget); - - return err; -} - -static int __init budget_patch_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_patch_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -static struct saa7146_extension budget_extension = { - .name = "budget_patch dvb", - .flags = 0, - - .module = THIS_MODULE, - .pci_tbl = pci_tbl, - .attach = budget_patch_attach, - .detach = budget_patch_detach, - - .irq_mask = MASK_10, - .irq_func = ttpci_budget_irq10_handler, -}; - -module_init(budget_patch_init); -module_exit(budget_patch_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others"); -MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 " - "based so-called Budget Patch cards"); diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c deleted file mode 100644 index 1638e1d9f53..00000000000 --- a/drivers/media/dvb/ttpci/budget.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * budget.c: driver for the SAA7146 based Budget DVB cards - * - * Compiled from various sources by Michael Hunold <michael@mihu.de> - * - * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> - * - * Copyright (C) 1999-2002 Ralph Metzler - * & Marcus Metzler for convergence integrated media GmbH - * - * 26feb2004 Support for FS Activy Card (Grundig tuner) by - * Michael Dreher <michael@5dot1.de>, - * Oliver Endriss <o.endriss@gmx.de> and - * Andreas 'randy' Weinberger - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * Or, point your browser to http://www.gnu.org/copyleft/gpl.html - * - * - * the project's page is at http://www.linuxtv.org/dvb/ - */ - -#include "budget.h" -#include "stv0299.h" -#include "ves1x93.h" -#include "ves1820.h" -#include "l64781.h" -#include "tda8083.h" -#include "s5h1420.h" -#include "tda10086.h" -#include "tda826x.h" -#include "lnbp21.h" -#include "bsru6.h" -#include "bsbe1.h" -#include "tdhd1.h" - -static int diseqc_method; -module_param(diseqc_method, int, 0444); -MODULE_PARM_DESC(diseqc_method, "Select DiSEqC method for subsystem id 13c2:1003, 0: default, 1: more reliable (for newer revisions only)"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -static void Set22K (struct budget *budget, int state) -{ - struct saa7146_dev *dev=budget->dev; - dprintk(2, "budget: %p\n", budget); - saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); -} - -/* Diseqc functions only for TT Budget card */ -/* taken from the Skyvision DVB driver by - Ralph Metzler <rjkm@metzlerbros.de> */ - -static void DiseqcSendBit (struct budget *budget, int data) -{ - struct saa7146_dev *dev=budget->dev; - dprintk(2, "budget: %p\n", budget); - - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - udelay(data ? 500 : 1000); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - udelay(data ? 1000 : 500); -} - -static void DiseqcSendByte (struct budget *budget, int data) -{ - int i, par=1, d; - - dprintk(2, "budget: %p\n", budget); - - for (i=7; i>=0; i--) { - d = (data>>i)&1; - par ^= d; - DiseqcSendBit(budget, d); - } - - DiseqcSendBit(budget, par); -} - -static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) -{ - struct saa7146_dev *dev=budget->dev; - int i; - - dprintk(2, "budget: %p\n", budget); - - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - mdelay(16); - - for (i=0; i<len; i++) - DiseqcSendByte(budget, msg[i]); - - mdelay(16); - - if (burst!=-1) { - if (burst) - DiseqcSendByte(budget, 0xff); - else { - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); - mdelay(12); - udelay(500); - saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); - } - msleep(20); - } - - return 0; -} - -/* - * Routines for the Fujitsu Siemens Activy budget card - * 22 kHz tone and DiSEqC are handled by the frontend. - * Voltage must be set here. - * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL - */ -static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) -{ - struct saa7146_dev *dev=budget->dev; - - dprintk(2, "budget: %p\n", budget); - - switch (voltage) { - case SEC_VOLTAGE_13: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); - break; - case SEC_VOLTAGE_18: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); - saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); - break; - case SEC_VOLTAGE_OFF: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - return SetVoltage_Activy (budget, voltage); -} - -static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - switch (tone) { - case SEC_TONE_ON: - Set22K (budget, 1); - break; - - case SEC_TONE_OFF: - Set22K (budget, 0); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); - - return 0; -} - -static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - - SendDiSEqCMsg (budget, 0, NULL, minicmd); - - return 0; -} - -static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - u8 pwr = 0; - u8 buf[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; - u32 div = (params->frequency + 479500) / 125; - - if (params->frequency > 2000000) pwr = 3; - else if (params->frequency > 1800000) pwr = 2; - else if (params->frequency > 1600000) pwr = 1; - else if (params->frequency > 1200000) pwr = 0; - else if (params->frequency >= 1100000) pwr = 1; - else pwr = 2; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = ((div & 0x18000) >> 10) | 0x95; - buf[3] = (pwr << 6) | 0x30; - - // NOTE: since we're using a prescaler of 2, we set the - // divisor frequency to 62.5kHz and divide by 125 above - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct ves1x93_config alps_bsrv2_config = -{ - .demod_address = 0x08, - .xin = 90100000UL, - .invert_pwm = 0, -}; - -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (params->frequency + 35937500 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct ves1820_config alps_tdbe2_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, -}; - -static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget *budget = fe->dvb->priv; - u8 *tuner_addr = fe->tuner_priv; - u32 div; - u8 cfg, cpump, band_select; - u8 data[4]; - struct i2c_msg msg = { .flags = 0, .buf = data, .len = sizeof(data) }; - - if (tuner_addr) - msg.addr = *tuner_addr; - else - msg.addr = 0x61; - - div = (36125000 + params->frequency) / 166666; - - cfg = 0x88; - - if (params->frequency < 175000000) cpump = 2; - else if (params->frequency < 390000000) cpump = 1; - else if (params->frequency < 470000000) cpump = 2; - else if (params->frequency < 750000000) cpump = 1; - else cpump = 3; - - if (params->frequency < 175000000) band_select = 0x0e; - else if (params->frequency < 470000000) band_select = 0x05; - else band_select = 0x03; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = ((div >> 10) & 0x60) | cfg; - data[3] = (cpump << 6) | band_select; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct l64781_config grundig_29504_401_config = { - .demod_address = 0x55, -}; - -static struct l64781_config grundig_29504_401_config_activy = { - .demod_address = 0x54, -}; - -static u8 tuner_address_grundig_29504_401_activy = 0x60; - -static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = params->frequency / 125; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x8e; - data[3] = 0x00; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct tda8083_config grundig_29504_451_config = { - .demod_address = 0x68, -}; - -static int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct budget* budget = (struct budget*) fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = params->frequency / 1000; - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0xc2; - - if (div < 1450) - data[3] = 0x00; - else if (div < 1850) - data[3] = 0x40; - else if (div < 2000) - data[3] = 0x80; - else - data[3] = 0xc0; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; - - return 0; -} - -static struct s5h1420_config s5h1420_config = { - .demod_address = 0x53, - .invert = 1, - .cdclk_polarity = 1, -}; - -static struct tda10086_config tda10086_config = { - .demod_address = 0x0e, - .invert = 0, - .diseqc_tone = 1, - .xtal_freq = TDA10086_XTAL_16M, -}; - -static struct stv0299_config alps_bsru6_config_activy = { - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .op0_off = 1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsru6_set_symbol_rate, -}; - -static struct stv0299_config alps_bsbe1_config_activy = { - .demod_address = 0x68, - .inittab = alps_bsbe1_inittab, - .mclk = 88000000UL, - .invert = 1, - .op0_off = 1, - .min_delay_ms = 100, - .set_symbol_rate = alps_bsbe1_set_symbol_rate, -}; - -static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) -{ - struct budget *budget = (struct budget *)fe->dvb->priv; - - return request_firmware(fw, name, &budget->dev->pci->dev); -} - - -static int i2c_readreg(struct i2c_adapter *i2c, u8 adr, u8 reg) -{ - u8 val; - struct i2c_msg msg[] = { - { .addr = adr, .flags = 0, .buf = ®, .len = 1 }, - { .addr = adr, .flags = I2C_M_RD, .buf = &val, .len = 1 } - }; - - return (i2c_transfer(i2c, msg, 2) != 2) ? -EIO : val; -} - -static u8 read_pwm(struct budget* budget) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, - { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; - - if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - -static void frontend_init(struct budget *budget) -{ - (void)alps_bsbe1_config; /* avoid warning */ - - switch(budget->dev->pci->subsystem_device) { - case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) - case 0x1013: - // try the ALPS BSRV2 first of all - budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - break; - } - - // try the ALPS BSRU6 now - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - if (budget->dev->pci->subsystem_device == 0x1003 && diseqc_method == 0) { - budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; - budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; - budget->dvb_frontend->ops.set_tone = budget_set_tone; - } - break; - } - break; - - case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) - - budget->dvb_frontend = dvb_attach(ves1820_attach, &alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - break; - } - break; - - case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) - - budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - break; - } - break; - - case 0x4f60: /* Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/tsa5059) */ - { - int subtype = i2c_readreg(&budget->i2c_adap, 0x50, 0x67); - - if (subtype < 0) - break; - /* fixme: find a better way to identify the card */ - if (subtype < 0x36) { - /* assume ALPS BSRU6 */ - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config_activy, &budget->i2c_adap); - if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSRU6 detected\n"); - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - break; - } - } else { - /* assume ALPS BSBE1 */ - /* reset tuner */ - saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTLO); - msleep(50); - saa7146_setgpio(budget->dev, 3, SAA7146_GPIO_OUTHI); - msleep(250); - budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsbe1_config_activy, &budget->i2c_adap); - if (budget->dvb_frontend) { - printk(KERN_INFO "budget: tuner ALPS BSBE1 detected\n"); - budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsbe1_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - break; - } - } - break; - } - - case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) - budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; - budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; - } - break; - - case 0x5f60: /* Fujitsu Siemens Activy Budget-T PCI rev AL (tda10046/ALPS TDHD1-204A) */ - budget->dvb_frontend = dvb_attach(tda10046_attach, &alps_tdhd1_204a_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdhd1_204a_tuner_set_params; - budget->dvb_frontend->tuner_priv = &budget->i2c_adap; - } - break; - - case 0x5f61: /* Fujitsu Siemens Activy Budget-T PCI rev GR (L64781/Grundig 29504-401(tsa5060)) */ - budget->dvb_frontend = dvb_attach(l64781_attach, &grundig_29504_401_config_activy, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->tuner_priv = &tuner_address_grundig_29504_401_activy; - budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; - } - break; - - case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) - budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; - if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); - goto error_out; - } - break; - } - - case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262) - // gpio2 is connected to CLB - reset it + leave it high - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); - msleep(1); - saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); - msleep(1); - - budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap); - if (budget->dvb_frontend) { - if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL) - printk("%s: No tda826x found!\n", __func__); - if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { - printk("%s: No LNBP21 found!\n", __func__); - goto error_out; - } - break; - } - } - - if (budget->dvb_frontend == NULL) { - printk("budget: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", - budget->dev->pci->vendor, - budget->dev->pci->device, - budget->dev->pci->subsystem_vendor, - budget->dev->pci->subsystem_device); - } else { - if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) - goto error_out; - } - return; - -error_out: - printk("budget: Frontend registration failed!\n"); - dvb_frontend_detach(budget->dvb_frontend); - budget->dvb_frontend = NULL; - return; -} - -static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) -{ - struct budget *budget = NULL; - int err; - - budget = kmalloc(sizeof(struct budget), GFP_KERNEL); - if( NULL == budget ) { - return -ENOMEM; - } - - dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget); - - dev->ext_priv = budget; - - err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr); - if (err) { - printk("==> failed\n"); - kfree (budget); - return err; - } - - budget->dvb_adapter.priv = budget; - frontend_init(budget); - - ttpci_budget_init_hooks(budget); - - return 0; -} - -static int budget_detach (struct saa7146_dev* dev) -{ - struct budget *budget = (struct budget*) dev->ext_priv; - int err; - - if (budget->dvb_frontend) { - dvb_unregister_frontend(budget->dvb_frontend); - dvb_frontend_detach(budget->dvb_frontend); - } - - err = ttpci_budget_deinit (budget); - - kfree (budget); - dev->ext_priv = NULL; - - return err; -} - -static struct saa7146_extension budget_extension; - -MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); -MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); -MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); -MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); -MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsact, "Fujitsu Siemens Activy Budget-T PCI (rev GR/Grundig frontend)", BUDGET_FS_ACTIVY); -MAKE_BUDGET_INFO(fsact1, "Fujitsu Siemens Activy Budget-T PCI (rev AL/ALPS TDHD1-204A)", BUDGET_FS_ACTIVY); - -static struct pci_device_id pci_tbl[] = { - MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), - MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), - MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), - MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), - MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), - MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), - MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), - MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), - MAKE_EXTENSION_PCI(fsact1, 0x1131, 0x5f60), - MAKE_EXTENSION_PCI(fsact, 0x1131, 0x5f61), - { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_extension budget_extension = { - .name = "budget dvb", - .flags = SAA7146_USE_I2C_IRQ, - - .module = THIS_MODULE, - .pci_tbl = pci_tbl, - .attach = budget_attach, - .detach = budget_detach, - - .irq_mask = MASK_10, - .irq_func = ttpci_budget_irq10_handler, -}; - -static int __init budget_init(void) -{ - return saa7146_register_extension(&budget_extension); -} - -static void __exit budget_exit(void) -{ - saa7146_unregister_extension(&budget_extension); -} - -module_init(budget_init); -module_exit(budget_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); -MODULE_DESCRIPTION("driver for the SAA7146 based so-called " - "budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h deleted file mode 100644 index 3ad0c6789ba..00000000000 --- a/drivers/media/dvb/ttpci/budget.h +++ /dev/null @@ -1,123 +0,0 @@ - -#ifndef __BUDGET_DVB__ -#define __BUDGET_DVB__ - -#include "dvb_frontend.h" -#include "dvbdev.h" -#include "demux.h" -#include "dvb_demux.h" -#include "dmxdev.h" -#include "dvb_filter.h" -#include "dvb_net.h" - -#include <linux/module.h> -#include <linux/mutex.h> - -#include <media/saa7146.h> - -extern int budget_debug; - -#ifdef dprintk -#undef dprintk -#endif - -#define dprintk(level,args...) \ - do { if ((budget_debug & level)) { printk("%s: %s(): ", KBUILD_MODNAME, __func__); printk(args); } } while (0) - -struct budget_info { - char *name; - int type; -}; - -/* place to store all the necessary device information */ -struct budget { - - /* devices */ - struct dvb_device dvb_dev; - struct dvb_net dvb_net; - - struct saa7146_dev *dev; - - struct i2c_adapter i2c_adap; - struct budget_info *card; - - unsigned char *grabbing; - struct saa7146_pgtable pt; - - struct tasklet_struct fidb_tasklet; - struct tasklet_struct vpe_tasklet; - - struct dmxdev dmxdev; - struct dvb_demux demux; - - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - - int ci_present; - int video_port; - - u32 buffer_width; - u32 buffer_height; - u32 buffer_size; - u32 buffer_warning_threshold; - u32 buffer_warnings; - unsigned long buffer_warning_time; - - u32 ttbp; - int feeding; - - spinlock_t feedlock; - - spinlock_t debilock; - - struct dvb_adapter dvb_adapter; - struct dvb_frontend *dvb_frontend; - int (*read_fe_status)(struct dvb_frontend *fe, fe_status_t *status); - int fe_synced; - - void *priv; -}; - -#define MAKE_BUDGET_INFO(x_var,x_name,x_type) \ -static struct budget_info x_var ## _info = { \ - .name=x_name, \ - .type=x_type }; \ -static struct saa7146_pci_extension_data x_var = { \ - .ext_priv = &x_var ## _info, \ - .ext = &budget_extension }; - -#define BUDGET_TT 0 -#define BUDGET_TT_HW_DISEQC 1 -#define BUDGET_PATCH 3 -#define BUDGET_FS_ACTIVY 4 -#define BUDGET_CIN1200S 5 -#define BUDGET_CIN1200C 6 -#define BUDGET_CIN1200T 7 -#define BUDGET_KNC1S 8 -#define BUDGET_KNC1C 9 -#define BUDGET_KNC1T 10 -#define BUDGET_KNC1SP 11 -#define BUDGET_KNC1CP 12 -#define BUDGET_KNC1TP 13 -#define BUDGET_TVSTAR 14 -#define BUDGET_CIN1200C_MK3 15 -#define BUDGET_KNC1C_MK3 16 -#define BUDGET_KNC1CP_MK3 17 -#define BUDGET_KNC1S2 18 - -#define BUDGET_VIDEO_PORTA 0 -#define BUDGET_VIDEO_PORTB 1 - -extern int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, - struct saa7146_pci_extension_data *info, - struct module *owner, short *adapter_nums); -extern void ttpci_budget_init_hooks(struct budget *budget); -extern int ttpci_budget_deinit(struct budget *budget); -extern void ttpci_budget_irq10_handler(struct saa7146_dev *dev, u32 * isr); -extern void ttpci_budget_set_video_port(struct saa7146_dev *dev, int video_port); -extern int ttpci_budget_debiread(struct budget *budget, u32 config, int addr, int count, - int uselocks, int nobusyloop); -extern int ttpci_budget_debiwrite(struct budget *budget, u32 config, int addr, int count, u32 value, - int uselocks, int nobusyloop); - -#endif diff --git a/drivers/media/dvb/ttpci/fdump.c b/drivers/media/dvb/ttpci/fdump.c deleted file mode 100644 index c90001d35e7..00000000000 --- a/drivers/media/dvb/ttpci/fdump.c +++ /dev/null @@ -1,44 +0,0 @@ -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -int main(int argc, char **argv) -{ - unsigned char buf[8]; - unsigned int i, count, bytes = 0; - FILE *fd_in, *fd_out; - - if (argc != 4) { - fprintf(stderr, "\n\tusage: %s <ucode.bin> <array_name> <output_name>\n\n", argv[0]); - return -1; - } - - fd_in = fopen(argv[1], "rb"); - if (fd_in == NULL) { - fprintf(stderr, "firmware file '%s' not found\n", argv[1]); - return -1; - } - - fd_out = fopen(argv[3], "w+"); - if (fd_out == NULL) { - fprintf(stderr, "cannot create output file '%s'\n", argv[3]); - return -1; - } - - fprintf(fd_out, "\n#include <asm/types.h>\n\nu8 %s [] = {", argv[2]); - - while ((count = fread(buf, 1, 8, fd_in)) > 0) { - fprintf(fd_out, "\n\t"); - for (i = 0; i < count; i++, bytes++) - fprintf(fd_out, "0x%02x, ", buf[i]); - } - - fprintf(fd_out, "\n};\n\n"); - - fclose(fd_in); - fclose(fd_out); - - return 0; -} diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c deleted file mode 100644 index 7dd54b3026a..00000000000 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - Retrieve encoded MAC address from 24C16 serial 2-wire EEPROM, - decode it and store it in the associated adapter struct for - use by dvb_net.c - - This card appear to have the 24C16 write protect held to ground, - thus permitting normal read/write operation. Theoretically it - would be possible to write routines to burn a different (encoded) - MAC address into the EEPROM. - - Robert Schlabbach GMX - Michael Glaum KVH Industries - Holger Waechtler Convergence - - Copyright (C) 2002-2003 Ralph Metzler <rjkm@metzlerbros.de> - Metzler Brothers Systementwicklung GbR - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#include <asm/errno.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/string.h> -#include <linux/i2c.h> - -#include "ttpci-eeprom.h" - -#if 1 -#define dprintk(x...) do { printk(x); } while (0) -#else -#define dprintk(x...) do { } while (0) -#endif - - -static int check_mac_tt(u8 *buf) -{ - int i; - u16 tmp = 0xffff; - - for (i = 0; i < 8; i++) { - tmp = (tmp << 8) | ((tmp >> 8) ^ buf[i]); - tmp ^= (tmp >> 4) & 0x0f; - tmp ^= (tmp << 12) ^ ((tmp & 0xff) << 5); - } - tmp ^= 0xffff; - return (((tmp >> 8) ^ buf[8]) | ((tmp & 0xff) ^ buf[9])); -} - -static int getmac_tt(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; - - /* In case there is a sig check failure have the orig contents available */ - 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; -} - -static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC) -{ - int ret; - u8 b0[] = { 0xcc }; - - struct i2c_msg msg[] = { - { .addr = 0x50, .flags = 0, .buf = b0, .len = 1 }, - { .addr = 0x50, .flags = I2C_M_RD, .buf = encodedMAC, .len = 20 } - }; - - /* dprintk("%s\n", __func__); */ - - ret = i2c_transfer(adapter, msg, 2); - - if (ret != 2) /* Assume EEPROM isn't there */ - return (-ENODEV); - - return 0; -} - - -int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac) -{ - int ret, i; - u8 encodedMAC[20]; - u8 decodedMAC[6]; - - ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC); - - if (ret != 0) { /* Will only be -ENODEV */ - dprintk("Couldn't read from EEPROM: not there?\n"); - memset(proposed_mac, 0, 6); - return ret; - } - - ret = getmac_tt(decodedMAC, encodedMAC); - if( ret != 0 ) { - dprintk("adapter failed MAC signature check\n"); - dprintk("encoded MAC from EEPROM was " ); - for(i=0; i<19; i++) { - dprintk( "%.2x:", encodedMAC[i]); - } - dprintk("%.2x\n", encodedMAC[19]); - memset(proposed_mac, 0, 6); - return ret; - } - - memcpy(proposed_mac, decodedMAC, 6); - dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - decodedMAC[0], decodedMAC[1], decodedMAC[2], - decodedMAC[3], decodedMAC[4], decodedMAC[5]); - return 0; -} - -EXPORT_SYMBOL(ttpci_eeprom_parse_mac); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); -MODULE_DESCRIPTION("Decode dvb_net MAC address from EEPROM of PCI DVB cards " - "made by Siemens, Technotrend, Hauppauge"); diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/dvb/ttpci/ttpci-eeprom.h deleted file mode 100644 index e2dc6cfe205..00000000000 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Retrieve encoded MAC address from ATMEL ttpci_eeprom serial 2-wire EEPROM, - decode it and store it in associated adapter net device - - Robert Schlabbach GMX - Michael Glaum KVH Industries - Holger Waechtler Convergence - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -*/ - -#ifndef __TTPCI_EEPROM_H__ -#define __TTPCI_EEPROM_H__ - -#include <linux/types.h> -#include <linux/i2c.h> - -extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac); - -#endif diff --git a/drivers/media/dvb/ttusb-budget/Kconfig b/drivers/media/dvb/ttusb-budget/Kconfig deleted file mode 100644 index 2663ae39b88..00000000000 --- a/drivers/media/dvb/ttusb-budget/Kconfig +++ /dev/null @@ -1,18 +0,0 @@ -config DVB_TTUSB_BUDGET - tristate "Technotrend/Hauppauge Nova-USB devices" - depends on DVB_CORE && USB && I2C && PCI - select DVB_CX22700 if !DVB_FE_CUSTOMISE - select DVB_TDA1004X if !DVB_FE_CUSTOMISE - select DVB_VES1820 if !DVB_FE_CUSTOMISE - select DVB_TDA8083 if !DVB_FE_CUSTOMISE - select DVB_STV0299 if !DVB_FE_CUSTOMISE - select DVB_STV0297 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - help - Support for external USB adapters designed by Technotrend and - produced by Hauppauge, shipped under the brand name 'Nova-USB'. - - These devices don't have a MPEG decoder built in, so you need - an external software decoder to watch TV. - - Say Y if you own such a device and want to use it. diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile deleted file mode 100644 index fbe2b9514c2..00000000000 --- a/drivers/media/dvb/ttusb-budget/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c deleted file mode 100644 index 4a3f2b8ea37..00000000000 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ /dev/null @@ -1,1827 +0,0 @@ -/* - * TTUSB DVB driver - * - * Copyright (c) 2002 Holger Waechtler <holger@convergence.de> - * Copyright (c) 2003 Felix Domke <tmbinc@elitedvb.net> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - */ -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/wait.h> -#include <linux/fs.h> -#include <linux/module.h> -#include <linux/usb.h> -#include <linux/delay.h> -#include <linux/time.h> -#include <linux/errno.h> -#include <linux/jiffies.h> -#include <linux/mutex.h> -#include <linux/firmware.h> - -#include "dvb_frontend.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_net.h" -#include "ves1820.h" -#include "cx22700.h" -#include "tda1004x.h" -#include "stv0299.h" -#include "tda8083.h" -#include "stv0297.h" -#include "lnbp21.h" - -#include <linux/dvb/frontend.h> -#include <linux/dvb/dmx.h> -#include <linux/pci.h> - -/* - TTUSB_HWSECTIONS: - the DSP supports filtering in hardware, however, since the "muxstream" - is a bit braindead (no matching channel masks or no matching filter mask), - we won't support this - yet. it doesn't event support negative filters, - so the best way is maybe to keep TTUSB_HWSECTIONS undef'd and just - parse TS data. USB bandwidth will be a problem when having large - datastreams, especially for dvb-net, but hey, that's not my problem. - - TTUSB_DISEQC, TTUSB_TONE: - let the STC do the diseqc/tone stuff. this isn't supported at least with - my TTUSB, so let it undef'd unless you want to implement another - frontend. never tested. - - DEBUG: - define it to > 3 for really hardcore debugging. you probably don't want - this unless the device doesn't load at all. > 2 for bandwidth statistics. -*/ - -static int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0) - -#define ISO_BUF_COUNT 4 -#define FRAMES_PER_ISO_BUF 4 -#define ISO_FRAME_SIZE 912 -#define TTUSB_MAXCHANNEL 32 -#ifdef TTUSB_HWSECTIONS -#define TTUSB_MAXFILTER 16 /* ??? */ -#endif - -#define TTUSB_REV_2_2 0x22 -#define TTUSB_BUDGET_NAME "ttusb_stc_fw" - -/** - * since we're casting (struct ttusb*) <-> (struct dvb_demux*) around - * the dvb_demux field must be the first in struct!! - */ -struct ttusb { - struct dvb_demux dvb_demux; - struct dmxdev dmxdev; - struct dvb_net dvbnet; - - /* and one for USB access. */ - struct mutex semi2c; - struct mutex semusb; - - struct dvb_adapter adapter; - struct usb_device *dev; - - struct i2c_adapter i2c_adap; - - int disconnecting; - int iso_streaming; - - unsigned int bulk_out_pipe; - unsigned int bulk_in_pipe; - unsigned int isoc_in_pipe; - - void *iso_buffer; - dma_addr_t iso_dma_handle; - - struct urb *iso_urb[ISO_BUF_COUNT]; - - int running_feed_count; - int last_channel; - int last_filter; - - u8 c; /* transaction counter, wraps around... */ - fe_sec_tone_mode_t tone; - fe_sec_voltage_t voltage; - - int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack - u8 mux_npacks; - u8 muxpack[256 + 8]; - int muxpack_ptr, muxpack_len; - - int insync; - - int cc; /* MuxCounter - will increment on EVERY MUX PACKET */ - /* (including stuffing. yes. really.) */ - - u8 last_result[32]; - - int revision; - - struct dvb_frontend* fe; -}; - -/* ugly workaround ... don't know why it's necessary to read */ -/* all result codes. */ - -#define DEBUG 0 -static int ttusb_cmd(struct ttusb *ttusb, - const u8 * data, int len, int needresult) -{ - int actual_len; - int err; -#if DEBUG >= 3 - int i; - - printk(">"); - for (i = 0; i < len; ++i) - printk(" %02x", data[i]); - printk("\n"); -#endif - - if (mutex_lock_interruptible(&ttusb->semusb) < 0) - return -EAGAIN; - - err = usb_bulk_msg(ttusb->dev, ttusb->bulk_out_pipe, - (u8 *) data, len, &actual_len, 1000); - if (err != 0) { - dprintk("%s: usb_bulk_msg(send) failed, err == %i!\n", - __func__, err); - mutex_unlock(&ttusb->semusb); - return err; - } - if (actual_len != len) { - dprintk("%s: only wrote %d of %d bytes\n", __func__, - actual_len, len); - mutex_unlock(&ttusb->semusb); - return -1; - } - - err = usb_bulk_msg(ttusb->dev, ttusb->bulk_in_pipe, - ttusb->last_result, 32, &actual_len, 1000); - - if (err != 0) { - printk("%s: failed, receive error %d\n", __func__, - err); - mutex_unlock(&ttusb->semusb); - return err; - } -#if DEBUG >= 3 - actual_len = ttusb->last_result[3] + 4; - printk("<"); - for (i = 0; i < actual_len; ++i) - printk(" %02x", ttusb->last_result[i]); - printk("\n"); -#endif - if (!needresult) - mutex_unlock(&ttusb->semusb); - return 0; -} - -static int ttusb_result(struct ttusb *ttusb, u8 * data, int len) -{ - memcpy(data, ttusb->last_result, len); - mutex_unlock(&ttusb->semusb); - return 0; -} - -static int ttusb_i2c_msg(struct ttusb *ttusb, - u8 addr, u8 * snd_buf, u8 snd_len, u8 * rcv_buf, - u8 rcv_len) -{ - u8 b[0x28]; - u8 id = ++ttusb->c; - int i, err; - - if (snd_len > 0x28 - 7 || rcv_len > 0x20 - 7) - return -EINVAL; - - b[0] = 0xaa; - b[1] = id; - b[2] = 0x31; - b[3] = snd_len + 3; - b[4] = addr << 1; - b[5] = snd_len; - b[6] = rcv_len; - - for (i = 0; i < snd_len; i++) - b[7 + i] = snd_buf[i]; - - err = ttusb_cmd(ttusb, b, snd_len + 7, 1); - - if (err) - return -EREMOTEIO; - - err = ttusb_result(ttusb, b, 0x20); - - /* check if the i2c transaction was successful */ - if ((snd_len != b[5]) || (rcv_len != b[6])) return -EREMOTEIO; - - if (rcv_len > 0) { - - if (err || b[0] != 0x55 || b[1] != id) { - dprintk - ("%s: usb_bulk_msg(recv) failed, err == %i, id == %02x, b == ", - __func__, err, id); - return -EREMOTEIO; - } - - for (i = 0; i < rcv_len; i++) - rcv_buf[i] = b[7 + i]; - } - - return rcv_len; -} - -static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) -{ - struct ttusb *ttusb = i2c_get_adapdata(adapter); - int i = 0; - int inc; - - if (mutex_lock_interruptible(&ttusb->semi2c) < 0) - return -EAGAIN; - - while (i < num) { - u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf; - int err; - - if (num > i + 1 && (msg[i + 1].flags & I2C_M_RD)) { - addr = msg[i].addr; - snd_buf = msg[i].buf; - snd_len = msg[i].len; - rcv_buf = msg[i + 1].buf; - rcv_len = msg[i + 1].len; - inc = 2; - } else { - addr = msg[i].addr; - snd_buf = msg[i].buf; - snd_len = msg[i].len; - rcv_buf = NULL; - rcv_len = 0; - inc = 1; - } - - err = ttusb_i2c_msg(ttusb, addr, - snd_buf, snd_len, rcv_buf, rcv_len); - - if (err < rcv_len) { - dprintk("%s: i == %i\n", __func__, i); - break; - } - - i += inc; - } - - mutex_unlock(&ttusb->semi2c); - return i; -} - -static int ttusb_boot_dsp(struct ttusb *ttusb) -{ - const struct firmware *fw; - int i, err; - u8 b[40]; - - err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin", - &ttusb->dev->dev); - if (err) { - printk(KERN_ERR "ttusb-budget: failed to request firmware\n"); - return err; - } - - /* BootBlock */ - b[0] = 0xaa; - b[2] = 0x13; - b[3] = 28; - - /* upload dsp code in 32 byte steps (36 didn't work for me ...) */ - /* 32 is max packet size, no messages should be splitted. */ - for (i = 0; i < fw->size; i += 28) { - memcpy(&b[4], &fw->data[i], 28); - - b[1] = ++ttusb->c; - - err = ttusb_cmd(ttusb, b, 32, 0); - if (err) - goto done; - } - - /* last block ... */ - b[1] = ++ttusb->c; - b[2] = 0x13; - b[3] = 0; - - err = ttusb_cmd(ttusb, b, 4, 0); - if (err) - goto done; - - /* BootEnd */ - b[1] = ++ttusb->c; - b[2] = 0x14; - b[3] = 0; - - err = ttusb_cmd(ttusb, b, 4, 0); - - done: - if (err) { - dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __func__, err); - } - - return err; -} - -static int ttusb_set_channel(struct ttusb *ttusb, int chan_id, int filter_type, - int pid) -{ - int err; - /* SetChannel */ - u8 b[] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type, - (pid >> 8) & 0xff, pid & 0xff - }; - - err = ttusb_cmd(ttusb, b, sizeof(b), 0); - return err; -} - -static int ttusb_del_channel(struct ttusb *ttusb, int channel_id) -{ - int err; - /* DelChannel */ - u8 b[] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id }; - - err = ttusb_cmd(ttusb, b, sizeof(b), 0); - return err; -} - -#ifdef TTUSB_HWSECTIONS -static int ttusb_set_filter(struct ttusb *ttusb, int filter_id, - int associated_chan, u8 filter[8], u8 mask[8]) -{ - int err; - /* SetFilter */ - u8 b[] = { 0xaa, 0, 0x24, 0x1a, filter_id, associated_chan, - filter[0], filter[1], filter[2], filter[3], - filter[4], filter[5], filter[6], filter[7], - filter[8], filter[9], filter[10], filter[11], - mask[0], mask[1], mask[2], mask[3], - mask[4], mask[5], mask[6], mask[7], - mask[8], mask[9], mask[10], mask[11] - }; - - err = ttusb_cmd(ttusb, b, sizeof(b), 0); - return err; -} - -static int ttusb_del_filter(struct ttusb *ttusb, int filter_id) -{ - int err; - /* DelFilter */ - u8 b[] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id }; - - err = ttusb_cmd(ttusb, b, sizeof(b), 0); - return err; -} -#endif - -static int ttusb_init_controller(struct ttusb *ttusb) -{ - u8 b0[] = { 0xaa, ++ttusb->c, 0x15, 1, 0 }; - u8 b1[] = { 0xaa, ++ttusb->c, 0x15, 1, 1 }; - u8 b2[] = { 0xaa, ++ttusb->c, 0x32, 1, 0 }; - /* i2c write read: 5 bytes, addr 0x10, 0x02 bytes write, 1 bytes read. */ - u8 b3[] = - { 0xaa, ++ttusb->c, 0x31, 5, 0x10, 0x02, 0x01, 0x00, 0x1e }; - u8 b4[] = - { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e }; - - u8 get_version[] = { 0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0 }; - u8 get_dsp_version[0x20] = - { 0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0 }; - int err; - - /* reset board */ - if ((err = ttusb_cmd(ttusb, b0, sizeof(b0), 0))) - return err; - - /* reset board (again?) */ - if ((err = ttusb_cmd(ttusb, b1, sizeof(b1), 0))) - return err; - - ttusb_boot_dsp(ttusb); - - /* set i2c bit rate */ - if ((err = ttusb_cmd(ttusb, b2, sizeof(b2), 0))) - return err; - - if ((err = ttusb_cmd(ttusb, b3, sizeof(b3), 1))) - return err; - - err = ttusb_result(ttusb, b4, sizeof(b4)); - - if ((err = ttusb_cmd(ttusb, get_version, sizeof(get_version), 1))) - return err; - - if ((err = ttusb_result(ttusb, get_version, sizeof(get_version)))) - return err; - - dprintk("%s: stc-version: %c%c%c%c%c\n", __func__, - get_version[4], get_version[5], get_version[6], - get_version[7], get_version[8]); - - if (memcmp(get_version + 4, "V 0.0", 5) && - memcmp(get_version + 4, "V 1.1", 5) && - memcmp(get_version + 4, "V 2.1", 5) && - memcmp(get_version + 4, "V 2.2", 5)) { - printk - ("%s: unknown STC version %c%c%c%c%c, please report!\n", - __func__, get_version[4], get_version[5], - get_version[6], get_version[7], get_version[8]); - } - - ttusb->revision = ((get_version[6] - '0') << 4) | - (get_version[8] - '0'); - - err = - ttusb_cmd(ttusb, get_dsp_version, sizeof(get_dsp_version), 1); - if (err) - return err; - - err = - ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version)); - if (err) - return err; - printk("%s: dsp-version: %c%c%c\n", __func__, - get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]); - return 0; -} - -#ifdef TTUSB_DISEQC -static int ttusb_send_diseqc(struct dvb_frontend* fe, - const struct dvb_diseqc_master_cmd *cmd) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - u8 b[12] = { 0xaa, ++ttusb->c, 0x18 }; - - int err; - - b[3] = 4 + 2 + cmd->msg_len; - b[4] = 0xFF; /* send diseqc master, not burst */ - b[5] = cmd->msg_len; - - memcpy(b + 5, cmd->msg, cmd->msg_len); - - /* Diseqc */ - if ((err = ttusb_cmd(ttusb, b, 4 + b[3], 0))) { - dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __func__, err); - } - - return err; -} -#endif - -static int ttusb_update_lnb(struct ttusb *ttusb) -{ - u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, - ttusb->voltage == SEC_VOLTAGE_18 ? 0 : 1, - ttusb->tone == SEC_TONE_ON ? 1 : 0, 1, 1 - }; - int err; - - /* SetLNB */ - if ((err = ttusb_cmd(ttusb, b, sizeof(b), 0))) { - dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __func__, err); - } - - return err; -} - -static int ttusb_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - - ttusb->voltage = voltage; - return ttusb_update_lnb(ttusb); -} - -#ifdef TTUSB_TONE -static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - - ttusb->tone = tone; - return ttusb_update_lnb(ttusb); -} -#endif - - -#if 0 -static void ttusb_set_led_freq(struct ttusb *ttusb, u8 freq) -{ - u8 b[] = { 0xaa, ++ttusb->c, 0x19, 1, freq }; - int err, actual_len; - - err = ttusb_cmd(ttusb, b, sizeof(b), 0); - if (err) { - dprintk("%s: usb_bulk_msg() failed, return value %i!\n", - __func__, err); - } -} -#endif - -/*****************************************************************************/ - -#ifdef TTUSB_HWSECTIONS -static void ttusb_handle_ts_data(struct ttusb_channel *channel, - const u8 * data, int len); -static void ttusb_handle_sec_data(struct ttusb_channel *channel, - const u8 * data, int len); -#endif - -static int numpkt, numts, numstuff, numsec, numinvalid; -static unsigned long lastj; - -static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, - int len) -{ - u16 csum = 0, cc; - int i; - for (i = 0; i < len; i += 2) - csum ^= le16_to_cpup((__le16 *) (muxpack + i)); - if (csum) { - printk("%s: muxpack with incorrect checksum, ignoring\n", - __func__); - numinvalid++; - return; - } - - cc = (muxpack[len - 4] << 8) | muxpack[len - 3]; - cc &= 0x7FFF; - if ((cc != ttusb->cc) && (ttusb->cc != -1)) - printk("%s: cc discontinuity (%d frames missing)\n", - __func__, (cc - ttusb->cc) & 0x7FFF); - ttusb->cc = (cc + 1) & 0x7FFF; - if (muxpack[0] & 0x80) { -#ifdef TTUSB_HWSECTIONS - /* section data */ - int pusi = muxpack[0] & 0x40; - int channel = muxpack[0] & 0x1F; - int payload = muxpack[1]; - const u8 *data = muxpack + 2; - /* check offset flag */ - if (muxpack[0] & 0x20) - data++; - - ttusb_handle_sec_data(ttusb->channel + channel, data, - payload); - data += payload; - - if ((!!(ttusb->muxpack[0] & 0x20)) ^ - !!(ttusb->muxpack[1] & 1)) - data++; -#warning TODO: pusi - printk("cc: %04x\n", (data[0] << 8) | data[1]); -#endif - numsec++; - } else if (muxpack[0] == 0x47) { -#ifdef TTUSB_HWSECTIONS - /* we have TS data here! */ - int pid = ((muxpack[1] & 0x0F) << 8) | muxpack[2]; - int channel; - for (channel = 0; channel < TTUSB_MAXCHANNEL; ++channel) - if (ttusb->channel[channel].active - && (pid == ttusb->channel[channel].pid)) - ttusb_handle_ts_data(ttusb->channel + - channel, muxpack, - 188); -#endif - numts++; - dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1); - } else if (muxpack[0] != 0) { - numinvalid++; - printk("illegal muxpack type %02x\n", muxpack[0]); - } else - numstuff++; -} - -static void ttusb_process_frame(struct ttusb *ttusb, u8 * data, int len) -{ - int maxwork = 1024; - while (len) { - if (!(maxwork--)) { - printk("%s: too much work\n", __func__); - break; - } - - switch (ttusb->mux_state) { - case 0: - case 1: - case 2: - len--; - if (*data++ == 0xAA) - ++ttusb->mux_state; - else { - ttusb->mux_state = 0; -#if DEBUG > 3 - if (ttusb->insync) - printk("%02x ", data[-1]); -#else - if (ttusb->insync) { - printk("%s: lost sync.\n", - __func__); - ttusb->insync = 0; - } -#endif - } - break; - case 3: - ttusb->insync = 1; - len--; - ttusb->mux_npacks = *data++; - ++ttusb->mux_state; - ttusb->muxpack_ptr = 0; - /* maximum bytes, until we know the length */ - ttusb->muxpack_len = 2; - break; - case 4: - { - int avail; - avail = len; - if (avail > - (ttusb->muxpack_len - - ttusb->muxpack_ptr)) - avail = - ttusb->muxpack_len - - ttusb->muxpack_ptr; - memcpy(ttusb->muxpack + ttusb->muxpack_ptr, - data, avail); - ttusb->muxpack_ptr += avail; - BUG_ON(ttusb->muxpack_ptr > 264); - data += avail; - len -= avail; - /* determine length */ - if (ttusb->muxpack_ptr == 2) { - if (ttusb->muxpack[0] & 0x80) { - ttusb->muxpack_len = - ttusb->muxpack[1] + 2; - if (ttusb-> - muxpack[0] & 0x20) - ttusb-> - muxpack_len++; - if ((!! - (ttusb-> - muxpack[0] & 0x20)) ^ - !!(ttusb-> - muxpack[1] & 1)) - ttusb-> - muxpack_len++; - ttusb->muxpack_len += 4; - } else if (ttusb->muxpack[0] == - 0x47) - ttusb->muxpack_len = - 188 + 4; - else if (ttusb->muxpack[0] == 0x00) - ttusb->muxpack_len = - ttusb->muxpack[1] + 2 + - 4; - else { - dprintk - ("%s: invalid state: first byte is %x\n", - __func__, - ttusb->muxpack[0]); - ttusb->mux_state = 0; - } - } - - /** - * if length is valid and we reached the end: - * goto next muxpack - */ - if ((ttusb->muxpack_ptr >= 2) && - (ttusb->muxpack_ptr == - ttusb->muxpack_len)) { - ttusb_process_muxpack(ttusb, - ttusb-> - muxpack, - ttusb-> - muxpack_ptr); - ttusb->muxpack_ptr = 0; - /* maximum bytes, until we know the length */ - ttusb->muxpack_len = 2; - - /** - * no muxpacks left? - * return to search-sync state - */ - if (!ttusb->mux_npacks--) { - ttusb->mux_state = 0; - break; - } - } - break; - } - default: - BUG(); - break; - } - } -} - -static void ttusb_iso_irq(struct urb *urb) -{ - struct ttusb *ttusb = urb->context; - - if (!ttusb->iso_streaming) - return; - -#if 0 - printk("%s: status %d, errcount == %d, length == %i\n", - __func__, - urb->status, urb->error_count, urb->actual_length); -#endif - - if (!urb->status) { - int i; - for (i = 0; i < urb->number_of_packets; ++i) { - struct usb_iso_packet_descriptor *d; - u8 *data; - int len; - numpkt++; - if (time_after_eq(jiffies, lastj + HZ)) { -#if DEBUG > 2 - printk - ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n", - numpkt * HZ / (jiffies - lastj), - numts, numstuff, numsec, numinvalid, - numts + numstuff + numsec + - numinvalid); -#endif - numts = numstuff = numsec = numinvalid = 0; - lastj = jiffies; - numpkt = 0; - } - d = &urb->iso_frame_desc[i]; - data = urb->transfer_buffer + d->offset; - len = d->actual_length; - d->actual_length = 0; - d->status = 0; - ttusb_process_frame(ttusb, data, len); - } - } - usb_submit_urb(urb, GFP_ATOMIC); -} - -static void ttusb_free_iso_urbs(struct ttusb *ttusb) -{ - int i; - - for (i = 0; i < ISO_BUF_COUNT; i++) - if (ttusb->iso_urb[i]) - usb_free_urb(ttusb->iso_urb[i]); - - pci_free_consistent(NULL, - ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * - ISO_BUF_COUNT, ttusb->iso_buffer, - ttusb->iso_dma_handle); -} - -static int ttusb_alloc_iso_urbs(struct ttusb *ttusb) -{ - int i; - - ttusb->iso_buffer = pci_alloc_consistent(NULL, - ISO_FRAME_SIZE * - FRAMES_PER_ISO_BUF * - ISO_BUF_COUNT, - &ttusb->iso_dma_handle); - - if (!ttusb->iso_buffer) { - dprintk("%s: pci_alloc_consistent - not enough memory\n", - __func__); - return -ENOMEM; - } - - memset(ttusb->iso_buffer, 0, - ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF * ISO_BUF_COUNT); - - for (i = 0; i < ISO_BUF_COUNT; i++) { - struct urb *urb; - - if (! - (urb = - usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) { - ttusb_free_iso_urbs(ttusb); - return -ENOMEM; - } - - ttusb->iso_urb[i] = urb; - } - - return 0; -} - -static void ttusb_stop_iso_xfer(struct ttusb *ttusb) -{ - int i; - - for (i = 0; i < ISO_BUF_COUNT; i++) - usb_kill_urb(ttusb->iso_urb[i]); - - ttusb->iso_streaming = 0; -} - -static int ttusb_start_iso_xfer(struct ttusb *ttusb) -{ - int i, j, err, buffer_offset = 0; - - if (ttusb->iso_streaming) { - printk("%s: iso xfer already running!\n", __func__); - return 0; - } - - ttusb->cc = -1; - ttusb->insync = 0; - ttusb->mux_state = 0; - - for (i = 0; i < ISO_BUF_COUNT; i++) { - int frame_offset = 0; - struct urb *urb = ttusb->iso_urb[i]; - - urb->dev = ttusb->dev; - urb->context = ttusb; - urb->complete = ttusb_iso_irq; - urb->pipe = ttusb->isoc_in_pipe; - urb->transfer_flags = URB_ISO_ASAP; - urb->interval = 1; - urb->number_of_packets = FRAMES_PER_ISO_BUF; - urb->transfer_buffer_length = - ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF; - urb->transfer_buffer = ttusb->iso_buffer + buffer_offset; - buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF; - - for (j = 0; j < FRAMES_PER_ISO_BUF; j++) { - urb->iso_frame_desc[j].offset = frame_offset; - urb->iso_frame_desc[j].length = ISO_FRAME_SIZE; - frame_offset += ISO_FRAME_SIZE; - } - } - - for (i = 0; i < ISO_BUF_COUNT; i++) { - if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) { - ttusb_stop_iso_xfer(ttusb); - printk - ("%s: failed urb submission (%i: err = %i)!\n", - __func__, i, err); - return err; - } - } - - ttusb->iso_streaming = 1; - - return 0; -} - -#ifdef TTUSB_HWSECTIONS -static void ttusb_handle_ts_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data, - int len) -{ - dvbdmxfeed->cb.ts(data, len, 0, 0, &dvbdmxfeed->feed.ts, 0); -} - -static void ttusb_handle_sec_data(struct dvb_demux_feed *dvbdmxfeed, const u8 * data, - int len) -{ -// struct dvb_demux_feed *dvbdmxfeed = channel->dvbdmxfeed; -#error TODO: handle ugly stuff -// dvbdmxfeed->cb.sec(data, len, 0, 0, &dvbdmxfeed->feed.sec, 0); -} -#endif - -static int ttusb_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux; - int feed_type = 1; - - dprintk("ttusb_start_feed\n"); - - switch (dvbdmxfeed->type) { - case DMX_TYPE_TS: - break; - case DMX_TYPE_SEC: - break; - default: - return -EINVAL; - } - - if (dvbdmxfeed->type == DMX_TYPE_TS) { - switch (dvbdmxfeed->pes_type) { - case DMX_TS_PES_VIDEO: - case DMX_TS_PES_AUDIO: - case DMX_TS_PES_TELETEXT: - case DMX_TS_PES_PCR: - case DMX_TS_PES_OTHER: - break; - default: - return -EINVAL; - } - } - -#ifdef TTUSB_HWSECTIONS -#error TODO: allocate filters - if (dvbdmxfeed->type == DMX_TYPE_TS) { - feed_type = 1; - } else if (dvbdmxfeed->type == DMX_TYPE_SEC) { - feed_type = 2; - } -#endif - - ttusb_set_channel(ttusb, dvbdmxfeed->index, feed_type, dvbdmxfeed->pid); - - if (0 == ttusb->running_feed_count++) - ttusb_start_iso_xfer(ttusb); - - return 0; -} - -static int ttusb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct ttusb *ttusb = (struct ttusb *) dvbdmxfeed->demux; - - ttusb_del_channel(ttusb, dvbdmxfeed->index); - - if (--ttusb->running_feed_count == 0) - ttusb_stop_iso_xfer(ttusb); - - return 0; -} - -static int ttusb_setup_interfaces(struct ttusb *ttusb) -{ - usb_set_interface(ttusb->dev, 1, 1); - - ttusb->bulk_out_pipe = usb_sndbulkpipe(ttusb->dev, 1); - ttusb->bulk_in_pipe = usb_rcvbulkpipe(ttusb->dev, 1); - ttusb->isoc_in_pipe = usb_rcvisocpipe(ttusb->dev, 2); - - return 0; -} - -#if 0 -static u8 stc_firmware[8192]; - -static int stc_open(struct inode *inode, struct file *file) -{ - struct ttusb *ttusb = file->private_data; - int addr; - - for (addr = 0; addr < 8192; addr += 16) { - u8 snd_buf[2] = { addr >> 8, addr & 0xFF }; - ttusb_i2c_msg(ttusb, 0x50, snd_buf, 2, stc_firmware + addr, - 16); - } - - return 0; -} - -static ssize_t stc_read(struct file *file, char *buf, size_t count, - loff_t *offset) -{ - return simple_read_from_buffer(buf, count, offset, stc_firmware, 8192); -} - -static int stc_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations stc_fops = { - .owner = THIS_MODULE, - .read = stc_read, - .open = stc_open, - .release = stc_release, -}; -#endif - -static u32 functionality(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - - - -static int alps_tdmb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - u8 data[4]; - struct i2c_msg msg = {.addr=0x61, .flags=0, .buf=data, .len=sizeof(data) }; - u32 div; - - div = (params->frequency + 36166667) / 166667; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = ((div >> 10) & 0x60) | 0x85; - data[3] = params->frequency < 592000000 ? 0x40 : 0x80; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) return -EIO; - return 0; -} - -static struct cx22700_config alps_tdmb7_config = { - .demod_address = 0x43, -}; - - - - - -static int philips_tdm1316l_tuner_init(struct dvb_frontend* fe) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab }; - static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; - struct i2c_msg tuner_msg = { .addr=0x60, .flags=0, .buf=td1316_init, .len=sizeof(td1316_init) }; - - // setup PLL configuration - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; - msleep(1); - - // disable the mc44BC374c (do not check for errors) - tuner_msg.addr = 0x65; - tuner_msg.buf = disable_mc44BC374c; - tuner_msg.len = sizeof(disable_mc44BC374c); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { - i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1); - } - - return 0; -} - -static int philips_tdm1316l_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - u8 tuner_buf[4]; - struct i2c_msg tuner_msg = {.addr=0x60, .flags=0, .buf=tuner_buf, .len=sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = params->frequency + 36130000; - if (tuner_frequency < 87000000) return -EINVAL; - else if (tuner_frequency < 130000000) cp = 3; - else if (tuner_frequency < 160000000) cp = 5; - else if (tuner_frequency < 200000000) cp = 6; - else if (tuner_frequency < 290000000) cp = 3; - else if (tuner_frequency < 420000000) cp = 5; - else if (tuner_frequency < 480000000) cp = 6; - else if (tuner_frequency < 620000000) cp = 3; - else if (tuner_frequency < 830000000) cp = 5; - else if (tuner_frequency < 895000000) cp = 7; - else return -EINVAL; - - // determine band - if (params->frequency < 49000000) return -EINVAL; - else if (params->frequency < 159000000) band = 1; - else if (params->frequency < 444000000) band = 2; - else if (params->frequency < 861000000) band = 4; - else return -EINVAL; - - // setup PLL filter - switch (params->u.ofdm.bandwidth) { - case BANDWIDTH_6_MHZ: - tda1004x_writereg(fe, 0x0C, 0); - filter = 0; - break; - - case BANDWIDTH_7_MHZ: - tda1004x_writereg(fe, 0x0C, 0); - filter = 0; - break; - - case BANDWIDTH_8_MHZ: - tda1004x_writereg(fe, 0x0C, 0xFF); - filter = 1; - break; - - default: - return -EINVAL; - } - - // calculate divisor - // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) - tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000; - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xca; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) - return -EIO; - - msleep(1); - return 0; -} - -static int philips_tdm1316l_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - - return request_firmware(fw, name, &ttusb->dev->dev); -} - -static struct tda1004x_config philips_tdm1316l_config = { - - .demod_address = 0x8, - .invert = 1, - .invert_oclk = 0, - .request_firmware = philips_tdm1316l_request_firmware, -}; - -static u8 alps_bsbe1_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x92, - 0xff, 0xff -}; - -static u8 alps_bsru6_inittab[] = { - 0x01, 0x15, - 0x02, 0x30, - 0x03, 0x00, - 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ - 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ - 0x06, 0x40, /* DAC not used, set to high impendance mode */ - 0x07, 0x00, /* DAC LSB */ - 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ - 0x09, 0x00, /* FIFO */ - 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ - 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ - 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ - 0x10, 0x3f, // AGC2 0x3d - 0x11, 0x84, - 0x12, 0xb9, - 0x15, 0xc9, // lock detector threshold - 0x16, 0x00, - 0x17, 0x00, - 0x18, 0x00, - 0x19, 0x00, - 0x1a, 0x00, - 0x1f, 0x50, - 0x20, 0x00, - 0x21, 0x00, - 0x22, 0x00, - 0x23, 0x00, - 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 - 0x29, 0x1e, // 1/2 threshold - 0x2a, 0x14, // 2/3 threshold - 0x2b, 0x0f, // 3/4 threshold - 0x2c, 0x09, // 5/6 threshold - 0x2d, 0x05, // 7/8 threshold - 0x2e, 0x01, - 0x31, 0x1f, // test all FECs - 0x32, 0x19, // viterbi and synchro search - 0x33, 0xfc, // rs control - 0x34, 0x93, // error control - 0x0f, 0x52, - 0xff, 0xff -}; - -static int alps_stv0299_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) -{ - u8 aclk = 0; - u8 bclk = 0; - - if (srate < 1500000) { - aclk = 0xb7; - bclk = 0x47; - } else if (srate < 3000000) { - aclk = 0xb7; - bclk = 0x4b; - } else if (srate < 7000000) { - aclk = 0xb7; - bclk = 0x4f; - } else if (srate < 14000000) { - aclk = 0xb7; - bclk = 0x53; - } else if (srate < 30000000) { - aclk = 0xb6; - bclk = 0x53; - } else if (srate < 45000000) { - aclk = 0xb4; - bclk = 0x51; - } - - stv0299_writereg(fe, 0x13, aclk); - stv0299_writereg(fe, 0x14, bclk); - stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); - stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); - stv0299_writereg(fe, 0x21, (ratio) & 0xf0); - - return 0; -} - -static int philips_tsa5059_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - u8 buf[4]; - u32 div; - struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - - if ((params->frequency < 950000) || (params->frequency > 2150000)) - return -EINVAL; - - div = (params->frequency + (125 - 1)) / 125; // round correctly - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; - buf[3] = 0xC4; - - if (params->frequency > 1530000) - buf[3] = 0xC0; - - /* BSBE1 wants XCE bit set */ - if (ttusb->revision == TTUSB_REV_2_2) - buf[3] |= 0x20; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) - return -EIO; - - return 0; -} - -static struct stv0299_config alps_stv0299_config = { - .demod_address = 0x68, - .inittab = alps_bsru6_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0299_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP1, - .min_delay_ms = 100, - .set_symbol_rate = alps_stv0299_set_symbol_rate, -}; - -static int ttusb_novas_grundig_29504_491_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv; - u8 buf[4]; - u32 div; - struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; - - div = params->frequency / 125; - - buf[0] = (div >> 8) & 0x7f; - buf[1] = div & 0xff; - buf[2] = 0x8e; - buf[3] = 0x00; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1) - return -EIO; - - return 0; -} - -static struct tda8083_config ttusb_novas_grundig_29504_491_config = { - - .demod_address = 0x68, -}; - -static int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) -{ - struct ttusb* ttusb = fe->dvb->priv; - u32 div; - u8 data[4]; - struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; - - div = (params->frequency + 35937500 + 31250) / 62500; - - data[0] = (div >> 8) & 0x7f; - data[1] = div & 0xff; - data[2] = 0x85 | ((div >> 10) & 0x60); - data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer (&ttusb->i2c_adap, &msg, 1) != 1) - return -EIO; - - return 0; -} - - -static struct ves1820_config alps_tdbe2_config = { - .demod_address = 0x09, - .xin = 57840000UL, - .invert = 1, - .selagc = VES1820_SELAGC_SIGNAMPERR, -}; - -static u8 read_pwm(struct ttusb* ttusb) -{ - u8 b = 0xff; - u8 pwm; - struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, - { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; - - if ((i2c_transfer(&ttusb->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) - pwm = 0x48; - - return pwm; -} - - -static int dvbc_philips_tdm1316l_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) -{ - struct ttusb *ttusb = (struct ttusb *) fe->dvb->priv; - u8 tuner_buf[5]; - struct i2c_msg tuner_msg = {.addr = 0x60, - .flags = 0, - .buf = tuner_buf, - .len = sizeof(tuner_buf) }; - int tuner_frequency = 0; - u8 band, cp, filter; - - // determine charge pump - tuner_frequency = params->frequency; - if (tuner_frequency < 87000000) {return -EINVAL;} - else if (tuner_frequency < 130000000) {cp = 3; band = 1;} - else if (tuner_frequency < 160000000) {cp = 5; band = 1;} - else if (tuner_frequency < 200000000) {cp = 6; band = 1;} - else if (tuner_frequency < 290000000) {cp = 3; band = 2;} - else if (tuner_frequency < 420000000) {cp = 5; band = 2;} - else if (tuner_frequency < 480000000) {cp = 6; band = 2;} - else if (tuner_frequency < 620000000) {cp = 3; band = 4;} - else if (tuner_frequency < 830000000) {cp = 5; band = 4;} - else if (tuner_frequency < 895000000) {cp = 7; band = 4;} - else {return -EINVAL;} - - // assume PLL filter should always be 8MHz for the moment. - filter = 1; - - // calculate divisor - // (Finput + Fif)/Fref; Fif = 36125000 Hz, Fref = 62500 Hz - tuner_frequency = ((params->frequency + 36125000) / 62500); - - // setup tuner buffer - tuner_buf[0] = tuner_frequency >> 8; - tuner_buf[1] = tuner_frequency & 0xff; - tuner_buf[2] = 0xc8; - tuner_buf[3] = (cp << 5) | (filter << 3) | band; - tuner_buf[4] = 0x80; - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { - printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 1\n"); - return -EIO; - } - - msleep(50); - - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) { - printk("dvb-ttusb-budget: dvbc_philips_tdm1316l_pll_set Error 2\n"); - return -EIO; - } - - msleep(1); - - return 0; -} - -static u8 dvbc_philips_tdm1316l_inittab[] = { - 0x80, 0x21, - 0x80, 0x20, - 0x81, 0x01, - 0x81, 0x00, - 0x00, 0x09, - 0x01, 0x69, - 0x03, 0x00, - 0x04, 0x00, - 0x07, 0x00, - 0x08, 0x00, - 0x20, 0x00, - 0x21, 0x40, - 0x22, 0x00, - 0x23, 0x00, - 0x24, 0x40, - 0x25, 0x88, - 0x30, 0xff, - 0x31, 0x00, - 0x32, 0xff, - 0x33, 0x00, - 0x34, 0x50, - 0x35, 0x7f, - 0x36, 0x00, - 0x37, 0x20, - 0x38, 0x00, - 0x40, 0x1c, - 0x41, 0xff, - 0x42, 0x29, - 0x43, 0x20, - 0x44, 0xff, - 0x45, 0x00, - 0x46, 0x00, - 0x49, 0x04, - 0x4a, 0xff, - 0x4b, 0x7f, - 0x52, 0x30, - 0x55, 0xae, - 0x56, 0x47, - 0x57, 0xe1, - 0x58, 0x3a, - 0x5a, 0x1e, - 0x5b, 0x34, - 0x60, 0x00, - 0x63, 0x00, - 0x64, 0x00, - 0x65, 0x00, - 0x66, 0x00, - 0x67, 0x00, - 0x68, 0x00, - 0x69, 0x00, - 0x6a, 0x02, - 0x6b, 0x00, - 0x70, 0xff, - 0x71, 0x00, - 0x72, 0x00, - 0x73, 0x00, - 0x74, 0x0c, - 0x80, 0x00, - 0x81, 0x00, - 0x82, 0x00, - 0x83, 0x00, - 0x84, 0x04, - 0x85, 0x80, - 0x86, 0x24, - 0x87, 0x78, - 0x88, 0x00, - 0x89, 0x00, - 0x90, 0x01, - 0x91, 0x01, - 0xa0, 0x00, - 0xa1, 0x00, - 0xa2, 0x00, - 0xb0, 0x91, - 0xb1, 0x0b, - 0xc0, 0x4b, - 0xc1, 0x00, - 0xc2, 0x00, - 0xd0, 0x00, - 0xd1, 0x00, - 0xd2, 0x00, - 0xd3, 0x00, - 0xd4, 0x00, - 0xd5, 0x00, - 0xde, 0x00, - 0xdf, 0x00, - 0x61, 0x38, - 0x62, 0x0a, - 0x53, 0x13, - 0x59, 0x08, - 0x55, 0x00, - 0x56, 0x40, - 0x57, 0x08, - 0x58, 0x3d, - 0x88, 0x10, - 0xa0, 0x00, - 0xa0, 0x00, - 0xa0, 0x00, - 0xa0, 0x04, - 0xff, 0xff, -}; - -static struct stv0297_config dvbc_philips_tdm1316l_config = { - .demod_address = 0x1c, - .inittab = dvbc_philips_tdm1316l_inittab, - .invert = 0, -}; - -static void frontend_init(struct ttusb* ttusb) -{ - switch(le16_to_cpu(ttusb->dev->descriptor.idProduct)) { - case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6|BSBE1(tsa5059)) - // try the stv0299 based first - ttusb->fe = dvb_attach(stv0299_attach, &alps_stv0299_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = philips_tsa5059_tuner_set_params; - - if(ttusb->revision == TTUSB_REV_2_2) { // ALPS BSBE1 - alps_stv0299_config.inittab = alps_bsbe1_inittab; - dvb_attach(lnbp21_attach, ttusb->fe, &ttusb->i2c_adap, 0, 0); - } else { // ALPS BSRU6 - ttusb->fe->ops.set_voltage = ttusb_set_voltage; - } - break; - } - - // Grundig 29504-491 - ttusb->fe = dvb_attach(tda8083_attach, &ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = ttusb_novas_grundig_29504_491_tuner_set_params; - ttusb->fe->ops.set_voltage = ttusb_set_voltage; - break; - } - break; - - case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) - ttusb->fe = dvb_attach(ves1820_attach, &alps_tdbe2_config, &ttusb->i2c_adap, read_pwm(ttusb)); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; - break; - } - - ttusb->fe = dvb_attach(stv0297_attach, &dvbc_philips_tdm1316l_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = dvbc_philips_tdm1316l_tuner_set_params; - break; - } - break; - - case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) - // try the ALPS TDMB7 first - ttusb->fe = dvb_attach(cx22700_attach, &alps_tdmb7_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.set_params = alps_tdmb7_tuner_set_params; - break; - } - - // Philips td1316 - ttusb->fe = dvb_attach(tda10046_attach, &philips_tdm1316l_config, &ttusb->i2c_adap); - if (ttusb->fe != NULL) { - ttusb->fe->ops.tuner_ops.init = philips_tdm1316l_tuner_init; - ttusb->fe->ops.tuner_ops.set_params = philips_tdm1316l_tuner_set_params; - break; - } - break; - } - - if (ttusb->fe == NULL) { - printk("dvb-ttusb-budget: A frontend driver was not found for device [%04x:%04x]\n", - le16_to_cpu(ttusb->dev->descriptor.idVendor), - le16_to_cpu(ttusb->dev->descriptor.idProduct)); - } else { - if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { - printk("dvb-ttusb-budget: Frontend registration failed!\n"); - dvb_frontend_detach(ttusb->fe); - ttusb->fe = NULL; - } - } -} - - - -static struct i2c_algorithm ttusb_dec_algo = { - .master_xfer = master_xfer, - .functionality = functionality, -}; - -static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *udev; - struct ttusb *ttusb; - int result; - - dprintk("%s: TTUSB DVB connected\n", __func__); - - udev = interface_to_usbdev(intf); - - if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV; - - if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL))) - return -ENOMEM; - - ttusb->dev = udev; - ttusb->c = 0; - ttusb->mux_state = 0; - mutex_init(&ttusb->semi2c); - - mutex_lock(&ttusb->semi2c); - - mutex_init(&ttusb->semusb); - - ttusb_setup_interfaces(ttusb); - - result = ttusb_alloc_iso_urbs(ttusb); - if (result < 0) { - dprintk("%s: ttusb_alloc_iso_urbs - failed\n", __func__); - mutex_unlock(&ttusb->semi2c); - kfree(ttusb); - return result; - } - - if (ttusb_init_controller(ttusb)) - printk("ttusb_init_controller: error\n"); - - mutex_unlock(&ttusb->semi2c); - - result = dvb_register_adapter(&ttusb->adapter, - "Technotrend/Hauppauge Nova-USB", - THIS_MODULE, &udev->dev, adapter_nr); - if (result < 0) { - ttusb_free_iso_urbs(ttusb); - kfree(ttusb); - return result; - } - ttusb->adapter.priv = ttusb; - - /* i2c */ - memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter)); - strcpy(ttusb->i2c_adap.name, "TTUSB DEC"); - - i2c_set_adapdata(&ttusb->i2c_adap, ttusb); - - ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL; - ttusb->i2c_adap.algo = &ttusb_dec_algo; - ttusb->i2c_adap.algo_data = NULL; - ttusb->i2c_adap.dev.parent = &udev->dev; - - result = i2c_add_adapter(&ttusb->i2c_adap); - if (result) { - dvb_unregister_adapter (&ttusb->adapter); - return result; - } - - memset(&ttusb->dvb_demux, 0, sizeof(ttusb->dvb_demux)); - - ttusb->dvb_demux.dmx.capabilities = - DMX_TS_FILTERING | DMX_SECTION_FILTERING; - ttusb->dvb_demux.priv = NULL; -#ifdef TTUSB_HWSECTIONS - ttusb->dvb_demux.filternum = TTUSB_MAXFILTER; -#else - ttusb->dvb_demux.filternum = 32; -#endif - ttusb->dvb_demux.feednum = TTUSB_MAXCHANNEL; - ttusb->dvb_demux.start_feed = ttusb_start_feed; - ttusb->dvb_demux.stop_feed = ttusb_stop_feed; - ttusb->dvb_demux.write_to_decoder = NULL; - - if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) { - printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result); - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter (&ttusb->adapter); - return -ENODEV; - } -//FIXME dmxdev (nur WAS?) - ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum; - ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx; - ttusb->dmxdev.capabilities = 0; - - if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) { - printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n", - result); - dvb_dmx_release(&ttusb->dvb_demux); - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter (&ttusb->adapter); - return -ENODEV; - } - - if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) { - printk("ttusb_dvb: dvb_net_init failed!\n"); - dvb_dmxdev_release(&ttusb->dmxdev); - dvb_dmx_release(&ttusb->dvb_demux); - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter (&ttusb->adapter); - return -ENODEV; - } - - usb_set_intfdata(intf, (void *) ttusb); - - frontend_init(ttusb); - - return 0; -} - -static void ttusb_disconnect(struct usb_interface *intf) -{ - struct ttusb *ttusb = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - ttusb->disconnecting = 1; - - ttusb_stop_iso_xfer(ttusb); - - ttusb->dvb_demux.dmx.close(&ttusb->dvb_demux.dmx); - dvb_net_release(&ttusb->dvbnet); - dvb_dmxdev_release(&ttusb->dmxdev); - dvb_dmx_release(&ttusb->dvb_demux); - if (ttusb->fe != NULL) { - dvb_unregister_frontend(ttusb->fe); - dvb_frontend_detach(ttusb->fe); - } - i2c_del_adapter(&ttusb->i2c_adap); - dvb_unregister_adapter(&ttusb->adapter); - - ttusb_free_iso_urbs(ttusb); - - kfree(ttusb); - - dprintk("%s: TTUSB DVB disconnected\n", __func__); -} - -static struct usb_device_id ttusb_table[] = { - {USB_DEVICE(0xb48, 0x1003)}, - {USB_DEVICE(0xb48, 0x1004)}, - {USB_DEVICE(0xb48, 0x1005)}, - {} -}; - -MODULE_DEVICE_TABLE(usb, ttusb_table); - -static struct usb_driver ttusb_driver = { - .name = "ttusb", - .probe = ttusb_probe, - .disconnect = ttusb_disconnect, - .id_table = ttusb_table, -}; - -static int __init ttusb_init(void) -{ - int err; - - if ((err = usb_register(&ttusb_driver)) < 0) { - printk("%s: usb_register failed! Error number %d", - __FILE__, err); - return err; - } - - return 0; -} - -static void __exit ttusb_exit(void) -{ - usb_deregister(&ttusb_driver); -} - -module_init(ttusb_init); -module_exit(ttusb_exit); - -MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>"); -MODULE_DESCRIPTION("TTUSB DVB Driver"); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("ttusb-budget/dspbootcode.bin"); diff --git a/drivers/media/dvb/ttusb-dec/Kconfig b/drivers/media/dvb/ttusb-dec/Kconfig deleted file mode 100644 index 290254ab06d..00000000000 --- a/drivers/media/dvb/ttusb-dec/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -config DVB_TTUSB_DEC - tristate "Technotrend/Hauppauge USB DEC devices" - depends on DVB_CORE && USB && INPUT && PCI - select CRC32 - help - Support for external USB adapters designed by Technotrend and - produced by Hauppauge, shipped under the brand name 'DEC2000-t' - and 'DEC3000-s'. - - Even if these devices have a MPEG decoder built in, they transmit - only compressed MPEG data over the USB bus, so you need - an external software decoder to watch TV on your computer. - - This driver needs external firmware. Please use the commands - "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", - "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", - "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - - Say Y if you own such a device and want to use it. diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/dvb/ttusb-dec/Makefile deleted file mode 100644 index 2d70a826939..00000000000 --- a/drivers/media/dvb/ttusb-dec/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c deleted file mode 100644 index 0aa96df80fc..00000000000 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ /dev/null @@ -1,1783 +0,0 @@ -/* - * TTUSB DEC Driver - * - * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org> - * IR support by Peter Beutner <p.beutner@gmx.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include <linux/list.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include <linux/usb.h> -#include <linux/interrupt.h> -#include <linux/firmware.h> -#include <linux/crc32.h> -#include <linux/init.h> -#include <linux/input.h> - -#include <linux/mutex.h> - -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_filter.h" -#include "dvb_frontend.h" -#include "dvb_net.h" -#include "ttusbdecfe.h" - -static int debug; -static int output_pva; -static int enable_rc; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); -module_param(output_pva, int, 0444); -MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)"); -module_param(enable_rc, int, 0644); -MODULE_PARM_DESC(enable_rc, "Turn on/off IR remote control(default: off)"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define dprintk if (debug) printk - -#define DRIVER_NAME "TechnoTrend/Hauppauge DEC USB" - -#define COMMAND_PIPE 0x03 -#define RESULT_PIPE 0x04 -#define IN_PIPE 0x08 -#define OUT_PIPE 0x07 -#define IRQ_PIPE 0x0A - -#define COMMAND_PACKET_SIZE 0x3c -#define ARM_PACKET_SIZE 0x1000 -#define IRQ_PACKET_SIZE 0x8 - -#define ISO_BUF_COUNT 0x04 -#define FRAMES_PER_ISO_BUF 0x04 -#define ISO_FRAME_SIZE 0x0380 - -#define MAX_PVA_LENGTH 6144 - -enum ttusb_dec_model { - TTUSB_DEC2000T, - TTUSB_DEC2540T, - TTUSB_DEC3000S -}; - -enum ttusb_dec_packet_type { - TTUSB_DEC_PACKET_PVA, - TTUSB_DEC_PACKET_SECTION, - TTUSB_DEC_PACKET_EMPTY -}; - -enum ttusb_dec_interface { - TTUSB_DEC_INTERFACE_INITIAL, - TTUSB_DEC_INTERFACE_IN, - TTUSB_DEC_INTERFACE_OUT -}; - -struct ttusb_dec { - enum ttusb_dec_model model; - char *model_name; - char *firmware_name; - int can_playback; - - /* DVB bits */ - struct dvb_adapter adapter; - struct dmxdev dmxdev; - struct dvb_demux demux; - struct dmx_frontend frontend; - struct dvb_net dvb_net; - struct dvb_frontend* fe; - - u16 pid[DMX_PES_OTHER]; - - /* USB bits */ - struct usb_device *udev; - u8 trans_count; - unsigned int command_pipe; - unsigned int result_pipe; - unsigned int in_pipe; - unsigned int out_pipe; - unsigned int irq_pipe; - enum ttusb_dec_interface interface; - struct mutex usb_mutex; - - void *irq_buffer; - struct urb *irq_urb; - dma_addr_t irq_dma_handle; - void *iso_buffer; - dma_addr_t iso_dma_handle; - struct urb *iso_urb[ISO_BUF_COUNT]; - int iso_stream_count; - struct mutex iso_mutex; - - u8 packet[MAX_PVA_LENGTH + 4]; - enum ttusb_dec_packet_type packet_type; - int packet_state; - int packet_length; - int packet_payload_length; - u16 next_packet_id; - - int pva_stream_count; - int filter_stream_count; - - struct dvb_filter_pes2ts a_pes2ts; - struct dvb_filter_pes2ts v_pes2ts; - - u8 v_pes[16 + MAX_PVA_LENGTH]; - int v_pes_length; - int v_pes_postbytes; - - struct list_head urb_frame_list; - struct tasklet_struct urb_tasklet; - spinlock_t urb_frame_list_lock; - - struct dvb_demux_filter *audio_filter; - struct dvb_demux_filter *video_filter; - struct list_head filter_info_list; - spinlock_t filter_info_list_lock; - - struct input_dev *rc_input_dev; - char rc_phys[64]; - - int active; /* Loaded successfully */ -}; - -struct urb_frame { - u8 data[ISO_FRAME_SIZE]; - int length; - struct list_head urb_frame_list; -}; - -struct filter_info { - u8 stream_id; - struct dvb_demux_filter *filter; - struct list_head filter_info_list; -}; - -static u16 rc_keys[] = { - KEY_POWER, - KEY_MUTE, - KEY_1, - KEY_2, - KEY_3, - KEY_4, - KEY_5, - KEY_6, - KEY_7, - KEY_8, - KEY_9, - KEY_0, - KEY_CHANNELUP, - KEY_VOLUMEDOWN, - KEY_OK, - KEY_VOLUMEUP, - KEY_CHANNELDOWN, - KEY_PREVIOUS, - KEY_ESC, - KEY_RED, - KEY_GREEN, - KEY_YELLOW, - KEY_BLUE, - KEY_OPTION, - KEY_M, - KEY_RADIO -}; - -static void ttusb_dec_set_model(struct ttusb_dec *dec, - enum ttusb_dec_model model); - -static void ttusb_dec_handle_irq( struct urb *urb) -{ - struct ttusb_dec * dec = urb->context; - char *buffer = dec->irq_buffer; - int retval; - - switch(urb->status) { - case 0: /*success*/ - break; - case -ECONNRESET: - case -ENOENT: - case -ESHUTDOWN: - case -ETIME: - /* this urb is dead, cleanup */ - dprintk("%s:urb shutting down with status: %d\n", - __func__, urb->status); - return; - default: - dprintk("%s:nonzero status received: %d\n", - __func__,urb->status); - goto exit; - } - - if( (buffer[0] == 0x1) && (buffer[2] == 0x15) ) { - /* IR - Event */ - /* this is an fact a bit too simple implementation; - * the box also reports a keyrepeat signal - * (with buffer[3] == 0x40) in an intervall of ~100ms. - * But to handle this correctly we had to imlemenent some - * kind of timer which signals a 'key up' event if no - * keyrepeat signal is recieved for lets say 200ms. - * this should/could be added later ... - * for now lets report each signal as a key down and up*/ - dprintk("%s:rc signal:%d\n", __func__, buffer[4]); - input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1); - input_sync(dec->rc_input_dev); - input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0); - input_sync(dec->rc_input_dev); - } - -exit: retval = usb_submit_urb(urb, GFP_ATOMIC); - if(retval) - printk("%s - usb_commit_urb failed with result: %d\n", - __func__, retval); -} - -static u16 crc16(u16 crc, const u8 *buf, size_t len) -{ - u16 tmp; - - while (len--) { - crc ^= *buf++; - crc ^= (u8)crc >> 4; - tmp = (u8)crc; - crc ^= (tmp ^ (tmp << 1)) << 4; - } - return crc; -} - -static int ttusb_dec_send_command(struct ttusb_dec *dec, const u8 command, - int param_length, const u8 params[], - int *result_length, u8 cmd_result[]) -{ - int result, actual_len, i; - u8 *b; - - dprintk("%s\n", __func__); - - b = kmalloc(COMMAND_PACKET_SIZE + 4, GFP_KERNEL); - if (!b) - return -ENOMEM; - - if ((result = mutex_lock_interruptible(&dec->usb_mutex))) { - kfree(b); - printk("%s: Failed to lock usb mutex.\n", __func__); - return result; - } - - b[0] = 0xaa; - b[1] = ++dec->trans_count; - b[2] = command; - b[3] = param_length; - - if (params) - memcpy(&b[4], params, param_length); - - if (debug) { - printk("%s: command: ", __func__); - for (i = 0; i < param_length + 4; i++) - printk("0x%02X ", b[i]); - printk("\n"); - } - - result = usb_bulk_msg(dec->udev, dec->command_pipe, b, - COMMAND_PACKET_SIZE + 4, &actual_len, 1000); - - if (result) { - printk("%s: command bulk message failed: error %d\n", - __func__, result); - mutex_unlock(&dec->usb_mutex); - kfree(b); - return result; - } - - result = usb_bulk_msg(dec->udev, dec->result_pipe, b, - COMMAND_PACKET_SIZE + 4, &actual_len, 1000); - - if (result) { - printk("%s: result bulk message failed: error %d\n", - __func__, result); - mutex_unlock(&dec->usb_mutex); - kfree(b); - return result; - } else { - if (debug) { - printk("%s: result: ", __func__); - for (i = 0; i < actual_len; i++) - printk("0x%02X ", b[i]); - printk("\n"); - } - - if (result_length) - *result_length = b[3]; - if (cmd_result && b[3] > 0) - memcpy(cmd_result, &b[4], b[3]); - - mutex_unlock(&dec->usb_mutex); - - kfree(b); - return 0; - } -} - -static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, - unsigned int *model, unsigned int *version) -{ - u8 c[COMMAND_PACKET_SIZE]; - int c_length; - int result; - __be32 tmp; - - dprintk("%s\n", __func__); - - result = ttusb_dec_send_command(dec, 0x08, 0, NULL, &c_length, c); - if (result) - return result; - - if (c_length >= 0x0c) { - if (mode != NULL) { - memcpy(&tmp, c, 4); - *mode = ntohl(tmp); - } - if (model != NULL) { - memcpy(&tmp, &c[4], 4); - *model = ntohl(tmp); - } - if (version != NULL) { - memcpy(&tmp, &c[8], 4); - *version = ntohl(tmp); - } - return 0; - } else { - return -1; - } -} - -static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) -{ - struct ttusb_dec *dec = priv; - - dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, - &dec->audio_filter->feed->feed.ts, - DMX_OK); - - return 0; -} - -static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) -{ - struct ttusb_dec *dec = priv; - - dec->video_filter->feed->cb.ts(data, 188, NULL, 0, - &dec->video_filter->feed->feed.ts, - DMX_OK); - - return 0; -} - -static void ttusb_dec_set_pids(struct ttusb_dec *dec) -{ - u8 b[] = { 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff }; - - __be16 pcr = htons(dec->pid[DMX_PES_PCR]); - __be16 audio = htons(dec->pid[DMX_PES_AUDIO]); - __be16 video = htons(dec->pid[DMX_PES_VIDEO]); - - dprintk("%s\n", __func__); - - memcpy(&b[0], &pcr, 2); - memcpy(&b[2], &audio, 2); - memcpy(&b[4], &video, 2); - - ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL); - - dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO], - ttusb_dec_audio_pes2ts_cb, dec); - dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO], - ttusb_dec_video_pes2ts_cb, dec); - dec->v_pes_length = 0; - dec->v_pes_postbytes = 0; -} - -static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) -{ - if (length < 8) { - printk("%s: packet too short - discarding\n", __func__); - return; - } - - if (length > 8 + MAX_PVA_LENGTH) { - printk("%s: packet too long - discarding\n", __func__); - return; - } - - switch (pva[2]) { - - case 0x01: { /* VideoStream */ - int prebytes = pva[5] & 0x03; - int postbytes = (pva[5] & 0x0c) >> 2; - __be16 v_pes_payload_length; - - if (output_pva) { - dec->video_filter->feed->cb.ts(pva, length, NULL, 0, - &dec->video_filter->feed->feed.ts, DMX_OK); - return; - } - - if (dec->v_pes_postbytes > 0 && - dec->v_pes_postbytes == prebytes) { - memcpy(&dec->v_pes[dec->v_pes_length], - &pva[12], prebytes); - - dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes, - dec->v_pes_length + prebytes, 1); - } - - if (pva[5] & 0x10) { - dec->v_pes[7] = 0x80; - dec->v_pes[8] = 0x05; - - dec->v_pes[9] = 0x21 | ((pva[8] & 0xc0) >> 5); - dec->v_pes[10] = ((pva[8] & 0x3f) << 2) | - ((pva[9] & 0xc0) >> 6); - dec->v_pes[11] = 0x01 | - ((pva[9] & 0x3f) << 2) | - ((pva[10] & 0x80) >> 6); - dec->v_pes[12] = ((pva[10] & 0x7f) << 1) | - ((pva[11] & 0xc0) >> 7); - dec->v_pes[13] = 0x01 | ((pva[11] & 0x7f) << 1); - - memcpy(&dec->v_pes[14], &pva[12 + prebytes], - length - 12 - prebytes); - dec->v_pes_length = 14 + length - 12 - prebytes; - } else { - dec->v_pes[7] = 0x00; - dec->v_pes[8] = 0x00; - - memcpy(&dec->v_pes[9], &pva[8], length - 8); - dec->v_pes_length = 9 + length - 8; - } - - dec->v_pes_postbytes = postbytes; - - if (dec->v_pes[9 + dec->v_pes[8]] == 0x00 && - dec->v_pes[10 + dec->v_pes[8]] == 0x00 && - dec->v_pes[11 + dec->v_pes[8]] == 0x01) - dec->v_pes[6] = 0x84; - else - dec->v_pes[6] = 0x80; - - v_pes_payload_length = htons(dec->v_pes_length - 6 + - postbytes); - memcpy(&dec->v_pes[4], &v_pes_payload_length, 2); - - if (postbytes == 0) - dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes, - dec->v_pes_length, 1); - - break; - } - - case 0x02: /* MainAudioStream */ - if (output_pva) { - dec->audio_filter->feed->cb.ts(pva, length, NULL, 0, - &dec->audio_filter->feed->feed.ts, DMX_OK); - return; - } - - dvb_filter_pes2ts(&dec->a_pes2ts, &pva[8], length - 8, - pva[5] & 0x10); - break; - - default: - printk("%s: unknown PVA type: %02x.\n", __func__, - pva[2]); - break; - } -} - -static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet, - int length) -{ - struct list_head *item; - struct filter_info *finfo; - struct dvb_demux_filter *filter = NULL; - unsigned long flags; - u8 sid; - - sid = packet[1]; - spin_lock_irqsave(&dec->filter_info_list_lock, flags); - for (item = dec->filter_info_list.next; item != &dec->filter_info_list; - item = item->next) { - finfo = list_entry(item, struct filter_info, filter_info_list); - if (finfo->stream_id == sid) { - filter = finfo->filter; - break; - } - } - spin_unlock_irqrestore(&dec->filter_info_list_lock, flags); - - if (filter) - filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, - &filter->filter, DMX_OK); -} - -static void ttusb_dec_process_packet(struct ttusb_dec *dec) -{ - int i; - u16 csum = 0; - u16 packet_id; - - if (dec->packet_length % 2) { - printk("%s: odd sized packet - discarding\n", __func__); - return; - } - - for (i = 0; i < dec->packet_length; i += 2) - csum ^= ((dec->packet[i] << 8) + dec->packet[i + 1]); - - if (csum) { - printk("%s: checksum failed - discarding\n", __func__); - return; - } - - packet_id = dec->packet[dec->packet_length - 4] << 8; - packet_id += dec->packet[dec->packet_length - 3]; - - if ((packet_id != dec->next_packet_id) && dec->next_packet_id) { - printk("%s: warning: lost packets between %u and %u\n", - __func__, dec->next_packet_id - 1, packet_id); - } - - if (packet_id == 0xffff) - dec->next_packet_id = 0x8000; - else - dec->next_packet_id = packet_id + 1; - - switch (dec->packet_type) { - case TTUSB_DEC_PACKET_PVA: - if (dec->pva_stream_count) - ttusb_dec_process_pva(dec, dec->packet, - dec->packet_payload_length); - break; - - case TTUSB_DEC_PACKET_SECTION: - if (dec->filter_stream_count) - ttusb_dec_process_filter(dec, dec->packet, - dec->packet_payload_length); - break; - - case TTUSB_DEC_PACKET_EMPTY: - break; - } -} - -static void swap_bytes(u8 *b, int length) -{ - u8 c; - - length -= length % 2; - for (; length; b += 2, length -= 2) { - c = *b; - *b = *(b + 1); - *(b + 1) = c; - } -} - -static void ttusb_dec_process_urb_frame(struct ttusb_dec *dec, u8 *b, - int length) -{ - swap_bytes(b, length); - - while (length) { - switch (dec->packet_state) { - - case 0: - case 1: - case 2: - if (*b++ == 0xaa) - dec->packet_state++; - else - dec->packet_state = 0; - - length--; - break; - - case 3: - if (*b == 0x00) { - dec->packet_state++; - dec->packet_length = 0; - } else if (*b != 0xaa) { - dec->packet_state = 0; - } - - b++; - length--; - break; - - case 4: - dec->packet[dec->packet_length++] = *b++; - - if (dec->packet_length == 2) { - if (dec->packet[0] == 'A' && - dec->packet[1] == 'V') { - dec->packet_type = - TTUSB_DEC_PACKET_PVA; - dec->packet_state++; - } else if (dec->packet[0] == 'S') { - dec->packet_type = - TTUSB_DEC_PACKET_SECTION; - dec->packet_state++; - } else if (dec->packet[0] == 0x00) { - dec->packet_type = - TTUSB_DEC_PACKET_EMPTY; - dec->packet_payload_length = 2; - dec->packet_state = 7; - } else { - printk("%s: unknown packet type: " - "%02x%02x\n", __func__, - dec->packet[0], dec->packet[1]); - dec->packet_state = 0; - } - } - - length--; - break; - - case 5: - dec->packet[dec->packet_length++] = *b++; - - if (dec->packet_type == TTUSB_DEC_PACKET_PVA && - dec->packet_length == 8) { - dec->packet_state++; - dec->packet_payload_length = 8 + - (dec->packet[6] << 8) + - dec->packet[7]; - } else if (dec->packet_type == - TTUSB_DEC_PACKET_SECTION && - dec->packet_length == 5) { - dec->packet_state++; - dec->packet_payload_length = 5 + - ((dec->packet[3] & 0x0f) << 8) + - dec->packet[4]; - } - - length--; - break; - - case 6: { - int remainder = dec->packet_payload_length - - dec->packet_length; - - if (length >= remainder) { - memcpy(dec->packet + dec->packet_length, - b, remainder); - dec->packet_length += remainder; - b += remainder; - length -= remainder; - dec->packet_state++; - } else { - memcpy(&dec->packet[dec->packet_length], - b, length); - dec->packet_length += length; - length = 0; - } - - break; - } - - case 7: { - int tail = 4; - - dec->packet[dec->packet_length++] = *b++; - - if (dec->packet_type == TTUSB_DEC_PACKET_SECTION && - dec->packet_payload_length % 2) - tail++; - - if (dec->packet_length == - dec->packet_payload_length + tail) { - ttusb_dec_process_packet(dec); - dec->packet_state = 0; - } - - length--; - break; - } - - default: - printk("%s: illegal packet state encountered.\n", - __func__); - dec->packet_state = 0; - } - } -} - -static void ttusb_dec_process_urb_frame_list(unsigned long data) -{ - struct ttusb_dec *dec = (struct ttusb_dec *)data; - struct list_head *item; - struct urb_frame *frame; - unsigned long flags; - - while (1) { - spin_lock_irqsave(&dec->urb_frame_list_lock, flags); - if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) { - frame = list_entry(item, struct urb_frame, - urb_frame_list); - list_del(&frame->urb_frame_list); - } else { - spin_unlock_irqrestore(&dec->urb_frame_list_lock, - flags); - return; - } - spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags); - - ttusb_dec_process_urb_frame(dec, frame->data, frame->length); - kfree(frame); - } -} - -static void ttusb_dec_process_urb(struct urb *urb) -{ - struct ttusb_dec *dec = urb->context; - - if (!urb->status) { - int i; - - for (i = 0; i < FRAMES_PER_ISO_BUF; i++) { - struct usb_iso_packet_descriptor *d; - u8 *b; - int length; - struct urb_frame *frame; - - d = &urb->iso_frame_desc[i]; - b = urb->transfer_buffer + d->offset; - length = d->actual_length; - - if ((frame = kmalloc(sizeof(struct urb_frame), - GFP_ATOMIC))) { - unsigned long flags; - - memcpy(frame->data, b, length); - frame->length = length; - - spin_lock_irqsave(&dec->urb_frame_list_lock, - flags); - list_add_tail(&frame->urb_frame_list, - &dec->urb_frame_list); - spin_unlock_irqrestore(&dec->urb_frame_list_lock, - flags); - - tasklet_schedule(&dec->urb_tasklet); - } - } - } else { - /* -ENOENT is expected when unlinking urbs */ - if (urb->status != -ENOENT) - dprintk("%s: urb error: %d\n", __func__, - urb->status); - } - - if (dec->iso_stream_count) - usb_submit_urb(urb, GFP_ATOMIC); -} - -static void ttusb_dec_setup_urbs(struct ttusb_dec *dec) -{ - int i, j, buffer_offset = 0; - - dprintk("%s\n", __func__); - - for (i = 0; i < ISO_BUF_COUNT; i++) { - int frame_offset = 0; - struct urb *urb = dec->iso_urb[i]; - - urb->dev = dec->udev; - urb->context = dec; - urb->complete = ttusb_dec_process_urb; - urb->pipe = dec->in_pipe; - urb->transfer_flags = URB_ISO_ASAP; - urb->interval = 1; - urb->number_of_packets = FRAMES_PER_ISO_BUF; - urb->transfer_buffer_length = ISO_FRAME_SIZE * - FRAMES_PER_ISO_BUF; - urb->transfer_buffer = dec->iso_buffer + buffer_offset; - buffer_offset += ISO_FRAME_SIZE * FRAMES_PER_ISO_BUF; - - for (j = 0; j < FRAMES_PER_ISO_BUF; j++) { - urb->iso_frame_desc[j].offset = frame_offset; - urb->iso_frame_desc[j].length = ISO_FRAME_SIZE; - frame_offset += ISO_FRAME_SIZE; - } - } -} - -static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) -{ - int i; - - dprintk("%s\n", __func__); - - if (mutex_lock_interruptible(&dec->iso_mutex)) - return; - - dec->iso_stream_count--; - - if (!dec->iso_stream_count) { - for (i = 0; i < ISO_BUF_COUNT; i++) - usb_kill_urb(dec->iso_urb[i]); - } - - mutex_unlock(&dec->iso_mutex); -} - -/* Setting the interface of the DEC tends to take down the USB communications - * for a short period, so it's important not to call this function just before - * trying to talk to it. - */ -static int ttusb_dec_set_interface(struct ttusb_dec *dec, - enum ttusb_dec_interface interface) -{ - int result = 0; - u8 b[] = { 0x05 }; - - if (interface != dec->interface) { - switch (interface) { - case TTUSB_DEC_INTERFACE_INITIAL: - result = usb_set_interface(dec->udev, 0, 0); - break; - case TTUSB_DEC_INTERFACE_IN: - result = ttusb_dec_send_command(dec, 0x80, sizeof(b), - b, NULL, NULL); - if (result) - return result; - result = usb_set_interface(dec->udev, 0, 8); - break; - case TTUSB_DEC_INTERFACE_OUT: - result = usb_set_interface(dec->udev, 0, 1); - break; - } - - if (result) - return result; - - dec->interface = interface; - } - - return 0; -} - -static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) -{ - int i, result; - - dprintk("%s\n", __func__); - - if (mutex_lock_interruptible(&dec->iso_mutex)) - return -EAGAIN; - - if (!dec->iso_stream_count) { - ttusb_dec_setup_urbs(dec); - - dec->packet_state = 0; - dec->v_pes_postbytes = 0; - dec->next_packet_id = 0; - - for (i = 0; i < ISO_BUF_COUNT; i++) { - if ((result = usb_submit_urb(dec->iso_urb[i], - GFP_ATOMIC))) { - printk("%s: failed urb submission %d: " - "error %d\n", __func__, i, result); - - while (i) { - usb_kill_urb(dec->iso_urb[i - 1]); - i--; - } - - mutex_unlock(&dec->iso_mutex); - return result; - } - } - } - - dec->iso_stream_count++; - - mutex_unlock(&dec->iso_mutex); - - return 0; -} - -static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - struct ttusb_dec *dec = dvbdmx->priv; - u8 b0[] = { 0x05 }; - int result = 0; - - dprintk("%s\n", __func__); - - dprintk(" ts_type:"); - - if (dvbdmxfeed->ts_type & TS_DECODER) - dprintk(" TS_DECODER"); - - if (dvbdmxfeed->ts_type & TS_PACKET) - dprintk(" TS_PACKET"); - - if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) - dprintk(" TS_PAYLOAD_ONLY"); - - dprintk("\n"); - - switch (dvbdmxfeed->pes_type) { - - case DMX_TS_PES_VIDEO: - dprintk(" pes_type: DMX_TS_PES_VIDEO\n"); - dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid; - dec->pid[DMX_PES_VIDEO] = dvbdmxfeed->pid; - dec->video_filter = dvbdmxfeed->filter; - ttusb_dec_set_pids(dec); - break; - - case DMX_TS_PES_AUDIO: - dprintk(" pes_type: DMX_TS_PES_AUDIO\n"); - dec->pid[DMX_PES_AUDIO] = dvbdmxfeed->pid; - dec->audio_filter = dvbdmxfeed->filter; - ttusb_dec_set_pids(dec); - break; - - case DMX_TS_PES_TELETEXT: - dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; - dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n"); - return -ENOSYS; - - case DMX_TS_PES_PCR: - dprintk(" pes_type: DMX_TS_PES_PCR\n"); - dec->pid[DMX_PES_PCR] = dvbdmxfeed->pid; - ttusb_dec_set_pids(dec); - break; - - case DMX_TS_PES_OTHER: - dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n"); - return -ENOSYS; - - default: - dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); - return -EINVAL; - - } - - result = ttusb_dec_send_command(dec, 0x80, sizeof(b0), b0, NULL, NULL); - if (result) - return result; - - dec->pva_stream_count++; - return ttusb_dec_start_iso_xfer(dec); -} - -static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct ttusb_dec *dec = dvbdmxfeed->demux->priv; - u8 b0[] = { 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00 }; - __be16 pid; - u8 c[COMMAND_PACKET_SIZE]; - int c_length; - int result; - struct filter_info *finfo; - unsigned long flags; - u8 x = 1; - - dprintk("%s\n", __func__); - - pid = htons(dvbdmxfeed->pid); - memcpy(&b0[0], &pid, 2); - memcpy(&b0[4], &x, 1); - memcpy(&b0[5], &dvbdmxfeed->filter->filter.filter_value[0], 1); - - result = ttusb_dec_send_command(dec, 0x60, sizeof(b0), b0, - &c_length, c); - - if (!result) { - if (c_length == 2) { - if (!(finfo = kmalloc(sizeof(struct filter_info), - GFP_ATOMIC))) - return -ENOMEM; - - finfo->stream_id = c[1]; - finfo->filter = dvbdmxfeed->filter; - - spin_lock_irqsave(&dec->filter_info_list_lock, flags); - list_add_tail(&finfo->filter_info_list, - &dec->filter_info_list); - spin_unlock_irqrestore(&dec->filter_info_list_lock, - flags); - - dvbdmxfeed->priv = finfo; - - dec->filter_stream_count++; - return ttusb_dec_start_iso_xfer(dec); - } - - return -EAGAIN; - } else - return result; -} - -static int ttusb_dec_start_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct dvb_demux *dvbdmx = dvbdmxfeed->demux; - - dprintk("%s\n", __func__); - - if (!dvbdmx->dmx.frontend) - return -EINVAL; - - dprintk(" pid: 0x%04X\n", dvbdmxfeed->pid); - - switch (dvbdmxfeed->type) { - - case DMX_TYPE_TS: - return ttusb_dec_start_ts_feed(dvbdmxfeed); - break; - - case DMX_TYPE_SEC: - return ttusb_dec_start_sec_feed(dvbdmxfeed); - break; - - default: - dprintk(" type: unknown (%d)\n", dvbdmxfeed->type); - return -EINVAL; - - } -} - -static int ttusb_dec_stop_ts_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct ttusb_dec *dec = dvbdmxfeed->demux->priv; - u8 b0[] = { 0x00 }; - - ttusb_dec_send_command(dec, 0x81, sizeof(b0), b0, NULL, NULL); - - dec->pva_stream_count--; - - ttusb_dec_stop_iso_xfer(dec); - - return 0; -} - -static int ttusb_dec_stop_sec_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - struct ttusb_dec *dec = dvbdmxfeed->demux->priv; - u8 b0[] = { 0x00, 0x00 }; - struct filter_info *finfo = (struct filter_info *)dvbdmxfeed->priv; - unsigned long flags; - - b0[1] = finfo->stream_id; - spin_lock_irqsave(&dec->filter_info_list_lock, flags); - list_del(&finfo->filter_info_list); - spin_unlock_irqrestore(&dec->filter_info_list_lock, flags); - kfree(finfo); - ttusb_dec_send_command(dec, 0x62, sizeof(b0), b0, NULL, NULL); - - dec->filter_stream_count--; - - ttusb_dec_stop_iso_xfer(dec); - - return 0; -} - -static int ttusb_dec_stop_feed(struct dvb_demux_feed *dvbdmxfeed) -{ - dprintk("%s\n", __func__); - - switch (dvbdmxfeed->type) { - case DMX_TYPE_TS: - return ttusb_dec_stop_ts_feed(dvbdmxfeed); - break; - - case DMX_TYPE_SEC: - return ttusb_dec_stop_sec_feed(dvbdmxfeed); - break; - } - - return 0; -} - -static void ttusb_dec_free_iso_urbs(struct ttusb_dec *dec) -{ - int i; - - dprintk("%s\n", __func__); - - for (i = 0; i < ISO_BUF_COUNT; i++) - usb_free_urb(dec->iso_urb[i]); - - pci_free_consistent(NULL, - ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * - ISO_BUF_COUNT), - dec->iso_buffer, dec->iso_dma_handle); -} - -static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) -{ - int i; - - dprintk("%s\n", __func__); - - dec->iso_buffer = pci_alloc_consistent(NULL, - ISO_FRAME_SIZE * - (FRAMES_PER_ISO_BUF * - ISO_BUF_COUNT), - &dec->iso_dma_handle); - - if (!dec->iso_buffer) { - dprintk("%s: pci_alloc_consistent - not enough memory\n", - __func__); - return -ENOMEM; - } - - memset(dec->iso_buffer, 0, - ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT)); - - for (i = 0; i < ISO_BUF_COUNT; i++) { - struct urb *urb; - - if (!(urb = usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) { - ttusb_dec_free_iso_urbs(dec); - return -ENOMEM; - } - - dec->iso_urb[i] = urb; - } - - ttusb_dec_setup_urbs(dec); - - return 0; -} - -static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) -{ - spin_lock_init(&dec->urb_frame_list_lock); - INIT_LIST_HEAD(&dec->urb_frame_list); - tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list, - (unsigned long)dec); -} - -static int ttusb_init_rc( struct ttusb_dec *dec) -{ - struct input_dev *input_dev; - u8 b[] = { 0x00, 0x01 }; - int i; - int err; - - usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys)); - strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys)); - - input_dev = input_allocate_device(); - if (!input_dev) - return -ENOMEM; - - input_dev->name = "ttusb_dec remote control"; - input_dev->phys = dec->rc_phys; - input_dev->evbit[0] = BIT_MASK(EV_KEY); - input_dev->keycodesize = sizeof(u16); - input_dev->keycodemax = 0x1a; - input_dev->keycode = rc_keys; - - for (i = 0; i < ARRAY_SIZE(rc_keys); i++) - set_bit(rc_keys[i], input_dev->keybit); - - err = input_register_device(input_dev); - if (err) { - input_free_device(input_dev); - return err; - } - - dec->rc_input_dev = input_dev; - if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) - printk("%s: usb_submit_urb failed\n",__func__); - /* enable irq pipe */ - ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); - - return 0; -} - -static void ttusb_dec_init_v_pes(struct ttusb_dec *dec) -{ - dprintk("%s\n", __func__); - - dec->v_pes[0] = 0x00; - dec->v_pes[1] = 0x00; - dec->v_pes[2] = 0x01; - dec->v_pes[3] = 0xe0; -} - -static int ttusb_dec_init_usb(struct ttusb_dec *dec) -{ - dprintk("%s\n", __func__); - - mutex_init(&dec->usb_mutex); - mutex_init(&dec->iso_mutex); - - dec->command_pipe = usb_sndbulkpipe(dec->udev, COMMAND_PIPE); - dec->result_pipe = usb_rcvbulkpipe(dec->udev, RESULT_PIPE); - dec->in_pipe = usb_rcvisocpipe(dec->udev, IN_PIPE); - dec->out_pipe = usb_sndisocpipe(dec->udev, OUT_PIPE); - dec->irq_pipe = usb_rcvintpipe(dec->udev, IRQ_PIPE); - - if(enable_rc) { - dec->irq_urb = usb_alloc_urb(0, GFP_KERNEL); - if(!dec->irq_urb) { - return -ENOMEM; - } - dec->irq_buffer = usb_buffer_alloc(dec->udev,IRQ_PACKET_SIZE, - GFP_ATOMIC, &dec->irq_dma_handle); - if(!dec->irq_buffer) { - usb_free_urb(dec->irq_urb); - return -ENOMEM; - } - usb_fill_int_urb(dec->irq_urb, dec->udev,dec->irq_pipe, - dec->irq_buffer, IRQ_PACKET_SIZE, - ttusb_dec_handle_irq, dec, 1); - dec->irq_urb->transfer_dma = dec->irq_dma_handle; - dec->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - } - - return ttusb_dec_alloc_iso_urbs(dec); -} - -static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) -{ - int i, j, actual_len, result, size, trans_count; - u8 b0[] = { 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x61, 0x00 }; - u8 b1[] = { 0x61 }; - u8 *b; - char idstring[21]; - const u8 *firmware = NULL; - size_t firmware_size = 0; - u16 firmware_csum = 0; - __be16 firmware_csum_ns; - __be32 firmware_size_nl; - u32 crc32_csum, crc32_check; - __be32 tmp; - const struct firmware *fw_entry = NULL; - - dprintk("%s\n", __func__); - - if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) { - printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", - __func__, dec->firmware_name); - return 1; - } - - firmware = fw_entry->data; - firmware_size = fw_entry->size; - - if (firmware_size < 60) { - printk("%s: firmware size too small for DSP code (%zu < 60).\n", - __func__, firmware_size); - release_firmware(fw_entry); - return -1; - } - - /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored - at offset 56 of file, so use it to check if the firmware file is - valid. */ - crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; - memcpy(&tmp, &firmware[56], 4); - crc32_check = ntohl(tmp); - if (crc32_csum != crc32_check) { - printk("%s: crc32 check of DSP code failed (calculated " - "0x%08x != 0x%08x in file), file invalid.\n", - __func__, crc32_csum, crc32_check); - release_firmware(fw_entry); - return -1; - } - memcpy(idstring, &firmware[36], 20); - idstring[20] = '\0'; - printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring); - - firmware_size_nl = htonl(firmware_size); - memcpy(b0, &firmware_size_nl, 4); - firmware_csum = crc16(~0, firmware, firmware_size) ^ ~0; - firmware_csum_ns = htons(firmware_csum); - memcpy(&b0[6], &firmware_csum_ns, 2); - - result = ttusb_dec_send_command(dec, 0x41, sizeof(b0), b0, NULL, NULL); - - if (result) { - release_firmware(fw_entry); - return result; - } - - trans_count = 0; - j = 0; - - b = kmalloc(ARM_PACKET_SIZE, GFP_KERNEL); - if (b == NULL) { - release_firmware(fw_entry); - return -ENOMEM; - } - - for (i = 0; i < firmware_size; i += COMMAND_PACKET_SIZE) { - size = firmware_size - i; - if (size > COMMAND_PACKET_SIZE) - size = COMMAND_PACKET_SIZE; - - b[j + 0] = 0xaa; - b[j + 1] = trans_count++; - b[j + 2] = 0xf0; - b[j + 3] = size; - memcpy(&b[j + 4], &firmware[i], size); - - j += COMMAND_PACKET_SIZE + 4; - - if (j >= ARM_PACKET_SIZE) { - result = usb_bulk_msg(dec->udev, dec->command_pipe, b, - ARM_PACKET_SIZE, &actual_len, - 100); - j = 0; - } else if (size < COMMAND_PACKET_SIZE) { - result = usb_bulk_msg(dec->udev, dec->command_pipe, b, - j - COMMAND_PACKET_SIZE + size, - &actual_len, 100); - } - } - - result = ttusb_dec_send_command(dec, 0x43, sizeof(b1), b1, NULL, NULL); - - release_firmware(fw_entry); - kfree(b); - - return result; -} - -static int ttusb_dec_init_stb(struct ttusb_dec *dec) -{ - int result; - unsigned int mode, model, version; - - dprintk("%s\n", __func__); - - result = ttusb_dec_get_stb_state(dec, &mode, &model, &version); - - if (!result) { - if (!mode) { - if (version == 0xABCDEFAB) - printk(KERN_INFO "ttusb_dec: no version " - "info in Firmware\n"); - else - printk(KERN_INFO "ttusb_dec: Firmware " - "%x.%02x%c%c\n", - version >> 24, (version >> 16) & 0xff, - (version >> 8) & 0xff, version & 0xff); - - result = ttusb_dec_boot_dsp(dec); - if (result) - return result; - else - return 1; - } else { - /* We can't trust the USB IDs that some firmwares - give the box */ - switch (model) { - case 0x00070001: - case 0x00070008: - case 0x0007000c: - ttusb_dec_set_model(dec, TTUSB_DEC3000S); - break; - case 0x00070009: - case 0x00070013: - ttusb_dec_set_model(dec, TTUSB_DEC2000T); - break; - case 0x00070011: - ttusb_dec_set_model(dec, TTUSB_DEC2540T); - break; - default: - printk(KERN_ERR "%s: unknown model returned " - "by firmware (%08x) - please report\n", - __func__, model); - return -1; - break; - } - - if (version >= 0x01770000) - dec->can_playback = 1; - - return 0; - } - } - else - return result; -} - -static int ttusb_dec_init_dvb(struct ttusb_dec *dec) -{ - int result; - - dprintk("%s\n", __func__); - - if ((result = dvb_register_adapter(&dec->adapter, - dec->model_name, THIS_MODULE, - &dec->udev->dev, - adapter_nr)) < 0) { - printk("%s: dvb_register_adapter failed: error %d\n", - __func__, result); - - return result; - } - - dec->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; - - dec->demux.priv = (void *)dec; - dec->demux.filternum = 31; - dec->demux.feednum = 31; - dec->demux.start_feed = ttusb_dec_start_feed; - dec->demux.stop_feed = ttusb_dec_stop_feed; - dec->demux.write_to_decoder = NULL; - - if ((result = dvb_dmx_init(&dec->demux)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __func__, - result); - - dvb_unregister_adapter(&dec->adapter); - - return result; - } - - dec->dmxdev.filternum = 32; - dec->dmxdev.demux = &dec->demux.dmx; - dec->dmxdev.capabilities = 0; - - if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) { - printk("%s: dvb_dmxdev_init failed: error %d\n", - __func__, result); - - dvb_dmx_release(&dec->demux); - dvb_unregister_adapter(&dec->adapter); - - return result; - } - - dec->frontend.source = DMX_FRONTEND_0; - - if ((result = dec->demux.dmx.add_frontend(&dec->demux.dmx, - &dec->frontend)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __func__, - result); - - dvb_dmxdev_release(&dec->dmxdev); - dvb_dmx_release(&dec->demux); - dvb_unregister_adapter(&dec->adapter); - - return result; - } - - if ((result = dec->demux.dmx.connect_frontend(&dec->demux.dmx, - &dec->frontend)) < 0) { - printk("%s: dvb_dmx_init failed: error %d\n", __func__, - result); - - dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); - dvb_dmxdev_release(&dec->dmxdev); - dvb_dmx_release(&dec->demux); - dvb_unregister_adapter(&dec->adapter); - - return result; - } - - dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx); - - return 0; -} - -static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) -{ - dprintk("%s\n", __func__); - - dvb_net_release(&dec->dvb_net); - dec->demux.dmx.close(&dec->demux.dmx); - dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); - dvb_dmxdev_release(&dec->dmxdev); - dvb_dmx_release(&dec->demux); - if (dec->fe) { - dvb_unregister_frontend(dec->fe); - if (dec->fe->ops.release) - dec->fe->ops.release(dec->fe); - } - dvb_unregister_adapter(&dec->adapter); -} - -static void ttusb_dec_exit_rc(struct ttusb_dec *dec) -{ - - dprintk("%s\n", __func__); - /* we have to check whether the irq URB is already submitted. - * As the irq is submitted after the interface is changed, - * this is the best method i figured out. - * Any others?*/ - if (dec->interface == TTUSB_DEC_INTERFACE_IN) - usb_kill_urb(dec->irq_urb); - - usb_free_urb(dec->irq_urb); - - usb_buffer_free(dec->udev,IRQ_PACKET_SIZE, - dec->irq_buffer, dec->irq_dma_handle); - - if (dec->rc_input_dev) { - input_unregister_device(dec->rc_input_dev); - dec->rc_input_dev = NULL; - } -} - - -static void ttusb_dec_exit_usb(struct ttusb_dec *dec) -{ - int i; - - dprintk("%s\n", __func__); - - dec->iso_stream_count = 0; - - for (i = 0; i < ISO_BUF_COUNT; i++) - usb_kill_urb(dec->iso_urb[i]); - - ttusb_dec_free_iso_urbs(dec); -} - -static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec) -{ - struct list_head *item; - struct urb_frame *frame; - - tasklet_kill(&dec->urb_tasklet); - - while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) { - frame = list_entry(item, struct urb_frame, urb_frame_list); - list_del(&frame->urb_frame_list); - kfree(frame); - } -} - -static void ttusb_dec_init_filters(struct ttusb_dec *dec) -{ - INIT_LIST_HEAD(&dec->filter_info_list); - spin_lock_init(&dec->filter_info_list_lock); -} - -static void ttusb_dec_exit_filters(struct ttusb_dec *dec) -{ - struct list_head *item; - struct filter_info *finfo; - - while ((item = dec->filter_info_list.next) != &dec->filter_info_list) { - finfo = list_entry(item, struct filter_info, filter_info_list); - list_del(&finfo->filter_info_list); - kfree(finfo); - } -} - -static int fe_send_command(struct dvb_frontend* fe, const u8 command, - int param_length, const u8 params[], - int *result_length, u8 cmd_result[]) -{ - struct ttusb_dec* dec = fe->dvb->priv; - return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); -} - -static struct ttusbdecfe_config fe_config = { - .send_command = fe_send_command -}; - -static int ttusb_dec_probe(struct usb_interface *intf, - const struct usb_device_id *id) -{ - struct usb_device *udev; - struct ttusb_dec *dec; - - dprintk("%s\n", __func__); - - udev = interface_to_usbdev(intf); - - if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) { - printk("%s: couldn't allocate memory.\n", __func__); - return -ENOMEM; - } - - usb_set_intfdata(intf, (void *)dec); - - switch (id->idProduct) { - case 0x1006: - ttusb_dec_set_model(dec, TTUSB_DEC3000S); - break; - - case 0x1008: - ttusb_dec_set_model(dec, TTUSB_DEC2000T); - break; - - case 0x1009: - ttusb_dec_set_model(dec, TTUSB_DEC2540T); - break; - } - - dec->udev = udev; - - if (ttusb_dec_init_usb(dec)) - return 0; - if (ttusb_dec_init_stb(dec)) { - ttusb_dec_exit_usb(dec); - return 0; - } - ttusb_dec_init_dvb(dec); - - dec->adapter.priv = dec; - switch (id->idProduct) { - case 0x1006: - dec->fe = ttusbdecfe_dvbs_attach(&fe_config); - break; - - case 0x1008: - case 0x1009: - dec->fe = ttusbdecfe_dvbt_attach(&fe_config); - break; - } - - if (dec->fe == NULL) { - printk("dvb-ttusb-dec: A frontend driver was not found for device [%04x:%04x]\n", - le16_to_cpu(dec->udev->descriptor.idVendor), - le16_to_cpu(dec->udev->descriptor.idProduct)); - } else { - if (dvb_register_frontend(&dec->adapter, dec->fe)) { - printk("budget-ci: Frontend registration failed!\n"); - if (dec->fe->ops.release) - dec->fe->ops.release(dec->fe); - dec->fe = NULL; - } - } - - ttusb_dec_init_v_pes(dec); - ttusb_dec_init_filters(dec); - ttusb_dec_init_tasklet(dec); - - dec->active = 1; - - ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN); - - if (enable_rc) - ttusb_init_rc(dec); - - return 0; -} - -static void ttusb_dec_disconnect(struct usb_interface *intf) -{ - struct ttusb_dec *dec = usb_get_intfdata(intf); - - usb_set_intfdata(intf, NULL); - - dprintk("%s\n", __func__); - - if (dec->active) { - ttusb_dec_exit_tasklet(dec); - ttusb_dec_exit_filters(dec); - if(enable_rc) - ttusb_dec_exit_rc(dec); - ttusb_dec_exit_usb(dec); - ttusb_dec_exit_dvb(dec); - } - - kfree(dec); -} - -static void ttusb_dec_set_model(struct ttusb_dec *dec, - enum ttusb_dec_model model) -{ - dec->model = model; - - switch (model) { - case TTUSB_DEC2000T: - dec->model_name = "DEC2000-t"; - dec->firmware_name = "dvb-ttusb-dec-2000t.fw"; - break; - - case TTUSB_DEC2540T: - dec->model_name = "DEC2540-t"; - dec->firmware_name = "dvb-ttusb-dec-2540t.fw"; - break; - - case TTUSB_DEC3000S: - dec->model_name = "DEC3000-s"; - dec->firmware_name = "dvb-ttusb-dec-3000s.fw"; - break; - } -} - -static struct usb_device_id ttusb_dec_table[] = { - {USB_DEVICE(0x0b48, 0x1006)}, /* DEC3000-s */ - /*{USB_DEVICE(0x0b48, 0x1007)}, Unconfirmed */ - {USB_DEVICE(0x0b48, 0x1008)}, /* DEC2000-t */ - {USB_DEVICE(0x0b48, 0x1009)}, /* DEC2540-t */ - {} -}; - -static struct usb_driver ttusb_dec_driver = { - .name = "ttusb-dec", - .probe = ttusb_dec_probe, - .disconnect = ttusb_dec_disconnect, - .id_table = ttusb_dec_table, -}; - -static int __init ttusb_dec_init(void) -{ - int result; - - if ((result = usb_register(&ttusb_dec_driver)) < 0) { - printk("%s: initialisation failed: error %d.\n", __func__, - result); - return result; - } - - return 0; -} - -static void __exit ttusb_dec_exit(void) -{ - usb_deregister(&ttusb_dec_driver); -} - -module_init(ttusb_dec_init); -module_exit(ttusb_dec_exit); - -MODULE_AUTHOR("Alex Woods <linux-dvb@giblets.org>"); -MODULE_DESCRIPTION(DRIVER_NAME); -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(usb, ttusb_dec_table); diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c deleted file mode 100644 index 21260aad1e5..00000000000 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * TTUSB DEC Frontend Driver - * - * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include "dvb_frontend.h" -#include "ttusbdecfe.h" - - -#define LOF_HI 10600000 -#define LOF_LO 9750000 - -struct ttusbdecfe_state { - - /* configuration settings */ - const struct ttusbdecfe_config* config; - - struct dvb_frontend frontend; - - u8 hi_band; - u8 voltage; -}; - - -static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe, - fe_status_t *status) -{ - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - return 0; -} - - -static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe, - fe_status_t *status) -{ - struct ttusbdecfe_state* state = fe->demodulator_priv; - u8 b[] = { 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - u8 result[4]; - int len, ret; - - *status=0; - - ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result); - if(ret) - return ret; - - if(len != 4) { - printk(KERN_ERR "%s: unexpected reply\n", __func__); - return -EIO; - } - - switch(result[3]) { - case 1: /* not tuned yet */ - case 2: /* no signal/no lock*/ - break; - case 3: /* signal found and locked*/ - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - break; - case 4: - *status = FE_TIMEDOUT; - break; - default: - pr_info("%s: returned unknown value: %d\n", - __func__, result[3]); - return -EIO; - } - - return 0; -} - -static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; - u8 b[] = { 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0xff }; - - __be32 freq = htonl(p->frequency / 1000); - memcpy(&b[4], &freq, sizeof (u32)); - state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); - - return 0; -} - -static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 1500; - /* Drift compensation makes no sense for DVB-T */ - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - -static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; - - u8 b[] = { 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - __be32 freq; - __be32 sym_rate; - __be32 band; - __be32 lnb_voltage; - - freq = htonl(p->frequency + - (state->hi_band ? LOF_HI : LOF_LO)); - memcpy(&b[4], &freq, sizeof(u32)); - sym_rate = htonl(p->u.qam.symbol_rate); - memcpy(&b[12], &sym_rate, sizeof(u32)); - band = htonl(state->hi_band ? LOF_HI : LOF_LO); - memcpy(&b[24], &band, sizeof(u32)); - lnb_voltage = htonl(state->voltage); - memcpy(&b[28], &lnb_voltage, sizeof(u32)); - - state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); - - return 0; -} - -static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) -{ - struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; - u8 b[] = { 0x00, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00 }; - - memcpy(&b[4], cmd->msg, cmd->msg_len); - - state->config->send_command(fe, 0x72, - sizeof(b) - (6 - cmd->msg_len), b, - NULL, NULL); - - return 0; -} - - -static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; - - state->hi_band = (SEC_TONE_ON == tone); - - return 0; -} - - -static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; - - switch (voltage) { - case SEC_VOLTAGE_13: - state->voltage = 13; - break; - case SEC_VOLTAGE_18: - state->voltage = 18; - break; - default: - return -EINVAL; - } - - return 0; -} - -static void ttusbdecfe_release(struct dvb_frontend* fe) -{ - struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops ttusbdecfe_dvbt_ops; - -struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config) -{ - struct ttusbdecfe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - /* setup the state */ - state->config = config; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops ttusbdecfe_dvbs_ops; - -struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config) -{ - struct ttusbdecfe_state* state = NULL; - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); - if (state == NULL) - return NULL; - - /* setup the state */ - state->config = config; - state->voltage = 0; - state->hi_band = 0; - - /* create dvb_frontend */ - memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { - - .info = { - .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, - }, - - .release = ttusbdecfe_release, - - .set_frontend = ttusbdecfe_dvbt_set_frontend, - - .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, - - .read_status = ttusbdecfe_dvbt_read_status, -}; - -static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { - - .info = { - .name = "TechnoTrend/Hauppauge DEC3000-s Frontend", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, - .symbol_rate_min = 1000000, /* guessed */ - .symbol_rate_max = 45000000, /* guessed */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK - }, - - .release = ttusbdecfe_release, - - .set_frontend = ttusbdecfe_dvbs_set_frontend, - - .read_status = ttusbdecfe_dvbs_read_status, - - .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd, - .set_voltage = ttusbdecfe_dvbs_set_voltage, - .set_tone = ttusbdecfe_dvbs_set_tone, -}; - -MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver"); -MODULE_AUTHOR("Alex Woods/Andrew de Quincey"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(ttusbdecfe_dvbt_attach); -EXPORT_SYMBOL(ttusbdecfe_dvbs_attach); diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h b/drivers/media/dvb/ttusb-dec/ttusbdecfe.h deleted file mode 100644 index 15ccc3d1a20..00000000000 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * TTUSB DEC Driver - * - * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef TTUSBDECFE_H -#define TTUSBDECFE_H - -#include <linux/dvb/frontend.h> - -struct ttusbdecfe_config -{ - int (*send_command)(struct dvb_frontend* fe, const u8 command, - int param_length, const u8 params[], - int *result_length, u8 cmd_result[]); -}; - -extern struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config); - -extern struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config); - -#endif // TTUSBDECFE_H |
