summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r--drivers/media/dvb/b2c2/Kconfig2
-rw-r--r--drivers/media/dvb/b2c2/Makefile1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h64
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c27
-rw-r--r--drivers/media/dvb/b2c2/flexcop-eeprom.c47
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c171
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c61
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c68
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c165
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h21
-rw-r--r--drivers/media/dvb/b2c2/flexcop-sram.c112
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c368
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.h62
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c86
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h20
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_be.h7
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_le.h7
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c14
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c2
-rw-r--r--drivers/media/dvb/dm1105/Kconfig1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c204
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig67
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile2
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c60
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h31
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c328
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.h69
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c164
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h11
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c12
-rw-r--r--drivers/media/dvb/frontends/Kconfig71
-rw-r--r--drivers/media/dvb/frontends/Makefile6
-rw-r--r--drivers/media/dvb/frontends/au8522.h16
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c835
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c (renamed from drivers/media/dvb/frontends/au8522.c)96
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h412
-rw-r--r--drivers/media/dvb/frontends/cx24113.c2
-rw-r--r--drivers/media/dvb/frontends/cx24116.c63
-rw-r--r--drivers/media/dvb/frontends/cx24123.c4
-rw-r--r--drivers/media/dvb/frontends/dib0070.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.h36
-rw-r--r--drivers/media/dvb/frontends/dib7000m.h28
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h35
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h19
-rw-r--r--drivers/media/dvb/frontends/itd1000_priv.h2
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c1
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c1087
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.h85
-rw-r--r--drivers/media/dvb/frontends/lnbh24.h55
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c41
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h34
-rw-r--r--drivers/media/dvb/frontends/s921_module.c1
-rw-r--r--drivers/media/dvb/frontends/stb6100_cfg.h4
-rw-r--r--drivers/media/dvb/frontends/stv0900.h62
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c1949
-rw-r--r--drivers/media/dvb/frontends/stv0900_init.h441
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h430
-rw-r--r--drivers/media/dvb/frontends/stv0900_reg.h3787
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c2847
-rw-r--r--drivers/media/dvb/frontends/stv6110.c456
-rw-r--r--drivers/media/dvb/frontends/stv6110.h62
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c30
-rw-r--r--drivers/media/dvb/frontends/zl10036.c519
-rw-r--r--drivers/media/dvb/frontends/zl10036.h53
-rw-r--r--drivers/media/dvb/frontends/zl10353.c8
-rw-r--r--drivers/media/dvb/frontends/zl10353.h4
-rw-r--r--drivers/media/dvb/frontends/zl10353_priv.h8
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c7
-rw-r--r--drivers/media/dvb/siano/Makefile4
-rw-r--r--drivers/media/dvb/siano/sms-cards.c92
-rw-r--r--drivers/media/dvb/siano/sms-cards.h5
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c45
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h41
-rw-r--r--drivers/media/dvb/siano/smsdvb.c60
-rw-r--r--drivers/media/dvb/siano/smsusb.c73
-rw-r--r--drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c480
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c88
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c6
93 files changed, 15395 insertions, 1397 deletions
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index a8c6249c409..9e578140074 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -13,7 +13,7 @@ config DVB_B2C2_FLEXCOP
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 MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index d9db066f985..b97cf7208a1 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -2,7 +2,6 @@ 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
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 8ce06336e76..3e1c472092a 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -28,11 +28,14 @@
/* Steal from usb.h */
#undef err
-#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
+#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)
+#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)
+#define warn(format, arg...) \
+ printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
struct flexcop_dma {
struct pci_dev *pdev;
@@ -91,16 +94,14 @@ struct flexcop_device {
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_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 (*stream_control) (struct flexcop_device *, int);
int (*get_mac_addr) (struct flexcop_device *fc, int extended);
-
void *bus_specific;
};
@@ -111,22 +112,28 @@ 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*);
+void flexcop_device_kfree(struct flexcop_device *);
-int flexcop_device_initialize(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);
+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);
+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 */
@@ -141,13 +148,15 @@ 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);
+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);
+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);
+int flexcop_frontend_init(struct flexcop_device *fc);
void flexcop_frontend_exit(struct flexcop_device *fc);
/* from flexcop-i2c.c */
@@ -159,11 +168,14 @@ 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);
+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);
+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);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index 26f0011a507..2881e0d956a 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -1,13 +1,12 @@
/*
- * 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.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-dma.c - 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)
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size)
{
u8 *tcpu;
dma_addr_t tdma = 0;
@@ -32,7 +31,8 @@ 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);
+ 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);
@@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
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;
+ 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) {
@@ -57,7 +57,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
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.");
+ err("either DMA1 or DMA2 can be configured within one "
+ "flexcop_dma_config call.");
return -EINVAL;
}
@@ -81,7 +82,8 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc,
r0x0 = dma2_010;
r0xc = dma2_01c;
} else {
- err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+ err("either transfer DMA1 or DMA2 can be started within one "
+ "flexcop_dma_xfer_control call.");
return -EINVAL;
}
@@ -154,8 +156,7 @@ 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_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);
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c
index 8a8ae8a3e6b..a25373a9bd8 100644
--- a/drivers/media/dvb/b2c2/flexcop-eeprom.c
+++ b/drivers/media/dvb/b2c2/flexcop-eeprom.c
@@ -1,9 +1,7 @@
/*
- * 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.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -14,17 +12,17 @@ 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)
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
+ u32 len, u8 *wbuf, u8 *rbuf, int retries)
{
- int i;
+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;
+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;
}
@@ -39,12 +37,10 @@ static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
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);
}
@@ -59,7 +55,6 @@ static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(key, buf, len);
-
return 1;
}
@@ -74,9 +69,7 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
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];
@@ -90,11 +83,11 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
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)
+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);
}
@@ -110,7 +103,8 @@ static u8 calc_lrc(u8 *buf, int len)
return sum;
}
-static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+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);
@@ -123,7 +117,8 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t
return ret;
}
-static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
+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)
@@ -133,8 +128,7 @@ static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf,
}
/* 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
- */
+ * 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];
@@ -142,12 +136,9 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
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");
+ 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);
}
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 5cded370854..f7afab5944c 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY;
+ fc->dev_type = FC_SKY_REV26;
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->dev_type = FC_AIR_DVBT;
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
goto fe_found;
}
@@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY_OLD;
+ fc->dev_type = FC_SKY_REV23;
goto fe_found;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 451974ba32f..77e45475f4c 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -1,33 +1,30 @@
/*
- * 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.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-hw-filter.c - pid and mac address filtering and 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");
+ 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);
+ 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);
+ 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);
+ 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];
@@ -36,27 +33,28 @@ void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
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);
+ 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);
+ 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)
+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);
+ 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);
+ flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
}
/* this fancy define reduces the code size of the quite similar PID controlling of
@@ -65,91 +63,112 @@ static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
#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);
+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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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);
+ 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)
+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");
+ 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;
+ 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)
+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);
+ 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 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;
@@ -164,24 +183,25 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
* - or the requested pid is 0x2000 */
if (!fc->pid_filtering && fc->feedcount == onoff)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
if (fc->pid_filtering) {
- flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+ flexcop_pid_control \
+ (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
if (fc->extra_feedcount > 0)
- flexcop_toggle_fullts_streaming(fc,1);
+ flexcop_toggle_fullts_streaming(fc, 1);
else if (dvbdmxfeed->pid == 0x2000)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
else
- flexcop_toggle_fullts_streaming(fc,0);
+ 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);
+ flexcop_rcv_data_ctrl(fc, onoff);
if (fc->stream_control) /* device specific stream control */
- fc->stream_control(fc,onoff);
+ fc->stream_control(fc, onoff);
/* feeding stopped -> reset the flexcop filter*/
if (onoff == 0) {
@@ -189,7 +209,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
flexcop_hw_filter_init(fc);
}
}
-
return 0;
}
EXPORT_SYMBOL(flexcop_pid_feed_control);
@@ -199,15 +218,15 @@ 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_control(fc, i, 0x1fff, 0);
flexcop_pid_group_filter(fc, 0, 0x1fe0);
- flexcop_pid_group_filter_ctrl(fc,0);
+ flexcop_pid_group_filter_ctrl(fc, 0);
- v = fc->read_ibi_reg(fc,pid_filter_308);
+ 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);
+ 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
index f13783f08f0..e2bed507648 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -1,17 +1,14 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for 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.
+ * 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)
+static int flexcop_i2c_operation(struct flexcop_device *fc,
+ flexcop_ibi_value *r100)
{
int i;
flexcop_ibi_value r;
@@ -26,7 +23,7 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
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 */
+ if (r.tw_sm_c_100.st_done) {
*r100 = r;
deb_i2c("i2c success\n");
return 0;
@@ -36,17 +33,31 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
return -EREMOTEIO;
}
}
- deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i);
+ 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 r100, u8 *buf)
{
flexcop_ibi_value r104;
- int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
+ int len = r100.tw_sm_c_100.total_bytes,
+ /* remember total_bytes is buflen-1 */
ret;
+ /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
+ * correctly:
+ *
+ * the ITD1000 is behind an i2c-gate which closes automatically
+ * after an i2c-transaction the STV0297 needs 2 consecutive reads
+ * one with no_base_addr = 0 and one with 1
+ *
+ * those two work-arounds are conflictin: we check for the card
+ * type, it is set when probing the ITD1000 */
+ if (i2c->fc->dev_type == FC_SKY_REV27)
+ 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("Retrying operation\n");
@@ -69,11 +80,11 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
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)
+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 */
@@ -81,7 +92,6 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
/* 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;
@@ -94,7 +104,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
}
int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
int ret;
@@ -117,7 +127,6 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
printk("rd(");
else
printk("wr(");
-
printk("%02x): %02x ", chipaddr, addr);
#endif
@@ -163,7 +172,8 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *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)
+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;
@@ -182,12 +192,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
/* 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);
+ 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);
+ msgs[i].buf[0], &msgs[i].buf[1],
+ msgs[i].len - 1);
if (ret < 0) {
err("i2c master_xfer failed");
break;
@@ -214,23 +225,21 @@ static struct i2c_algorithm flexcop_algo = {
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));
+ 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));
+ 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));
+ 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]);
@@ -268,7 +277,6 @@ 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;
}
@@ -279,6 +287,5 @@ void flexcop_i2c_exit(struct flexcop_device *fc)
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
index 93d20e56f90..e56627d2f0f 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -1,9 +1,7 @@
/*
- * 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.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-misc.c - miscellaneous functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -12,39 +10,43 @@ 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;
+ 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("unknown FlexCop Revision: %x. Please report this to "
+ "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");
+ 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");
+ deb_info("this FlexCop has "
+ "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",
+ "Unknown chip",
"FlexCopII",
"FlexCopIIb",
"FlexCopIII",
};
static const char *flexcop_device_names[] = {
- "Unkown device",
+ "Unknown device",
"Air2PC/AirStar 2 DVB-T",
"Air2PC/AirStar 2 ATSC 1st generation",
"Air2PC/AirStar 2 ATSC 2nd generation",
@@ -61,21 +63,23 @@ static const char *flexcop_bus_names[] = {
"PCI",
};
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
- char *suffix)
+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);
+ 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)
+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);
+ v = fc->read_ibi_reg(fc, reg+4*i);
+ deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
}
deb_rdump("\n");
}
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 76e37fd96bb..227c0200b70 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -1,9 +1,7 @@
/*
- * 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.
+ * 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"
@@ -11,7 +9,8 @@
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");
+MODULE_PARM_DESC(enable_pid_filtering,
+ "enable hardware pid filtering: supported values: 0 (fullts), 1");
static int irq_chk_intv = 100;
module_param(irq_chk_intv, int, 0644);
@@ -26,17 +25,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
#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)
+#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,16=check (|-able))."
- DEBSTATUS);
+ DEBSTATUS);
#define DRIVER_VERSION "0.1"
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
@@ -51,30 +50,30 @@ struct flexcop_pci {
void __iomem *io_mem;
u32 irq;
-/* buffersize (at least for DMA1, need to be % 188 == 0,
- * this logic is required */
+ /* 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 */
+ u32 last_dma1_cur_pos;
+ /* position of the pointer last time the timer/packet irq occured */
int count;
int count_prev;
int stream_problem;
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 int lastwreg, lastwval, lastrreg, lastrval;
-static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
+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;
@@ -82,19 +81,20 @@ static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, fl
if (lastrreg != r || lastrval != v.raw) {
lastrreg = r; lastrval = v.raw;
- deb_reg("new rd: %3x: %08x\n",r,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)
+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);
+ deb_reg("new wr: %3x: %08x\n", r, v.raw);
}
writel(v.raw, fc_pci->io_mem + r);
@@ -113,15 +113,16 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
deb_chk("no IRQ since the last check\n");
if (fc_pci->stream_problem++ == 3) {
struct dvb_demux_feed *feed;
+ deb_info("flexcop-pci: stream problem, resetting pid filter\n");
spin_lock_irq(&fc->demux.lock);
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 0);
}
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 1);
}
spin_unlock_irq(&fc->demux.lock);
@@ -149,11 +150,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
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);
+ spin_lock_irqsave(&fc_pci->irq_lock, flags);
+ v = fc->read_ibi_reg(fc, irq_20c);
- /* errors */
+ /* errors */
if (v.irq_20c.Data_receiver_error)
deb_chk("data receiver error\n");
if (v.irq_20c.Continuity_error_flag)
@@ -164,24 +164,29 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
deb_chk("Transport error\n");
if ((fc_pci->count % 1000) == 0)
- deb_chk("%d valid irq took place so far\n",fc_pci->count);
+ 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);
+ 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);
+ 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 */
+ } else if (v.irq_20c.DMA1_Timer_Status == 1) {
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 ",
+ 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);
@@ -191,30 +196,36 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
* 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);
+ 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->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);
+ 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);
+ 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);
+ deb_irq("isr for flexcop called, "
+ "apparently without reason (%08x)\n", v.raw);
ret = IRQ_NONE;
}
- spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
-
+ spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
return ret;
}
@@ -222,52 +233,48 @@ 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);
+ 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);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
deb_irq("IRQ enabled\n");
-
fc_pci->count_prev = fc_pci->count;
-
-// fc_pci->active_dma1_addr = 0;
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
-
} else {
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+ 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);
+ 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)
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
+ FC_DEFAULT_DMA1_BUFSIZE);
+ if (ret != 0)
return ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
+ FC_DEFAULT_DMA2_BUFSIZE);
+ if (ret != 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);
-
+ 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;
}
@@ -290,12 +297,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
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;
@@ -338,8 +341,8 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
fc_pci->init_state &= ~FC_PCI_INIT;
}
-
-static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int flexcop_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct flexcop_device *fc;
struct flexcop_pci *fc_pci;
@@ -350,7 +353,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_pci = fc->bus_specific;
fc_pci->fc_dev = fc;
@@ -358,7 +361,6 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
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)
@@ -368,29 +370,29 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->pid_filtering = enable_pid_filtering;
fc->bus_type = FC_PCI;
-
fc->dev = &pdev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_pci->pdev = pdev;
if ((ret = flexcop_pci_init(fc_pci)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_pci_exit;
-/* init dma */
+ /* 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);
- if (irq_chk_intv > 0)
- schedule_delayed_work(&fc_pci->irq_check_work,
- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
-
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ?
+ 100 :
+ irq_chk_intv));
return ret;
err_fc_exit:
@@ -420,7 +422,6 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
static struct pci_device_id flexcop_pci_tbl[] = {
{ PCI_DEVICE(0x13d0, 0x2103) },
-/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
{ },
};
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 7599fccc1a5..dc4528dcbb9 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -1,14 +1,11 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for 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.
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_REG_H__
#define __FLEXCOP_REG_H__
-
typedef enum {
FLEXCOP_UNK = 0,
FLEXCOP_II,
@@ -18,13 +15,13 @@ typedef enum {
typedef enum {
FC_UNK = 0,
- FC_AIR_DVB,
+ FC_CABLE,
+ FC_AIR_DVBT,
FC_AIR_ATSC1,
FC_AIR_ATSC2,
- FC_SKY,
- FC_SKY_OLD,
- FC_CABLE,
FC_AIR_ATSC3,
+ FC_SKY_REV23,
+ FC_SKY_REV26,
FC_SKY_REV27,
FC_SKY_REV28,
} flexcop_device_type_t;
@@ -36,12 +33,12 @@ typedef enum {
/* FlexCop IBI Registers */
#if defined(__LITTLE_ENDIAN)
- #include "flexcop_ibi_value_le.h"
+#include "flexcop_ibi_value_le.h"
#else
#if defined(__BIG_ENDIAN)
- #include "flexcop_ibi_value_be.h"
+#include "flexcop_ibi_value_be.h"
#else
- #error no endian defined
+#error no endian defined
#endif
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c
index cda69528548..f2199e43e80 100644
--- a/drivers/media/dvb/b2c2/flexcop-sram.c
+++ b/drivers/media/dvb/b2c2/flexcop-sram.c
@@ -1,45 +1,43 @@
/*
- * 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.
+ * Linux driver for 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)
+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);
+ 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;
+ 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)
+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);
+ 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);
+ deb_sram("sram dest: %x target: %x\n", dest, target);
if (dest & FC_SRAM_DEST_NET)
v.sram_dest_reg_714.NET_Dest = target;
@@ -154,14 +152,12 @@ static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len
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) {
@@ -174,26 +170,22 @@ static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
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.
+ /* 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;
@@ -203,19 +195,17 @@ static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
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.
+ /* 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;
@@ -224,39 +214,29 @@ static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_set_size(struct adapter *adapter, u32 mask)
{
- write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+ 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);
@@ -269,7 +249,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -287,7 +266,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -297,26 +275,24 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
if (tmp2 != 0x5a)
return 0;
-
return 1;
}
static u32 sram_length(struct adapter *adapter)
{
if (adapter->dw_sram_type == 0x10000)
- return 32768; // 32K
+ return 32768; /* 32K */
if (adapter->dw_sram_type == 0x00000)
- return 65536; // 64K
+ return 65536; /* 64K */
if (adapter->dw_sram_type == 0x20000)
- return 131072; // 128K
-
- return 32768; // 32K
+ 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.
+ - 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.
@@ -324,24 +300,18 @@ static u32 sram_length(struct adapter *adapter)
bank 0 covers addresses 0x00000-0x07fff
bank 1 covers addresses 0x08000-0x0ffff
bank 2 covers addresses 0x10000-0x17fff
- bank 3 covers addresses 0x18000-0x1ffff
-*/
+ bank 3 covers addresses 0x18000-0x1ffff */
static int flexcop_sram_detect(struct flexcop_device *fc)
{
- flexcop_ibi_value r208,r71c_0,vr71c_1;
-
+ 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 ???
@@ -350,9 +320,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
@@ -360,9 +328,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x20000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 128K\n", __func__);
-
return 128;
}
@@ -370,9 +336,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x00000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 64K\n", __func__);
-
return 64;
}
@@ -380,18 +344,14 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
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;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index ae0d76a5d51..bedcfb67162 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -1,11 +1,8 @@
/*
- * 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.
+ * Linux driver for 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"
@@ -18,42 +15,47 @@
/* 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) {\
+ do { if ((debug & level)) printk(args); } while (0)
+
+#define debug_dump(b, l, method) do {\
int i; \
- for (i = 0; i < l; i++) method("%02x ", b[i]); \
- method("\n");\
-}
+ for (i = 0; i < l; i++) \
+ method("%02x ", b[i]); \
+ method("\n"); \
+} while (0)
#define DEBSTATUS ""
#else
-#define dprintk(level,args...)
-#define debug_dump(b,l,method)
+#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);
+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)
+#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)
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (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))
+#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
@@ -69,12 +71,13 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
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);
+ 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*/
+ request_type, /* 0xc0 read or 0x40 write */
wAddress,
0,
val,
@@ -82,55 +85,49 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
B2C2_WAIT_FOR_OPERATION_RDW * HZ);
if (len != sizeof(u32)) {
- err("error while %s dword from %d (%d).",read ? "reading" : "writing",
- wAddress,wRegOffsPCI);
+ 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 *pbBuffer, u32 buflen)
{
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
u16 wIndex;
- int nWaitTime,pipe,len;
-
+ 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;
+ case B2C2_USB_READ_V8_MEM:
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+ request_type |= USB_DIR_IN;
+ 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;
+ case B2C2_USB_WRITE_V8_MEM:
+ wIndex |= pbBuffer[0];
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+ 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;
+ case B2C2_USB_FLASH_BLOCK:
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- default:
- deb_info("unsupported request for v8_mem_req %x.\n",req);
+ 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);
+ deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
+ wAddress, wIndex, buflen);
- len = usb_control_msg(fc_usb->udev,pipe,
+ len = usb_control_msg(fc_usb->udev, pipe,
req,
request_type,
wAddress,
@@ -139,39 +136,53 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
buflen,
nWaitTime * HZ);
- debug_dump(pbBuffer,len,deb_v8);
-
+ 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)))
+ ((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)
+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;
+ 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)
+ 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));
+
+ ret = flexcop_usb_v8_memory_req(fc_usb, req,
+ page_start + (addr / V8_MEMORY_PAGE_SIZE),
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended),
+ &buf[i], pagechunk);
+
+ if (ret < 0)
return ret;
-
addr += pagechunk;
len -= pagechunk;
}
@@ -180,8 +191,9 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request
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);
+ 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
@@ -191,11 +203,8 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
{
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;
-
+ 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,
@@ -218,36 +227,35 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
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:
+ 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;
+ case USB_FUNC_I2C_CHECKWRITE:
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
+ nWaitTime = 2;
+ 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;
+ case USB_FUNC_I2C_READ:
+ case USB_FUNC_I2C_REPEATREAD:
+ pipe = B2C2_USB_CTRL_PIPE_IN;
+ nWaitTime = 2;
+ request_type |= USB_DIR_IN;
break;
- default:
- deb_info("unsupported function for i2c_req %x\n",func);
- return -EINVAL;
+ 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);
+ 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,
@@ -257,44 +265,49 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
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)
+/* 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);
+ 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)
+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);
+ 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)
+ 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);
+ 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);
+ USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
}
-static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
+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);
+ 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);
+ 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;
@@ -304,23 +317,26 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in
}
while (l >= 190) {
- if (*b == 0xff)
+ 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;
+ 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;
+ default:
+ deb_ts("wrong packet type\n");
+ l = 0;
break;
}
- else {
+ } else {
deb_ts("wrong header\n");
l = 0;
}
@@ -337,23 +353,26 @@ static void flexcop_usb_urb_complete(struct urb *urb)
int i;
if (urb->actual_length > 0)
- deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length);
+ 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);
+ 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);
+ 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->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);
}
@@ -374,35 +393,47 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
}
if (fc_usb->iso_buffer != NULL)
- pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);
+ 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;
+ 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);
+ 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);
+ 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))) {
+ for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+ fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
+ GFP_ATOMIC);
+ if (fc_usb->iso_urb[i] == NULL) {
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);
+ deb_ts("initializing and submitting urb no. %d "
+ "(buf_offset: %d).\n", i, buffer_offset);
urb->dev = fc_usb->udev;
urb->context = fc_usb;
@@ -416,26 +447,26 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
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);
+ 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);
+ 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);
-
+ /* 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:
@@ -448,20 +479,20 @@ 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;
+ case USB_SPEED_LOW:
+ err("cannot handle USB speed because it is too 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 unknown.");
+ return -ENODEV;
}
usb_set_intfdata(fc_usb->uintf, fc_usb);
return 0;
@@ -485,7 +516,7 @@ static int flexcop_usb_probe(struct usb_interface *intf,
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_usb = fc->bus_specific;
fc_usb->fc_dev = fc;
@@ -502,21 +533,21 @@ static int flexcop_usb_probe(struct usb_interface *intf,
fc->dev = &udev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_usb->udev = udev;
fc_usb->uintf = intf;
if ((ret = flexcop_usb_init(fc_usb)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_usb_exit;
-/* xfer init */
+ /* xfer init */
if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
goto err_fc_exit;
- info("%s successfully initialized and connected.",DRIVER_NAME);
+ info("%s successfully initialized and connected.", DRIVER_NAME);
return 0;
err_fc_exit:
@@ -535,12 +566,12 @@ static void flexcop_usb_disconnect(struct usb_interface *intf)
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);
+ info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
}
static struct usb_device_id flexcop_usb_table [] = {
- { USB_DEVICE(0x0af7, 0x0101) },
- { }
+ { USB_DEVICE(0x0af7, 0x0101) },
+ { }
};
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
@@ -557,10 +588,9 @@ static int __init flexcop_usb_module_init(void)
{
int result;
if ((result = usb_register(&flexcop_usb_driver))) {
- err("usb_register failed. (%d)",result);
+ err("usb_register failed. (%d)", result);
return result;
}
-
return 0;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h
index 630e647a2ca..92529a9c447 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.h
+++ b/drivers/media/dvb/b2c2/flexcop-usb.h
@@ -1,15 +1,20 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.h - header file for the USB part
+ * see flexcop.c for copyright information
+ */
#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_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)
+#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;
@@ -18,8 +23,8 @@ struct flexcop_usb {
u8 *iso_buffer;
int buffer_size;
dma_addr_t dma_addr;
- struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
+ struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
struct flexcop_device *fc_dev;
u8 tmp_buffer[1023+190];
@@ -30,14 +35,6 @@ struct flexcop_usb {
/* 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
@@ -47,7 +44,6 @@ typedef enum {
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,
@@ -62,15 +58,13 @@ typedef enum {
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 */
+ /* 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
- */
+/* function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function */
typedef enum {
UTILITY_SET_FILTER = 0x01,
UTILITY_DATA_ENABLE = 0x02,
@@ -84,7 +78,7 @@ typedef enum {
UTILITY_DATA_RESET = 0x0A,
UTILITY_GET_DATA_STATUS = 0x10,
UTILITY_GET_V8_REG = 0x11,
-/* DKT 020326 - add function for v1.14 */
+ /* DKT 020326 - add function for v1.14 */
UTILITY_SRAM_WRITE = 0x12,
UTILITY_SRAM_READ = 0x13,
UTILITY_SRAM_TESTFILL = 0x14,
@@ -92,13 +86,13 @@ typedef enum {
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_RW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
-#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 */
+#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
typedef enum {
V8_MEMORY_PAGE_DVB_CI = 0x20,
@@ -107,13 +101,11 @@ typedef enum {
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
+#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
index 91068952b50..2df1b0214dc 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -1,22 +1,20 @@
/*
- * 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
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.c - main module part
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * based on 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)
+ * 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)
- *
+ * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
+ * 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
@@ -46,7 +44,10 @@
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);
+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);
@@ -57,37 +58,36 @@ 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);
+ 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);
+ 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);
+ "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.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);
+ err("dvb_dmx failed: error %d", ret);
goto err_dmx;
}
@@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
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);
+ 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);
+ 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);
+ 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);
+ err("connect frontend failed: error %d", ret);
goto err_connect_frontend;
}
@@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
return 0;
err_connect_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_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);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
err_dmx_add_hw_frontend:
dvb_dmxdev_release(&fc->dmxdev);
err_dmx_dev:
@@ -141,12 +141,13 @@ static void flexcop_dvb_exit(struct flexcop_device *fc)
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);
+ 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;
@@ -168,9 +169,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets);
static void flexcop_reset(struct flexcop_device *fc)
{
- flexcop_ibi_value v210,v204;
+ flexcop_ibi_value v210, v204;
-/* reset the flexcop itself */
+ /* reset the flexcop itself */
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
@@ -183,13 +184,11 @@ static void flexcop_reset(struct flexcop_device *fc)
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 */
+ /* reset the periphical devices */
v204 = fc->read_ibi_reg(fc,misc_204);
v204.misc_204.Per_reset_sig = 0;
@@ -201,25 +200,24 @@ static void flexcop_reset(struct flexcop_device *fc)
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);
+ 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);
- udelay(1000);
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);
+ struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
+ GFP_KERNEL);
if (!fc) {
err("no memory");
return NULL;
@@ -254,7 +252,6 @@ int flexcop_device_initialize(struct flexcop_device *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)))
@@ -279,7 +276,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
goto error;
flexcop_device_name(fc,"initialization of","complete");
-
return 0;
error:
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
index 0cebe1d92e0..897b10c85ad 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -1,9 +1,7 @@
/*
- * 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.
+ * Linux driver for 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___
@@ -21,11 +19,11 @@ extern int b2c2_flexcop_debug;
#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)
+#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
index ed9a6756b19..8f64bdbd72b 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * 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__
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
index 49f2315b6e5..c75830d7d94 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * 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__
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 27edb0ece58..8668e634c7e 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -8,7 +8,7 @@ config DVB_BT8XX
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
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 0258451423a..4601b059b2b 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -552,16 +552,19 @@ free_mem_and_exit:
return result;
}
-static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
+static long dst_ca_ioctl(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 dvb_device *dvbdev;
+ struct dst_state *state;
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;
+ lock_kernel();
+ dvbdev = (struct dvb_device *)file->private_data;
+ state = (struct dst_state *)dvbdev->priv;
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);
@@ -647,6 +650,7 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
kfree (p_ca_slot_info);
kfree (p_ca_caps);
+ unlock_kernel();
return result;
}
@@ -682,9 +686,9 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t
return 0;
}
-static struct file_operations dst_ca_fops = {
+static const struct file_operations dst_ca_fops = {
.owner = THIS_MODULE,
- .ioctl = dst_ca_ioctl,
+ .unlocked_ioctl = dst_ca_ioctl,
.open = dst_ca_open,
.release = dst_ca_release,
.read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 48762a2b9e4..b1857c19bbd 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -814,7 +814,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
mutex_init(&card->lock);
card->bttv_nr = sub->core->nr;
- strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
+ strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
card->i2c_adapter = &sub->core->i2c_adap;
switch(sub->core->type) {
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
index 43f4d44edca..de3eeb0a8d6 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -8,6 +8,7 @@ config DVB_DM1105
select DVB_STB6000 if !DVB_FE_CUSTOMISE
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
+ select VIDEO_IR
help
Support for cards based on the SDMC DM1105 PCI chip like
DvbWorld 2002
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index f48f73aff19..5b20cf5a29f 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -156,46 +156,12 @@ 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;
+ struct ir_input_state ir;
char input_phys[32];
- struct tasklet_struct ir_tasklet;
+ struct work_struct work;
u32 ir_command;
};
@@ -220,10 +186,14 @@ struct dm1105dvb {
/* i2c */
struct i2c_adapter i2c_adap;
+ /* irq */
+ struct work_struct work;
+
/* dma */
dma_addr_t dma_addr;
unsigned char *ts_buf;
u32 wrp;
+ u32 nextwrp;
u32 buffer_size;
unsigned int PacketErrorCount;
unsigned int dmarst;
@@ -233,8 +203,6 @@ struct dm1105dvb {
#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)
{
@@ -407,38 +375,61 @@ static int dm1105dvb_stop_feed(struct dvb_demux_feed *f)
return 0;
}
-/* ir tasklet */
-static void dm1105_emit_key(unsigned long parm)
+/* ir work handler */
+static void dm1105_emit_key(struct work_struct *work)
{
- struct infrared *ir = (struct infrared *) parm;
+ struct infrared *ir = container_of(work, struct infrared, work);
u32 ircom = ir->ir_command;
u8 data;
- u16 keycode;
+
+ if (ir_debug)
+ printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);
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];
+ ir_input_keydown(ir->input_dev, &ir->ir, data, data);
+ ir_input_nokey(ir->input_dev, &ir->ir);
+}
- if (!keycode)
- return;
+/* work handler */
+static void dm1105_dmx_buffer(struct work_struct *work)
+{
+ struct dm1105dvb *dm1105dvb =
+ container_of(work, struct dm1105dvb, work);
+ unsigned int nbpackets;
+ u32 oldwrp = dm1105dvb->wrp;
+ u32 nextwrp = dm1105dvb->nextwrp;
+
+ 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;
+ 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);
+ if (nextwrp < oldwrp) {
+ memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size,
+ dm1105dvb->ts_buf, nextwrp);
+ nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188;
+ } else
+ nbpackets = (nextwrp - oldwrp) / 188;
+ dm1105dvb->wrp = nextwrp;
+ dvb_dmx_swfilter_packets(&dm1105dvb->demux,
+ &dm1105dvb->ts_buf[oldwrp], nbpackets);
}
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));
@@ -447,71 +438,25 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
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);
+ dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) -
+ inl(dm_io_mem(DM1105_STADR));
+ schedule_work(&dm1105dvb->work);
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);
+ dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE));
+ schedule_work(&dm1105dvb->ir.work);
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);
+ return IRQ_HANDLED;
}
int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
{
struct input_dev *input_dev;
- int err;
-
- dm1105dvb_local = dm1105;
+ IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec;
+ int ir_type = IR_TYPE_OTHER;
+ int err = -ENOMEM;
input_dev = input_allocate_device();
if (!input_dev)
@@ -521,12 +466,11 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- input_dev->evbit[0] = BIT(EV_KEY);
+ ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
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;
+ input_dev->id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
input_dev->id.product = dm1105->pdev->subsystem_device;
@@ -534,25 +478,22 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
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);
+
+ INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
+
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);
}
@@ -710,7 +651,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
if (!dm1105dvb)
- goto out;
+ return -ENOMEM;
dm1105dvb->pdev = pdev;
dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
@@ -740,13 +681,9 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
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;
+ goto err_pci_iounmap;
/* i2c */
i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);
@@ -813,8 +750,15 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);
dm1105_ir_init(dm1105dvb);
-out:
- return ret;
+
+ INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer);
+
+ ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED,
+ DRIVER_NAME, dm1105dvb);
+ if (ret < 0)
+ goto err_free_irq;
+
+ return 0;
err_disconnect_frontend:
dmx->disconnect_frontend(dmx);
@@ -843,7 +787,7 @@ err_pci_disable_device:
err_kfree:
pci_set_drvdata(pdev, NULL);
kfree(dm1105dvb);
- goto out;
+ return ret;
}
static void __devexit dm1105_remove(struct pci_dev *pdev)
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 069d847ba88..c35fbb8d8f4 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -1024,7 +1024,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_demux_fops = {
+static const struct file_operations dvb_demux_fops = {
.owner = THIS_MODULE,
.read = dvb_demux_read,
.ioctl = dvb_demux_ioctl,
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 7e3aeaa7370..cb22da53bfb 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1607,7 +1607,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
EXPORT_SYMBOL(dvb_ca_en50221_init);
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_en50221_io_read,
.write = dvb_ca_en50221_io_write,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 8dcb3fbf7ac..ebc78157b9b 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1875,7 +1875,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_frontend_fops = {
+static const struct file_operations dvb_frontend_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.poll = dvb_frontend_poll,
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index f6ba8468858..8280f8d66a3 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1459,7 +1459,7 @@ static int dvb_net_close(struct inode *inode, struct file *file)
}
-static struct file_operations dvb_net_fops = {
+static const struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 6a32680dbb1..a454ee8f1e4 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -228,8 +228,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->fops = dvbdevfops;
init_waitqueue_head (&dvbdev->wait_queue);
- memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
- dvbdev->fops->owner = adap->module;
+ memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
+ dvbdevfops->owner = adap->module;
list_add_tail (&dvbdev->list_head, &adap->device_list);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index dca49cf962e..79927305e84 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -71,7 +71,7 @@ struct dvb_adapter {
struct dvb_device {
struct list_head list_head;
- struct file_operations *fops;
+ const struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
int minor;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 49f7b20c25d..6103caad164 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -25,7 +25,7 @@ config DVB_USB_A800
depends on DVB_USB
select DVB_DIB3000MC
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
@@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_DIB3000MB
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
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.
@@ -55,7 +55,7 @@ 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
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
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.
@@ -69,15 +69,17 @@ config DVB_USB_DIBUSB_MC
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_DIB7000P if !DVB_FE_CUSTOMISE
+ select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+ select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
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
+ select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+ select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
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
@@ -95,7 +97,8 @@ config DVB_USB_UMT_010
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
@@ -108,10 +111,11 @@ config DVB_USB_CXUSB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+ select DVB_LGS8GL5 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
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -125,8 +129,8 @@ config DVB_USB_M920X
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
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
Currently, only devices with a product id of
@@ -137,7 +141,7 @@ 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
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
receiver with USB ID 0db0:5581.
@@ -146,7 +150,7 @@ 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
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
@@ -199,7 +203,7 @@ config DVB_USB_NOVA_T_USB2
depends on DVB_USB
select DVB_DIB3000MC
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
@@ -235,8 +239,8 @@ config DVB_USB_OPERA1
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
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
and the TerraTec Cinergy T USB XE (Rev.1)
@@ -284,7 +288,7 @@ 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
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
@@ -293,9 +297,18 @@ config DVB_USB_AF9015
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
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_CE6230
+ tristate "Intel CE6230 DVB-T USB2.0 support"
+ depends on DVB_USB && EXPERIMENTAL
+ select DVB_ZL10353
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ help
+ Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 3122b7cc2c2..f92734ed777 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -76,6 +76,8 @@ 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
+dvb-usb-ce6230-objs = ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 6a97a40d3df..f0ba8b07b84 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -27,9 +27,7 @@
#include "qt1010.h"
#include "tda18271.h"
#include "mxl5005s.h"
-#if 0
-#include "mc44s80x.h"
-#endif
+#include "mc44s803.h"
static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -37,9 +35,6 @@ 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);
@@ -283,6 +278,21 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
req.data = &msg[i+1].buf[0];
ret = af9015_ctrl_msg(d, &req);
i += 2;
+ } else if (msg[i].flags & I2C_M_RD) {
+ ret = -EINVAL;
+ if (msg[i].addr ==
+ af9015_af9013_config[0].demod_address)
+ goto error;
+ 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].len;
+ req.data = &msg[i].buf[0];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 1;
} else {
if (msg[i].addr ==
af9015_af9013_config[0].demod_address)
@@ -748,6 +758,16 @@ static int af9015_read_config(struct usb_device *udev)
af9015_config.ir_table_size =
ARRAY_SIZE(af9015_ir_table_digittrade);
break;
+ case AF9015_REMOTE_AVERMEDIA_KS:
+ 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_ks;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_avermedia_ks);
+ break;
}
} else {
switch (le16_to_cpu(udev->descriptor.idVendor)) {
@@ -836,9 +856,6 @@ static int af9015_read_config(struct usb_device *udev)
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 adapter0 buffer size according to USB port speed, adapter1 buffer
size can be static because it is enabled only USB2.0 */
@@ -935,7 +952,6 @@ static int af9015_read_config(struct usb_device *udev)
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:
@@ -948,6 +964,10 @@ static int af9015_read_config(struct usb_device *udev)
case AF9013_TUNER_MXL5005R:
af9015_af9013_config[i].rf_spec_inv = 0;
break;
+ case AF9013_TUNER_MC44S803:
+ af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+ af9015_af9013_config[i].rf_spec_inv = 1;
+ break;
default:
warn("tuner id:%d not supported, please report!", val);
return -ENODEV;
@@ -1135,6 +1155,11 @@ static struct mxl5005s_config af9015_mxl5005_config = {
.AgcMasterByte = 0x00,
};
+static struct mc44s803_config af9015_mc44s803_config = {
+ .i2c_address = 0xc0,
+ .dig_out = 1,
+};
+
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
struct af9015_state *state = adap->dev->priv;
@@ -1179,15 +1204,8 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *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
+ ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
+ &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_UNKNOWN:
default:
@@ -1218,6 +1236,7 @@ static struct usb_device_id af9015_usb_table[] = {
{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)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1417,7 +1436,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
{
.name = "KWorld USB DVB-T TV Stick II " \
"(VS-DVB-T 395U)",
- .cold_ids = {&af9015_usb_table[16], NULL},
+ .cold_ids = {&af9015_usb_table[16],
+ &af9015_usb_table[17], NULL},
.warm_ids = {NULL},
},
}
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 21c7782f488..00e25714662 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -124,6 +124,7 @@ enum af9015_remote {
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
AF9015_REMOTE_MYGICTV_U718,
AF9015_REMOTE_DIGITTRADE_DVB_T,
+ AF9015_REMOTE_AVERMEDIA_KS,
};
/* Leadtek WinFast DTV Dongle Gold */
@@ -597,6 +598,36 @@ static u8 af9015_ir_table_avermedia[] = {
0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
};
+static u8 af9015_ir_table_avermedia_ks[] = {
+ 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
+ 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
+ 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
+ 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
+ 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
+ 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
+ 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
+ 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
+ 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
+ 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
+ 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
+ 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
+ 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
+ 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
+ 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
+ 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
+ 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
+ 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
+ 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
+ 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
+ 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
+ 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
+ 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
+ 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
+ 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
+ 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
+ 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
+};
+
/* Digittrade DVB-T USB Stick */
static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
{ 0x01, 0x0f, KEY_LAST }, /* RETURN */
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
new file mode 100644
index 00000000000..5862820f109
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -0,0 +1,328 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2009 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 "ce6230.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
+
+/* debug */
+static int dvb_usb_ce6230_debug;
+module_param_named(debug, dvb_usb_ce6230_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
+{
+ int ret;
+ unsigned int pipe;
+ u8 request;
+ u8 requesttype;
+ u16 value;
+ u16 index;
+ u8 buf[req->data_len];
+
+ request = req->cmd;
+ value = req->value;
+ index = req->index;
+
+ switch (req->cmd) {
+ case I2C_READ:
+ case DEMOD_READ:
+ case REG_READ:
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+ break;
+ case I2C_WRITE:
+ case DEMOD_WRITE:
+ case REG_WRITE:
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+ break;
+ default:
+ err("unknown command:%02x", req->cmd);
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+ /* write */
+ memcpy(buf, req->data, req->data_len);
+ pipe = usb_sndctrlpipe(udev, 0);
+ } else {
+ /* read */
+ pipe = usb_rcvctrlpipe(udev, 0);
+ }
+
+ msleep(1); /* avoid I2C errors */
+
+ ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
+ buf, sizeof(buf), CE6230_USB_TIMEOUT);
+
+ ce6230_debug_dump(request, requesttype, value, index, buf,
+ req->data_len, deb_xfer);
+
+ if (ret < 0)
+ deb_info("%s: usb_control_msg failed:%d\n", __func__, ret);
+ else
+ ret = 0;
+
+ /* read request, copy returned data to return buf */
+ if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+ memcpy(req->data, buf, req->data_len);
+
+error:
+ return ret;
+}
+
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+ return ce6230_rw_udev(d->udev, req);
+}
+
+/* I2C */
+static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i = 0;
+ struct req_t req;
+ int ret = 0;
+ memset(&req, 0, sizeof(&req));
+
+ if (num > 2)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ while (i < num) {
+ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+ if (msg[i].addr ==
+ ce6230_zl10353_config.demod_address) {
+ req.cmd = DEMOD_READ;
+ req.value = msg[i].addr >> 1;
+ req.index = msg[i].buf[0];
+ req.data_len = msg[i+1].len;
+ req.data = &msg[i+1].buf[0];
+ ret = ce6230_ctrl_msg(d, &req);
+ } else {
+ err("i2c read not implemented");
+ ret = -EPERM;
+ }
+ i += 2;
+ } else {
+ if (msg[i].addr ==
+ ce6230_zl10353_config.demod_address) {
+ req.cmd = DEMOD_WRITE;
+ req.value = msg[i].addr >> 1;
+ req.index = msg[i].buf[0];
+ req.data_len = msg[i].len-1;
+ req.data = &msg[i].buf[1];
+ ret = ce6230_ctrl_msg(d, &req);
+ } else {
+ req.cmd = I2C_WRITE;
+ req.value = 0x2000 + (msg[i].addr >> 1);
+ req.index = 0x0000;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = ce6230_ctrl_msg(d, &req);
+ }
+ i += 1;
+ }
+ if (ret)
+ break;
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+ return ret ? ret : i;
+}
+
+static u32 ce6230_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ce6230_i2c_algo = {
+ .master_xfer = ce6230_i2c_xfer,
+ .functionality = ce6230_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config ce6230_zl10353_config = {
+ .demod_address = 0x1e,
+ .adc_clock = 450000,
+ .if2 = 45700,
+ .no_tuner = 1,
+ .parallel_ts = 1,
+ .clock_ctl_1 = 0x34,
+ .pll_0 = 0x0e,
+};
+
+static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ deb_info("%s:\n", __func__);
+ adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe == NULL)
+ return -ENODEV;
+ return 0;
+}
+
+static struct mxl5005s_config ce6230_mxl5003s_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 int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ deb_info("%s:\n", __func__);
+ ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
+ &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
+ return ret;
+}
+
+static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ int ret;
+ deb_info("%s: onoff:%d\n", __func__, onoff);
+
+ /* InterfaceNumber 1 / AlternateSetting 0 idle
+ InterfaceNumber 1 / AlternateSetting 1 streaming */
+ ret = usb_set_interface(d->udev, 1, onoff);
+ if (ret)
+ err("usb_set_interface failed with error:%d", ret);
+
+ return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ce6230_properties;
+
+static int ce6230_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret = 0;
+ struct dvb_usb_device *d = NULL;
+
+ deb_info("%s: interface:%d\n", __func__,
+ intf->cur_altsetting->desc.bInterfaceNumber);
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+ ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE,
+ &d, adapter_nr);
+ if (ret)
+ err("init failed with error:%d\n", ret);
+ }
+
+ return ret;
+}
+
+static struct usb_device_id ce6230_table[] = {
+ { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ce6230_table);
+
+static struct dvb_usb_device_properties ce6230_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .no_reconnect = 1,
+
+ .size_of_priv = 0,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = ce6230_zl10353_frontend_attach,
+ .tuner_attach = ce6230_mxl5003s_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 6,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+ }
+ },
+
+ .power_ctrl = ce6230_power_ctrl,
+
+ .i2c_algo = &ce6230_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ {
+ .name = "Intel CE9500 reference design",
+ .cold_ids = {NULL},
+ .warm_ids = {&ce6230_table[0], NULL},
+ },
+ }
+};
+
+static struct usb_driver ce6230_driver = {
+ .name = "dvb_usb_ce6230",
+ .probe = ce6230_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = ce6230_table,
+};
+
+/* module stuff */
+static int __init ce6230_module_init(void)
+{
+ int ret;
+ deb_info("%s:\n", __func__);
+ ret = usb_register(&ce6230_driver);
+ if (ret)
+ err("usb_register failed with error:%d", ret);
+
+ return ret;
+}
+
+static void __exit ce6230_module_exit(void)
+{
+ deb_info("%s:\n", __func__);
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&ce6230_driver);
+}
+
+module_init(ce6230_module_init);
+module_exit(ce6230_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ce6230.h b/drivers/media/dvb/dvb-usb/ce6230.h
new file mode 100644
index 00000000000..97c42482ccb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.h
@@ -0,0 +1,69 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2009 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_CE6230_H_
+#define _DVB_USB_CE6230_H_
+
+#define DVB_USB_LOG_PREFIX "ce6230"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args)
+#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args)
+#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args)
+#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args)
+#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args)
+#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args)
+
+#define ce6230_debug_dump(r, t, v, i, b, l, func) { \
+ int loop_; \
+ func("%02x %02x %02x %02x %02x %02x %02x %02x", \
+ t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
+ if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+ func(" >>> "); \
+ else \
+ func(" <<< "); \
+ for (loop_ = 0; loop_ < l; loop_++) \
+ func("%02x ", b[loop_]); \
+ func("\n");\
+}
+
+#define CE6230_USB_TIMEOUT 1000
+
+struct req_t {
+ u8 cmd; /* [1] */
+ u16 value; /* [2|3] */
+ u16 index; /* [4|5] */
+ u16 data_len; /* [6|7] */
+ u8 *data;
+};
+
+enum ce6230_cmd {
+ CONFIG_READ = 0xd0, /* rd 0 (unclear) */
+ UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */
+ I2C_READ = 0xd9, /* rd 9 (unclear) */
+ I2C_WRITE = 0xca, /* wr a */
+ DEMOD_READ = 0xdb, /* rd b */
+ DEMOD_WRITE = 0xcc, /* wr c */
+ REG_READ = 0xde, /* rd e */
+ REG_WRITE = 0xcf, /* wr f */
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 200b215f4d8..db7f7f79a66 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -158,6 +158,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
err("i2c read error (status = %d)\n", result);
break;
}
+
+ deb_data("<<< ");
+ debug_dump(msg[i].buf, msg[i].len, deb_data);
+
} else {
/* Write request */
buf[0] = REQUEST_NEW_I2C_WRITE;
@@ -169,6 +173,9 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
/* The Actual i2c payload */
memcpy(&buf[4], msg[i].buf, msg[i].len);
+ deb_data(">>> ");
+ debug_dump(buf, msg[i].len + 4, deb_data);
+
result = usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev, 0),
REQUEST_NEW_I2C_WRITE,
@@ -211,7 +218,8 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
/* 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);
+ deb_info("I2C read failed on address 0x%02x\n",
+ msg[i].addr);
break;
}
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 635d30a5507..8ddbadf6219 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -17,6 +17,8 @@
#include "xc5000.h"
#include "s5h1411.h"
#include "dib0070.h"
+#include "lgdt3305.h"
+#include "mxl5007t.h"
static int force_lna_activation;
module_param(force_lna_activation, int, 0644);
@@ -262,7 +264,12 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
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);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -284,7 +291,12 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
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);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -421,8 +433,12 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &stk7700ph_dib7700_xc3028_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &stk7700ph_dib7700_xc3028_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&stk7700ph_dib7700_xc3028_config);
@@ -1187,8 +1203,12 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &dib7070p_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &dib7070p_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&dib7070p_dib7000p_config);
@@ -1244,7 +1264,12 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7070pd_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
return adap->fe == NULL ? -ENODEV : 0;
@@ -1347,6 +1372,72 @@ static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
== NULL ? -ENODEV : 0;
}
+static struct lgdt3305_config hcw_lgdt3305_config = {
+ .i2c_addr = 0x0e,
+ .mpeg_mode = LGDT3305_MPEG_PARALLEL,
+ .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_LOW,
+ .deny_i2c_rptr = 0,
+ .spectral_inversion = 1,
+ .qam_if_khz = 6000,
+ .vsb_if_khz = 6000,
+ .usref_8vsb = 0x0500,
+};
+
+static struct mxl5007t_config hcw_mxl5007t_config = {
+ .xtal_freq_hz = MxL_XTAL_25_MHZ,
+ .if_freq_hz = MxL_IF_6_MHZ,
+ .invert_if = 1,
+};
+
+/* TIGER-ATSC map:
+ GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
+ GPIO1 - ANT_SEL (H: VPA, L: MCX)
+ GPIO4 - SCL2
+ GPIO6 - EN_TUNER
+ GPIO7 - SDA2
+ GPIO10 - DEM_RST
+
+ MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
+ */
+static int lgdt3305_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;
+
+ st->disable_streaming_master_mode = 1;
+
+ /* fe power enable */
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(30);
+
+ /* demod reset */
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+
+ adap->fe = dvb_attach(lgdt3305_attach,
+ &hcw_lgdt3305_config,
+ &adap->dev->i2c_adap);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ return dvb_attach(mxl5007t_attach, adap->fe,
+ &adap->dev->i2c_adap, 0x60,
+ &hcw_mxl5007t_config) == 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) },
@@ -1396,6 +1487,12 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
{ USB_DEVICE(USB_VID_TERRATEC,
USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
+ { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
+/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
+ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
+ { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1595,7 +1692,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 9,
+ .num_device_descs = 11,
.devices = {
{ "DiBcom STK7070P reference design",
{ &dib0700_usb_id_table[15], NULL },
@@ -1633,6 +1730,14 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[33], NULL },
{ NULL },
},
+ { "Elgato EyeTV DTT",
+ { &dib0700_usb_id_table[49], NULL },
+ { NULL },
+ },
+ { "Yuan PD378S",
+ { &dib0700_usb_id_table[45], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
@@ -1661,7 +1766,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
- .num_device_descs = 5,
+ .num_device_descs = 6,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@@ -1682,8 +1787,16 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Terratec Cinergy DT USB XS Diversity",
{ &dib0700_usb_id_table[43], NULL },
{ NULL },
+ },
+ { "Sony PlayTV",
+ { &dib0700_usb_id_table[44], 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,
@@ -1699,7 +1812,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 5,
+ .num_device_descs = 7,
.devices = {
{ "Terratec Cinergy HT USB XE",
{ &dib0700_usb_id_table[27], NULL },
@@ -1725,6 +1838,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[39], NULL },
{ NULL },
},
+ { "YUAN High-Tech MC770",
+ { &dib0700_usb_id_table[48], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dib0700_rc_keys,
@@ -1759,6 +1876,31 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.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 = lgdt3305_frontend_attach,
+ .tuner_attach = mxl5007t_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv = sizeof(struct
+ dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "Hauppauge ATSC MiniCard (B200)",
+ { &dib0700_usb_id_table[46], NULL },
+ { NULL },
+ },
+ { "Hauppauge ATSC MiniCard (B210)",
+ { &dib0700_usb_id_table[47], NULL },
+ { NULL },
+ },
+ },
},
};
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0db0c06ee6f..dc7ea21cd13 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -27,12 +27,14 @@
#define USB_VID_DIBCOM 0x10b8
#define USB_VID_DPOSH 0x1498
#define USB_VID_DVICO 0x0fe9
+#define USB_VID_ELGATO 0x0fd9
#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_INTEL 0x8086
#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KWORLD_2 0x1b80
#define USB_VID_KYE 0x0458
@@ -48,6 +50,7 @@
#define USB_VID_TERRATEC 0x0ccd
#define USB_VID_TELESTAR 0x10b9
#define USB_VID_VISIONPLUS 0x13d3
+#define USB_VID_SONY 0x1415
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_UNIWILL 0x1584
@@ -95,8 +98,10 @@
#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_INTEL_CE9500 0x9500
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_395U 0xe396
+#define USB_PID_KWORLD_395U_2 0xe39b
#define USB_PID_KWORLD_PC160_2T 0xc160
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
@@ -149,6 +154,8 @@
#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_HAUPPAUGE_TIGER_ATSC 0xb200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210 0xb210
#define USB_PID_AVERMEDIA_EXPRESS 0xb568
#define USB_PID_AVERMEDIA_VOLAR 0xa807
#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
@@ -232,9 +239,13 @@
#define USB_PID_ASUS_U3100 0x173f
#define USB_PID_YUAN_EC372S 0x1edc
#define USB_PID_YUAN_STK7700PH 0x1f08
+#define USB_PID_YUAN_PD378S 0x2edc
+#define USB_PID_YUAN_MC770 0x0871
#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
+#define USB_PID_SONY_PLAYTV 0x0003
+#define USB_PID_ELGATO_EYETV_DTT 0x0021
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index b1de0f7e26e..2d5352e54dc 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties {
int generic_bulk_ctrl_endpoint;
int num_device_descs;
- struct dvb_usb_device_description devices[9];
+ struct dvb_usb_device_description devices[11];
};
/**
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index b55d9ccaf33..12f7730184a 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -115,7 +115,7 @@ static const char *debug_fcp_ctype(unsigned int ctype)
}
static const char *debug_fcp_opcode(unsigned int opcode,
- const u8 *data, size_t length)
+ const u8 *data, int length)
{
switch (opcode) {
case AVC_OPCODE_VENDOR: break;
@@ -135,13 +135,14 @@ static const char *debug_fcp_opcode(unsigned int opcode,
case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL: return "RegisterRC";
case SFE_VENDOR_OPCODE_LNB_CONTROL: return "LNBControl";
case SFE_VENDOR_OPCODE_TUNE_QPSK: return "TuneQPSK";
+ case SFE_VENDOR_OPCODE_TUNE_QPSK2: return "TuneQPSK2";
case SFE_VENDOR_OPCODE_HOST2CA: return "Host2CA";
case SFE_VENDOR_OPCODE_CA2HOST: return "CA2Host";
}
return "Vendor";
}
-static void debug_fcp(const u8 *data, size_t length)
+static void debug_fcp(const u8 *data, int length)
{
unsigned int subunit_type, subunit_id, op;
const char *prefix = data[0] > 7 ? "FCP <- " : "FCP -> ";
@@ -150,7 +151,7 @@ static void debug_fcp(const u8 *data, size_t length)
subunit_type = data[1] >> 3;
subunit_id = data[1] & 7;
op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
- printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
+ printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n",
prefix, subunit_type, subunit_id, length,
debug_fcp_ctype(data[0]),
debug_fcp_opcode(op, data, length));
@@ -266,7 +267,10 @@ static void avc_tuner_tuneqpsk(struct firedtv *fdtv,
c->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
c->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
c->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
- c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
+ if (fdtv->type == FIREDTV_DVB_S2)
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2;
+ else
+ c->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
c->operand[4] = (params->frequency >> 24) & 0xff;
c->operand[5] = (params->frequency >> 16) & 0xff;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 00269560793..a486a7f81fa 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -1,17 +1,21 @@
-menu "Customise DVB Frontends"
- depends on DVB_CORE
-
config DVB_FE_CUSTOMISE
bool "Customise the frontend modules to build"
+ depends on DVB_CORE
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.
+ This allows the user to select/deselect frontend drivers 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.
+if DVB_FE_CUSTOMISE
+
+menu "Customise DVB Frontends"
+
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -55,6 +59,13 @@ config DVB_MT312
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_ZL10036
+ tristate "Zarlink ZL10036 silicon tuner"
+ 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
@@ -83,6 +94,20 @@ config DVB_STV0299
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_STV6110
+ tristate "ST STV6110 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_STV0900
+ tristate "ST STV0900 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
+
config DVB_TDA8083
tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C
@@ -288,6 +313,13 @@ config DVB_TDA10048
help
A DVB-T tuner module. Say Y when you want to support this frontend.
+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.
+
comment "DVB-C (cable) frontends"
depends on DVB_CORE
@@ -387,6 +419,14 @@ config DVB_LGDT3304
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+config DVB_LGDT3305
+ tristate "LG Electronics LGDT3305 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_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
@@ -397,7 +437,7 @@ config DVB_S5H1409
config DVB_AU8522
tristate "Auvitek AU8522 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && VIDEO_V4L2
default m if DVB_FE_CUSTOMISE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -439,18 +479,18 @@ config DVB_TUNER_DIB0070
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
+ This device is only used inside a SiP called together with a
demodulator for now.
comment "SEC control devices for DVB-S"
depends on DVB_CORE
config DVB_LNBP21
- tristate "LNBP21 SEC controller"
+ tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- An SEC control chip.
+ An SEC control chips.
config DVB_ISL6405
tristate "ISL6405 SEC controller"
@@ -478,11 +518,6 @@ 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
+
+endif
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index af7bdf0ad4c..65a336aa1db 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -7,6 +7,8 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
s921-objs := s921_module.o s921_core.o
stb0899-objs = stb0899_drv.o stb0899_algo.o
+stv0900-objs = stv0900_core.o stv0900_sw.o
+au8522-objs = au8522_dig.o au8522_decoder.o
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -28,6 +30,7 @@ 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_ZL10036) += zl10036.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
@@ -41,6 +44,7 @@ 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_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
@@ -64,4 +68,6 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o
obj-$(CONFIG_DVB_S921) += s921.o
+obj-$(CONFIG_DVB_STV6110) += stv6110.o
+obj-$(CONFIG_DVB_STV0900) += stv0900.o
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index 7b94f554a09..565dcf31af5 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
}
#endif /* CONFIG_DVB_AU8522 */
+/* Other modes may need to be added later */
+enum au8522_video_input {
+ AU8522_COMPOSITE_CH1 = 1,
+ AU8522_COMPOSITE_CH2,
+ AU8522_COMPOSITE_CH3,
+ AU8522_COMPOSITE_CH4,
+ AU8522_COMPOSITE_CH4_SIF,
+ AU8522_SVIDEO_CH13,
+ AU8522_SVIDEO_CH24,
+};
+
+enum au8522_audio_input {
+ AU8522_AUDIO_NONE,
+ AU8522_AUDIO_SIF,
+};
+
#endif /* __AU8522_H__ */
/*
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
new file mode 100644
index 00000000000..d63e1527dc8
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -0,0 +1,835 @@
+/*
+ * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, Ltd.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* Developer notes:
+ *
+ * VBI support is not yet working
+ * Saturation and hue setting are not yet working
+ * Enough is implemented here for CVBS and S-Video inputs, but the actual
+ * analog demodulator code isn't implemented (not needed for xc5000 since it
+ * has its own demodulator and outputs CVBS)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/v4l2-device.h>
+#include "au8522.h"
+#include "au8522_priv.h"
+
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+
+static int au8522_analog_debug;
+
+
+module_param_named(analog_debug, au8522_analog_debug, int, 0644);
+
+MODULE_PARM_DESC(analog_debug,
+ "Analog debugging messages [0=Off (default) 1=On]");
+
+struct au8522_register_config {
+ u16 reg_name;
+ u8 reg_val[8];
+};
+
+
+/* Video Decoder Filter Coefficients
+ The values are as follows from left to right
+ 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
+*/
+struct au8522_register_config filter_coef[] = {
+ {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
+ {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
+ {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
+ {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
+ {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
+ {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
+ {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
+ {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
+ {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
+ {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
+ {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
+ {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
+ {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
+ {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
+ {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
+ {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
+ {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
+ {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
+ {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
+ {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
+ {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
+
+};
+#define NUM_FILTER_COEF (sizeof(filter_coef)\
+ / sizeof(struct au8522_register_config))
+
+
+/* Registers 0x060b through 0x0652 are the LP Filter coefficients
+ The values are as follows from left to right
+ 0="SIF" 1="ATVRF/ATVRF13"
+ Note: the "ATVRF/ATVRF13" mode has never been tested
+*/
+struct au8522_register_config lpfilter_coef[] = {
+ {0x060b, {0x21, 0x0b} },
+ {0x060c, {0xad, 0xad} },
+ {0x060d, {0x70, 0xf0} },
+ {0x060e, {0xea, 0xe9} },
+ {0x060f, {0xdd, 0xdd} },
+ {0x0610, {0x08, 0x64} },
+ {0x0611, {0x60, 0x60} },
+ {0x0612, {0xf8, 0xb2} },
+ {0x0613, {0x01, 0x02} },
+ {0x0614, {0xe4, 0xb4} },
+ {0x0615, {0x19, 0x02} },
+ {0x0616, {0xae, 0x2e} },
+ {0x0617, {0xee, 0xc5} },
+ {0x0618, {0x56, 0x56} },
+ {0x0619, {0x30, 0x58} },
+ {0x061a, {0xf9, 0xf8} },
+ {0x061b, {0x24, 0x64} },
+ {0x061c, {0x07, 0x07} },
+ {0x061d, {0x30, 0x30} },
+ {0x061e, {0xa9, 0xed} },
+ {0x061f, {0x09, 0x0b} },
+ {0x0620, {0x42, 0xc2} },
+ {0x0621, {0x1d, 0x2a} },
+ {0x0622, {0xd6, 0x56} },
+ {0x0623, {0x95, 0x8b} },
+ {0x0624, {0x2b, 0x2b} },
+ {0x0625, {0x30, 0x24} },
+ {0x0626, {0x3e, 0x3e} },
+ {0x0627, {0x62, 0xe2} },
+ {0x0628, {0xe9, 0xf5} },
+ {0x0629, {0x99, 0x19} },
+ {0x062a, {0xd4, 0x11} },
+ {0x062b, {0x03, 0x04} },
+ {0x062c, {0xb5, 0x85} },
+ {0x062d, {0x1e, 0x20} },
+ {0x062e, {0x2a, 0xea} },
+ {0x062f, {0xd7, 0xd2} },
+ {0x0630, {0x15, 0x15} },
+ {0x0631, {0xa3, 0xa9} },
+ {0x0632, {0x1f, 0x1f} },
+ {0x0633, {0xf9, 0xd1} },
+ {0x0634, {0xc0, 0xc3} },
+ {0x0635, {0x4d, 0x8d} },
+ {0x0636, {0x21, 0x31} },
+ {0x0637, {0x83, 0x83} },
+ {0x0638, {0x08, 0x8c} },
+ {0x0639, {0x19, 0x19} },
+ {0x063a, {0x45, 0xa5} },
+ {0x063b, {0xef, 0xec} },
+ {0x063c, {0x8a, 0x8a} },
+ {0x063d, {0xf4, 0xf6} },
+ {0x063e, {0x8f, 0x8f} },
+ {0x063f, {0x44, 0x0c} },
+ {0x0640, {0xef, 0xf0} },
+ {0x0641, {0x66, 0x66} },
+ {0x0642, {0xcc, 0xd2} },
+ {0x0643, {0x41, 0x41} },
+ {0x0644, {0x63, 0x93} },
+ {0x0645, {0x8e, 0x8e} },
+ {0x0646, {0xa2, 0x42} },
+ {0x0647, {0x7b, 0x7b} },
+ {0x0648, {0x04, 0x04} },
+ {0x0649, {0x00, 0x00} },
+ {0x064a, {0x40, 0x40} },
+ {0x064b, {0x8c, 0x98} },
+ {0x064c, {0x00, 0x00} },
+ {0x064d, {0x63, 0xc3} },
+ {0x064e, {0x04, 0x04} },
+ {0x064f, {0x20, 0x20} },
+ {0x0650, {0x00, 0x00} },
+ {0x0651, {0x40, 0x40} },
+ {0x0652, {0x01, 0x01} },
+};
+#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
+ / sizeof(struct au8522_register_config))
+
+static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct au8522_state, sd);
+}
+
+static void setup_vbi(struct au8522_state *state, int aud_input)
+{
+ int i;
+
+ /* These are set to zero regardless of what mode we're in */
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
+ 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
+ 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
+ 0x00);
+
+ /* Setup the VBI registers */
+ for (i = 0x30; i < 0x60; i++)
+ au8522_writereg(state, i, 0x40);
+
+ /* For some reason, every register is 0x40 except register 0x44
+ (confirmed via the HVR-950q USB capture) */
+ au8522_writereg(state, 0x44, 0x60);
+
+ /* Enable VBI (we always do this regardless of whether the user is
+ viewing closed caption info) */
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
+ AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
+
+}
+
+static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
+{
+ int i;
+ int filter_coef_type;
+
+ /* Provide reasonable defaults for picture tuning values */
+ au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
+ au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
+ state->brightness = 0xed - 128;
+ au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
+ state->contrast = 0x79;
+ au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
+ au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+ au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+
+ /* Other decoder registers */
+ au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
+
+ if (input_mode == 0x23) {
+ /* S-Video input mapping */
+ au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
+ } else {
+ /* All other modes (CVBS/ATVRF etc.) */
+ au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
+ }
+
+ au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
+ AU8522_TVDEC_PGA_REG012H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
+ AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
+ au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
+ AU8522_TVDED_DBG_MODE_REG060H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+ AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
+ au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
+ AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
+ AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
+ AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
+ AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
+ AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
+ AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
+ AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
+ AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
+ AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
+ AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
+ AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
+ AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
+ au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
+ au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
+ AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
+ au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
+ au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
+ AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
+ AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
+ AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
+ AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
+ AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
+ AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
+ au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
+ AU8522_TOREGAAGC_REG0E5H_CVBS);
+ au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
+
+ setup_vbi(state, 0);
+
+ if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+ input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ /* Despite what the table says, for the HVR-950q we still need
+ to be in CVBS mode for the S-Video input (reason uknown). */
+ /* filter_coef_type = 3; */
+ filter_coef_type = 5;
+ } else {
+ filter_coef_type = 5;
+ }
+
+ /* Load the Video Decoder Filter Coefficients */
+ for (i = 0; i < NUM_FILTER_COEF; i++) {
+ au8522_writereg(state, filter_coef[i].reg_name,
+ filter_coef[i].reg_val[filter_coef_type]);
+ }
+
+ /* It's not clear what these registers are for, but they are always
+ set to the same value regardless of what mode we're in */
+ au8522_writereg(state, AU8522_REG42EH, 0x87);
+ au8522_writereg(state, AU8522_REG42FH, 0xa2);
+ au8522_writereg(state, AU8522_REG430H, 0xbf);
+ au8522_writereg(state, AU8522_REG431H, 0xcb);
+ au8522_writereg(state, AU8522_REG432H, 0xa1);
+ au8522_writereg(state, AU8522_REG433H, 0x41);
+ au8522_writereg(state, AU8522_REG434H, 0x88);
+ au8522_writereg(state, AU8522_REG435H, 0xc2);
+ au8522_writereg(state, AU8522_REG436H, 0x3c);
+}
+
+static void au8522_setup_cvbs_mode(struct au8522_state *state)
+{
+ /* here we're going to try the pre-programmed route */
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+ setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
+{
+ /* here we're going to try the pre-programmed route */
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+ /* It's not clear why they turn off the PGA before enabling the clamp
+ control, but the Windows trace does it so we will too... */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+ /* Enable clamping control */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+
+ /* Turn on the PGA */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+ setup_decoder_defaults(state,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_svideo_mode(struct au8522_state *state)
+{
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
+
+ /* Set input to Y on Channe1, C on Channel 3 */
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+ /* Disable clamping control (required for S-video) */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
+
+ setup_decoder_defaults(state,
+ AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void disable_audio_input(struct au8522_state *state)
+{
+ /* This can probably be optimized */
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+
+ au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+ au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
+
+ au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
+ msleep(5);
+ au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
+ au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+ au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* 0=disable, 1=SIF */
+static void set_audio_input(struct au8522_state *state, int aud_input)
+{
+ int i;
+
+ /* Note that this function needs to be used in conjunction with setting
+ the input routing via register 0x81 */
+
+ if (aud_input == AU8522_AUDIO_NONE) {
+ disable_audio_input(state);
+ return;
+ }
+
+ if (aud_input != AU8522_AUDIO_SIF) {
+ /* The caller asked for a mode we don't currently support */
+ printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
+ aud_input);
+ return;
+ }
+
+ /* Load the Audio Decoder Filter Coefficients */
+ for (i = 0; i < NUM_LPFILTER_COEF; i++) {
+ au8522_writereg(state, lpfilter_coef[i].reg_name,
+ lpfilter_coef[i].reg_val[0]);
+ }
+
+ /* Setup audio */
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+ msleep(150);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
+ msleep(1);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
+ msleep(50);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
+ msleep(80);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+ au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
+ msleep(70);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
+ au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+ au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct au8522_state *state = to_state(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ state->brightness = ctrl->value;
+ au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
+ ctrl->value - 128);
+ break;
+ case V4L2_CID_CONTRAST:
+ state->contrast = ctrl->value;
+ au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
+ ctrl->value);
+ break;
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ /* Not yet implemented */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct au8522_state *state = to_state(sd);
+
+ /* Note that we are using values cached in the state structure instead
+ of reading the registers due to issues with i2c reads not working
+ properly/consistently yet on the HVR-950q */
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = state->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = state->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ /* Not yet supported */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Not yet implemented */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int au8522_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct au8522_state *state = to_state(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->val = au8522_readreg(state, reg->reg & 0xffff);
+ return 0;
+}
+
+static int au8522_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct au8522_state *state = to_state(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ au8522_writereg(state, reg->reg, reg->val & 0xff);
+ return 0;
+}
+#endif
+
+static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct au8522_state *state = to_state(sd);
+
+ if (enable) {
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ 0x01);
+ msleep(1);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+ } else {
+ /* This does not completely power down the device
+ (it only reduces it from around 140ma to 80ma) */
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ 1 << 5);
+ }
+ return 0;
+}
+
+static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1,
+ AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ /* Not yet implemented */
+ default:
+ break;
+ }
+
+ qc->type = 0;
+ return -EINVAL;
+}
+
+static int au8522_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct au8522_state *state = to_state(sd);
+
+ au8522_writereg(state, 0xa4, 1 << 5);
+
+ return 0;
+}
+
+static int au8522_s_video_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct au8522_state *state = to_state(sd);
+
+ au8522_reset(sd, 0);
+
+ /* Jam open the i2c gate to the tuner. We do this here to handle the
+ case where the user went into digital mode (causing the gate to be
+ closed), and then came back to analog mode */
+ au8522_writereg(state, 0x106, 1);
+
+ if (route->input == AU8522_COMPOSITE_CH1) {
+ au8522_setup_cvbs_mode(state);
+ } else if (route->input == AU8522_SVIDEO_CH13) {
+ au8522_setup_svideo_mode(state);
+ } else if (route->input == AU8522_COMPOSITE_CH4_SIF) {
+ au8522_setup_cvbs_tuner_mode(state);
+ } else {
+ printk(KERN_ERR "au8522 mode not currently supported\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int au8522_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct au8522_state *state = to_state(sd);
+ set_audio_input(state, route->input);
+ return 0;
+}
+
+static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+ int val = 0;
+ struct au8522_state *state = to_state(sd);
+ u8 lock_status;
+
+ /* Interrogate the decoder to see if we are getting a real signal */
+ lock_status = au8522_readreg(state, 0x00);
+ if (lock_status == 0xa2)
+ vt->signal = 0x01;
+ else
+ vt->signal = 0x00;
+
+ vt->capability |=
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+ val = V4L2_TUNER_SUB_MONO;
+ vt->rxsubchans = val;
+ vt->audmode = V4L2_TUNER_MODE_STEREO;
+ return 0;
+}
+
+static int au8522_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct au8522_state *state = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
+}
+
+static int au8522_log_status(struct v4l2_subdev *sd)
+{
+ /* FIXME: Add some status info here */
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops au8522_core_ops = {
+ .log_status = au8522_log_status,
+ .g_chip_ident = au8522_g_chip_ident,
+ .g_ctrl = au8522_g_ctrl,
+ .s_ctrl = au8522_s_ctrl,
+ .queryctrl = au8522_queryctrl,
+ .reset = au8522_reset,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = au8522_g_register,
+ .s_register = au8522_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
+ .g_tuner = au8522_g_tuner,
+};
+
+static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
+ .s_routing = au8522_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops au8522_video_ops = {
+ .s_routing = au8522_s_video_routing,
+ .g_fmt = au8522_g_fmt,
+ .s_fmt = au8522_s_fmt,
+ .s_stream = au8522_s_stream,
+};
+
+static const struct v4l2_subdev_ops au8522_ops = {
+ .core = &au8522_core_ops,
+ .tuner = &au8522_tuner_ops,
+ .audio = &au8522_audio_ops,
+ .video = &au8522_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct au8522_state *state;
+ struct v4l2_subdev *sd;
+ int instance;
+ struct au8522_config *demod_config;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ return -EIO;
+ }
+
+ /* allocate memory for the internal state */
+ instance = au8522_get_state(&state, client->adapter, client->addr);
+ switch (instance) {
+ case 0:
+ printk(KERN_ERR "au8522_decoder allocation failed\n");
+ return -EIO;
+ case 1:
+ /* new demod instance */
+ printk(KERN_INFO "au8522_decoder creating new instance...\n");
+ break;
+ default:
+ /* existing demod instance */
+ printk(KERN_INFO "au8522_decoder attach existing instance.\n");
+ break;
+ }
+
+ demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
+ demod_config->demod_address = 0x8e >> 1;
+
+ state->config = demod_config;
+ state->i2c = client->adapter;
+
+ sd = &state->sd;
+ v4l2_i2c_subdev_init(sd, client, &au8522_ops);
+
+ state->c = client;
+ state->vid_input = AU8522_COMPOSITE_CH1;
+ state->aud_input = AU8522_AUDIO_NONE;
+ state->id = 8522;
+ state->rev = 0;
+
+ /* Jam open the i2c gate to the tuner */
+ au8522_writereg(state, 0x106, 1);
+
+ return 0;
+}
+
+static int au8522_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ v4l2_device_unregister_subdev(sd);
+ au8522_release_state(to_state(sd));
+ return 0;
+}
+
+static const struct i2c_device_id au8522_id[] = {
+ {"au8522", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, au8522_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "au8522",
+ .probe = au8522_probe,
+ .remove = au8522_remove,
+ .id_table = au8522_id,
+};
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522_dig.c
index eabf9a68e7e..35731258bb0 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -27,35 +27,25 @@
#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;
-};
+#include "au8522_priv.h"
static int debug;
-#define dprintk(arg...) do { \
- if (debug) \
- printk(arg); \
+/* Despite the name "hybrid_tuner", the framework works just as well for
+ hybrid demodulators as well... */
+static LIST_HEAD(hybrid_tuner_instance_list);
+static DEFINE_MUTEX(au8522_list_mutex);
+
+#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 au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
{
int ret;
- u8 buf [] = { reg >> 8, reg & 0xff, data };
+ u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
struct i2c_msg msg = { .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 3 };
@@ -69,13 +59,13 @@ static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
return (ret != 1) ? -1 : 0;
}
-static u8 au8522_readreg(struct au8522_state *state, u16 reg)
+u8 au8522_readreg(struct au8522_state *state, u16 reg)
{
int ret;
- u8 b0 [] = { reg >> 8, reg & 0xff };
- u8 b1 [] = { 0 };
+ u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
+ u8 b1[] = { 0 };
- struct i2c_msg msg [] = {
+ struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, .flags = 0,
.buf = b0, .len = 2 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD,
@@ -528,7 +518,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
/* Reset the demod hardware and reset all of the configuration registers
to a default state. */
-static int au8522_init(struct dvb_frontend *fe)
+int au8522_init(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -624,7 +614,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led)
return 0;
}
-static int au8522_sleep(struct dvb_frontend *fe)
+int au8522_sleep(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -632,6 +622,9 @@ static int au8522_sleep(struct dvb_frontend *fe)
/* turn off led */
au8522_led_ctrl(state, 0);
+ /* Power down the chip */
+ au8522_writereg(state, 0xa4, 1 << 5);
+
state->current_frequency = 0;
return 0;
@@ -798,23 +791,58 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
return 0;
}
+static struct dvb_frontend_ops au8522_ops;
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address)
+{
+ int ret;
+
+ mutex_lock(&au8522_list_mutex);
+ ret = hybrid_tuner_request_state(struct au8522_state, (*state),
+ hybrid_tuner_instance_list,
+ i2c, client_address, "au8522");
+ mutex_unlock(&au8522_list_mutex);
+
+ return ret;
+}
+
+void au8522_release_state(struct au8522_state *state)
+{
+ mutex_lock(&au8522_list_mutex);
+ if (state != NULL)
+ hybrid_tuner_release_state(state);
+ mutex_unlock(&au8522_list_mutex);
+}
+
+
static void au8522_release(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
- kfree(state);
+ au8522_release_state(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;
+ int instance;
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ instance = au8522_get_state(&state, i2c, config->demod_address);
+ switch (instance) {
+ case 0:
+ dprintk("%s state allocation failed\n", __func__);
+ break;
+ case 1:
+ /* new demod instance */
+ dprintk("%s using new instance\n", __func__);
+ break;
+ default:
+ /* existing demod instance */
+ dprintk("%s using existing instance\n", __func__);
+ break;
+ }
/* setup the state */
state->config = config;
@@ -836,7 +864,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
return &state->frontend;
error:
- kfree(state);
+ au8522_release_state(state);
return NULL;
}
EXPORT_SYMBOL(au8522_attach);
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
new file mode 100644
index 00000000000..f328f2b3ad3
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -0,0 +1,412 @@
+/*
+ Auvitek AU8522 QAM/8VSB demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+ Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
+ Copyright (C) 2005-2008 Auvitek International, Ltd.
+
+ 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 <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "tuner-i2c.h"
+
+struct au8522_state {
+ struct i2c_client *c;
+ struct i2c_adapter *i2c;
+
+ /* Used for sharing of the state between analog and digital mode */
+ struct tuner_i2c_props i2c_props;
+ struct list_head hybrid_tuner_instance_list;
+
+ /* 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;
+
+ /* Analog settings */
+ struct v4l2_subdev sd;
+ v4l2_std_id std;
+ int vid_input;
+ int aud_input;
+ u32 id;
+ u32 rev;
+ u8 brightness;
+ u8 contrast;
+};
+
+/* These are routines shared by both the VSB/QAM demodulator and the analog
+ decoder */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
+u8 au8522_readreg(struct au8522_state *state, u16 reg);
+int au8522_init(struct dvb_frontend *fe);
+int au8522_sleep(struct dvb_frontend *fe);
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address);
+void au8522_release_state(struct au8522_state *state);
+
+/* REGISTERS */
+#define AU8522_INPUT_CONTROL_REG081H 0x081
+#define AU8522_PGA_CONTROL_REG082H 0x082
+#define AU8522_CLAMPING_CONTROL_REG083H 0x083
+
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5
+#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6
+#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
+#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9
+#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA
+#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB
+#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC
+#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD
+#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE
+#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF
+
+/* Receiver registers */
+#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0
+#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
+#define AU8522_TOREGAGC1_REG0B3H 0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
+#define AU8522_FRMREGBBH_REG0B5H 0x0B5
+#define AU8522_FRMREGBBM_REG0B6H 0x0B6
+#define AU8522_FRMREGBBL_REG0B7H 0x0B7
+/* 0xB8 TO 0xD7 are the filter coefficients */
+#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
+#define AU8522_TOREGAGC2_REG0DAH 0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
+#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC
+#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD
+#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE
+#define AU8522_TOREGFREQ_REG0DFH 0x0DF
+
+#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB
+#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC
+#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED
+
+#define AU8522_CHIP_MODE_REG0FEH 0x0FE
+
+/* I2C bus control registers */
+#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
+#define AU8522_I2C_STATUS_REG092H 0x092
+#define AU8522_I2C_WR_DATA0_REG093H 0x093
+#define AU8522_I2C_WR_DATA1_REG094H 0x094
+#define AU8522_I2C_WR_DATA2_REG095H 0x095
+#define AU8522_I2C_WR_DATA3_REG096H 0x096
+#define AU8522_I2C_WR_DATA4_REG097H 0x097
+#define AU8522_I2C_WR_DATA5_REG098H 0x098
+#define AU8522_I2C_WR_DATA6_REG099H 0x099
+#define AU8522_I2C_WR_DATA7_REG09AH 0x09A
+#define AU8522_I2C_RD_DATA0_REG09BH 0x09B
+#define AU8522_I2C_RD_DATA1_REG09CH 0x09C
+#define AU8522_I2C_RD_DATA2_REG09DH 0x09D
+#define AU8522_I2C_RD_DATA3_REG09EH 0x09E
+#define AU8522_I2C_RD_DATA4_REG09FH 0x09F
+#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0
+#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1
+#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2
+
+#define AU8522_ENA_USB_REG101H 0x101
+
+#define AU8522_I2S_CTRL_0_REG110H 0x110
+#define AU8522_I2S_CTRL_1_REG111H 0x111
+#define AU8522_I2S_CTRL_2_REG112H 0x112
+
+#define AU8522_FRMREGFFECONTROL_REG121H 0x121
+#define AU8522_FRMREGDFECONTROL_REG122H 0x122
+
+#define AU8522_CARRFREQOFFSET0_REG201H 0x201
+#define AU8522_CARRFREQOFFSET1_REG202H 0x202
+
+#define AU8522_DECIMATION_GAIN_REG21AH 0x21A
+#define AU8522_FRMREGIFSLP_REG21BH 0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
+#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E
+#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
+#define AU8522_FRMREGCSTHRD_REG220H 0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
+#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227
+#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
+
+/* Analog TV Decoder */
+#define AU8522_TVDEC_STATUS_REG000H 0x000
+#define AU8522_TVDEC_INT_STATUS_REG001H 0x001
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
+#define AU8522_TVDEC_SHARPNESSREG009H 0x009
+#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A
+#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B
+#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C
+#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D
+#define AU8522_TVDEC_HUE_H_REG00EH 0x00E
+#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
+#define AU8522_TVDEC_INT_MASK_REG010H 0x010
+#define AU8522_VIDEO_MODE_REG011H 0x011
+#define AU8522_TVDEC_PGA_REG012H 0x012
+#define AU8522_TVDEC_COMB_MODE_REG015H 0x015
+#define AU8522_REG016H 0x016
+#define AU8522_TVDED_DBG_MODE_REG060H 0x060
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B
+#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E
+#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F
+
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4
+#define AU8522_TOREGAAGC_REG0E5H 0x0E5
+
+#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401
+#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402
+#define AU8522_FILTER_COEF_R410 0x410
+#define AU8522_FILTER_COEF_R411 0x411
+#define AU8522_FILTER_COEF_R412 0x412
+#define AU8522_FILTER_COEF_R413 0x413
+#define AU8522_FILTER_COEF_R414 0x414
+#define AU8522_FILTER_COEF_R415 0x415
+#define AU8522_FILTER_COEF_R416 0x416
+#define AU8522_FILTER_COEF_R417 0x417
+#define AU8522_FILTER_COEF_R418 0x418
+#define AU8522_FILTER_COEF_R419 0x419
+#define AU8522_FILTER_COEF_R41A 0x41A
+#define AU8522_FILTER_COEF_R41B 0x41B
+#define AU8522_FILTER_COEF_R41C 0x41C
+#define AU8522_FILTER_COEF_R41D 0x41D
+#define AU8522_FILTER_COEF_R41E 0x41E
+#define AU8522_FILTER_COEF_R41F 0x41F
+#define AU8522_FILTER_COEF_R420 0x420
+#define AU8522_FILTER_COEF_R421 0x421
+#define AU8522_FILTER_COEF_R422 0x422
+#define AU8522_FILTER_COEF_R423 0x423
+#define AU8522_FILTER_COEF_R424 0x424
+#define AU8522_FILTER_COEF_R425 0x425
+#define AU8522_FILTER_COEF_R426 0x426
+#define AU8522_FILTER_COEF_R427 0x427
+#define AU8522_FILTER_COEF_R428 0x428
+#define AU8522_FILTER_COEF_R429 0x429
+#define AU8522_FILTER_COEF_R42A 0x42A
+#define AU8522_FILTER_COEF_R42B 0x42B
+#define AU8522_FILTER_COEF_R42C 0x42C
+#define AU8522_FILTER_COEF_R42D 0x42D
+
+/* VBI Control Registers */
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017
+#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018
+#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019
+#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A
+#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B
+#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023
+
+#define AU8522_REG071H 0x071
+#define AU8522_REG072H 0x072
+#define AU8522_REG074H 0x074
+#define AU8522_REG075H 0x075
+
+/* Digital Demodulator Registers */
+#define AU8522_FRAME_COUNT0_REG084H 0x084
+#define AU8522_RS_STATUS_G0_REG085H 0x085
+#define AU8522_RS_STATUS_B0_REG086H 0x086
+#define AU8522_RS_STATUS_E_REG087H 0x087
+#define AU8522_DEMODULATION_STATUS_REG088H 0x088
+#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6
+#define AU8522_TSPORT_CONTROL_REG10BH 0x10B
+#define AU8522_TSTHES_REG10CH 0x10C
+#define AU8522_FRMREGDFEKEEP_REG301H 0x301
+#define AU8522_DFE_AVERAGE_REG302H 0x302
+#define AU8522_FRMREGEQLERRWIN_REG303H 0x303
+#define AU8522_FRMREGFFEKEEP_REG304H 0x304
+#define AU8522_FRMREGDFECONTROL1_REG305H 0x305
+#define AU8522_FRMREGEQLERRLOW_REG306H 0x306
+
+#define AU8522_REG42EH 0x42E
+#define AU8522_REG42FH 0x42F
+#define AU8522_REG430H 0x430
+#define AU8522_REG431H 0x431
+#define AU8522_REG432H 0x432
+#define AU8522_REG433H 0x433
+#define AU8522_REG434H 0x434
+#define AU8522_REG435H 0x435
+#define AU8522_REG436H 0x436
+
+/* GPIO Registers */
+#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0
+#define AU8522_GPIO_STATUS_REG0E1H 0x0E1
+#define AU8522_GPIO_DATA_REG0E2H 0x0E2
+
+/* Audio Control Registers */
+#define AU8522_AUDIOAGC_REG0EEH 0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
+#define AU8522_REG0F9H 0x0F9
+
+#define AU8522_AUDIOAGC2_REG605H 0x605
+#define AU8522_AUDIOFREQ_REG606H 0x606
+
+
+/**************************************************************/
+
+#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
+/* CH1 AS Y,CH3 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
+/* CH2 AS Y,CH4 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02
+
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD
+
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01
+
+/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
+#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79
+#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80
+#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80
+#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00
+#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00
+#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F
+#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00
+#define AU8522_REG016H_CVBS 0x00
+#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19
+#define AU8522_REG0F9H_AUDIO 0x20
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
+#define AU8522_REG071H_CVBS 0x18
+#define AU8522_REG072H_CVBS 0x30
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0
+#define AU8522_REG074H_CVBS 0x80
+#define AU8522_REG075H_CVBS 0xF0
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE
+#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00
+#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40
+
+/* Enables Closed captioning */
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
index f6e7b0380a5..e4fd533a427 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
int rc;
if (state == NULL) {
- err("Unable to kmalloc\n");
+ err("Unable to kzalloc\n");
goto error;
}
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 28ad609e73f..9b9f57264ce 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -15,6 +15,9 @@
September, 9th 2008
Fixed locking on high symbol rates (>30000).
Implement MPEG initialization parameter.
+ January, 17th 2009
+ Fill set_voltage with actually control voltage code.
+ Correct set tone to not affect voltage.
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
@@ -146,7 +149,7 @@ enum cmds {
CMD_GETAGC = 0x19,
CMD_LNBCONFIG = 0x20,
CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
- CMD_SET_TONEPRE = 0x22,
+ CMD_LNBDCLEVEL = 0x22,
CMD_SET_TONE = 0x23,
CMD_UPDFWVERS = 0x35,
CMD_TUNERSLEEP = 0x36,
@@ -667,16 +670,6 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
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;
@@ -837,6 +830,34 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
return -ETIMEDOUT; /* -EBUSY ? */
}
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct cx24116_cmd cmd;
+ int ret;
+
+ dprintk("%s: %s\n", __func__,
+ voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+ voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+ /* Wait for LNB ready */
+ ret = cx24116_wait_for_lnb(fe);
+ if (ret != 0)
+ return ret;
+
+ /* Wait for voltage/min repeat delay */
+ msleep(100);
+
+ cmd.args[0x00] = CMD_LNBDCLEVEL;
+ cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
+ cmd.len = 0x02;
+
+ /* Min delay time before DiSEqC send */
+ msleep(15);
+
+ return cx24116_cmd_execute(fe, &cmd);
+}
+
static int cx24116_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t tone)
{
@@ -857,14 +878,6 @@ static int cx24116_set_tone(struct dvb_frontend *fe,
/* 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;
@@ -1099,13 +1112,10 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
+ state = kzalloc(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;
@@ -1154,7 +1164,12 @@ static int cx24116_initfe(struct dvb_frontend *fe)
if (ret != 0)
return ret;
- return cx24116_diseqc_init(fe);
+ ret = cx24116_diseqc_init(fe);
+ if (ret != 0)
+ return ret;
+
+ /* HVR-4000 needs this */
+ return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
}
/*
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 1a8c36f7606..0592f043ea6 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -1069,13 +1069,13 @@ static struct dvb_frontend_ops cx24123_ops;
struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter *i2c)
{
+ /* allocate memory for the internal state */
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");
+ err("Unable to kzalloc\n");
goto error;
}
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 21f2c5161af..9670f5d20cf 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -58,6 +58,4 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
}
#endif
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
-
#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
index 4142ed7a47d..d75ffad2d75 100644
--- a/drivers/media/dvb/frontends/dib3000mc.h
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -39,19 +39,43 @@ struct dib3000mc_config {
#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);
+#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);
+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);
#else
-static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+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[]);
+static inline
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib3000mc_config cfg[])
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
-extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
+static inline
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+ int gating)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MC
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);
diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h
index 597e9cc2da6..113819ce9f0 100644
--- a/drivers/media/dvb/frontends/dib7000m.h
+++ b/drivers/media/dvb/frontends/dib7000m.h
@@ -38,8 +38,32 @@ struct dib7000m_config {
#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);
+#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
+ defined(MODULE))
+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);
+#else
+static inline
+struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr, struct dib7000m_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+static inline
+struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
+ enum dibx000_i2c_interface intf,
+ int gating)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
/* TODO
extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index aab8112e2db..02a4c82f0c7 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -37,7 +37,8 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
-#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE))
+#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);
@@ -49,10 +50,11 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
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);
+extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
#else
-static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
- u8 i2c_addr,
- struct dib7000p_config *cfg)
+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;
@@ -60,36 +62,39 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
static inline
struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
- enum dibx000_i2c_interface i, int x)
+ 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[])
+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)
+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)
+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);
+static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
+#endif
#endif
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 1e81e713df6..172f1f928f0 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -74,7 +74,7 @@ static struct {
} fw[] = {
#define _FW_ENTRY(a, b, c) { \
.name = a, \
- .file = 0, \
+ .file = NULL, \
.lock = __RW_LOCK_UNLOCKED(fw[c].lock), \
.refcnt = 0, \
.data = { } }
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
index 8210f19d56c..1fcb987d638 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.h
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -25,8 +25,27 @@
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
+#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
+defined(MODULE))
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);
+#else
+static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_DUMMY_FE */
#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h
index 8cdc54e5790..08ca851223c 100644
--- a/drivers/media/dvb/frontends/itd1000_priv.h
+++ b/drivers/media/dvb/frontends/itd1000_priv.h
@@ -31,7 +31,7 @@ struct itd1000_state {
/* ugly workaround for flexcop's incapable i2c-controller
* FIXME, if possible
*/
- u8 shadow[255];
+ u8 shadow[256];
};
enum itd1000_register {
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index 3bb0c4394f8..eb72a9866c9 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -363,7 +363,6 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
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;
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
new file mode 100644
index 00000000000..d92d0557a80
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -0,0 +1,1087 @@
+/*
+ * Support for LGDT3305 - VSB/QAM
+ *
+ * Copyright (C) 2008, 2009 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 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/dvb/frontend.h>
+#include "dvb_math.h"
+#include "lgdt3305.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG 2
+
+#define lg_printk(kern, fmt, arg...) \
+ printk(kern "%s: " fmt, __func__, ##arg)
+
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg)
+#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
+#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
+
+#define lg_fail(ret) \
+({ \
+ int __ret; \
+ __ret = (ret < 0); \
+ if (__ret) \
+ lg_err("error %d on line %d\n", ret, __LINE__); \
+ __ret; \
+})
+
+struct lgdt3305_state {
+ struct i2c_adapter *i2c_adap;
+ const struct lgdt3305_config *cfg;
+
+ struct dvb_frontend frontend;
+
+ fe_modulation_t current_modulation;
+ u32 current_frequency;
+ u32 snr;
+};
+
+/* ------------------------------------------------------------------------ */
+
+#define LGDT3305_GEN_CTRL_1 0x0000
+#define LGDT3305_GEN_CTRL_2 0x0001
+#define LGDT3305_GEN_CTRL_3 0x0002
+#define LGDT3305_GEN_STATUS 0x0003
+#define LGDT3305_GEN_CONTROL 0x0007
+#define LGDT3305_GEN_CTRL_4 0x000a
+#define LGDT3305_DGTL_AGC_REF_1 0x0012
+#define LGDT3305_DGTL_AGC_REF_2 0x0013
+#define LGDT3305_CR_CTR_FREQ_1 0x0106
+#define LGDT3305_CR_CTR_FREQ_2 0x0107
+#define LGDT3305_CR_CTR_FREQ_3 0x0108
+#define LGDT3305_CR_CTR_FREQ_4 0x0109
+#define LGDT3305_CR_MSE_1 0x011b
+#define LGDT3305_CR_MSE_2 0x011c
+#define LGDT3305_CR_LOCK_STATUS 0x011d
+#define LGDT3305_CR_CTRL_7 0x0126
+#define LGDT3305_AGC_POWER_REF_1 0x0300
+#define LGDT3305_AGC_POWER_REF_2 0x0301
+#define LGDT3305_AGC_DELAY_PT_1 0x0302
+#define LGDT3305_AGC_DELAY_PT_2 0x0303
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307
+#define LGDT3305_IFBW_1 0x0308
+#define LGDT3305_IFBW_2 0x0309
+#define LGDT3305_AGC_CTRL_1 0x030c
+#define LGDT3305_AGC_CTRL_4 0x0314
+#define LGDT3305_EQ_MSE_1 0x0413
+#define LGDT3305_EQ_MSE_2 0x0414
+#define LGDT3305_EQ_MSE_3 0x0415
+#define LGDT3305_PT_MSE_1 0x0417
+#define LGDT3305_PT_MSE_2 0x0418
+#define LGDT3305_PT_MSE_3 0x0419
+#define LGDT3305_FEC_BLOCK_CTRL 0x0504
+#define LGDT3305_FEC_LOCK_STATUS 0x050a
+#define LGDT3305_FEC_PKT_ERR_1 0x050c
+#define LGDT3305_FEC_PKT_ERR_2 0x050d
+#define LGDT3305_TP_CTRL_1 0x050e
+#define LGDT3305_BERT_PERIOD 0x0801
+#define LGDT3305_BERT_ERROR_COUNT_1 0x080a
+#define LGDT3305_BERT_ERROR_COUNT_2 0x080b
+#define LGDT3305_BERT_ERROR_COUNT_3 0x080c
+#define LGDT3305_BERT_ERROR_COUNT_4 0x080d
+
+static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
+{
+ int ret;
+ u8 buf[] = { reg >> 8, reg & 0xff, val };
+ struct i2c_msg msg = {
+ .addr = state->cfg->i2c_addr, .flags = 0,
+ .buf = buf, .len = 3,
+ };
+
+ lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+ ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+ if (ret != 1) {
+ lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
+ msg.buf[0], msg.buf[1], msg.buf[2], ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
+{
+ int ret;
+ u8 reg_buf[] = { reg >> 8, reg & 0xff };
+ struct i2c_msg msg[] = {
+ { .addr = state->cfg->i2c_addr,
+ .flags = 0, .buf = reg_buf, .len = 2 },
+ { .addr = state->cfg->i2c_addr,
+ .flags = I2C_M_RD, .buf = val, .len = 1 },
+ };
+
+ lg_reg("reg: 0x%04x\n", reg);
+
+ ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ lg_err("error (addr %02x reg %04x error (ret == %i)\n",
+ state->cfg->i2c_addr, reg, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+#define read_reg(state, reg) \
+({ \
+ u8 __val; \
+ int ret = lgdt3305_read_reg(state, reg, &__val); \
+ if (lg_fail(ret)) \
+ __val = 0; \
+ __val; \
+})
+
+static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
+ u16 reg, int bit, int onoff)
+{
+ u8 val;
+ int ret;
+
+ lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+ ret = lgdt3305_read_reg(state, reg, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ val &= ~(1 << bit);
+ val |= (onoff & 1) << bit;
+
+ ret = lgdt3305_write_reg(state, reg, val);
+fail:
+ return ret;
+}
+
+struct lgdt3305_reg {
+ u16 reg;
+ u8 val;
+};
+
+static int lgdt3305_write_regs(struct lgdt3305_state *state,
+ struct lgdt3305_reg *regs, int len)
+{
+ int i, ret;
+
+ lg_reg("writing %d registers...\n", len);
+
+ for (i = 0; i < len - 1; i++) {
+ ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
+ if (lg_fail(ret))
+ return ret;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_soft_reset(struct lgdt3305_state *state)
+{
+ int ret;
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ msleep(20);
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
+fail:
+ return ret;
+}
+
+static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
+ enum lgdt3305_mpeg_mode mode)
+{
+ lg_dbg("(%d)\n", mode);
+ return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
+}
+
+static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
+ enum lgdt3305_tp_clock_edge edge,
+ enum lgdt3305_tp_valid_polarity valid)
+{
+ u8 val;
+ int ret;
+
+ lg_dbg("edge = %d, valid = %d\n", edge, valid);
+
+ ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ val &= ~0x09;
+
+ if (edge)
+ val |= 0x08;
+ if (valid)
+ val |= 0x01;
+
+ ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_soft_reset(state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_modulation(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u8 opermode;
+ int ret;
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
+ if (lg_fail(ret))
+ goto fail;
+
+ opermode &= ~0x03;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ opermode |= 0x03;
+ break;
+ case QAM_64:
+ opermode |= 0x00;
+ break;
+ case QAM_256:
+ opermode |= 0x01;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ int val;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ val = 0;
+ break;
+ case QAM_64:
+ case QAM_256:
+ val = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lg_dbg("val = %d\n", val);
+
+ return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 agc_ref;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ agc_ref = 0x32c4;
+ break;
+ case QAM_64:
+ agc_ref = 0x2a00;
+ break;
+ case QAM_256:
+ agc_ref = 0x2a80;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ lg_dbg("agc ref: 0x%04x\n", agc_ref);
+
+ lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
+ lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
+
+ return 0;
+}
+
+static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 ifbw, rfbw, agcdelay;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ agcdelay = 0x04c0;
+ rfbw = 0x8000;
+ ifbw = 0x8000;
+ break;
+ case QAM_64:
+ case QAM_256:
+ agcdelay = 0x046b;
+ rfbw = 0x8889;
+ ifbw = 0x8888;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state->cfg->rf_agc_loop) {
+ lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
+
+ /* rf agc loop filter bandwidth */
+ lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
+ agcdelay >> 8);
+ lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
+ agcdelay & 0xff);
+
+ lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+ rfbw >> 8);
+ lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+ rfbw & 0xff);
+ } else {
+ lg_dbg("ifbw: 0x%04x\n", ifbw);
+
+ /* if agc loop filter bandwidth */
+ lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
+ lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
+ }
+
+ return 0;
+}
+
+static int lgdt3305_agc_setup(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ int lockdten, acqen;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ lockdten = 0;
+ acqen = 0;
+ break;
+ case QAM_64:
+ case QAM_256:
+ lockdten = 1;
+ acqen = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
+
+ /* control agc function */
+ lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+
+ return lgdt3305_rfagc_loop(state, param);
+}
+
+static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 usref = 0;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ if (state->cfg->usref_8vsb)
+ usref = state->cfg->usref_8vsb;
+ break;
+ case QAM_64:
+ if (state->cfg->usref_qam64)
+ usref = state->cfg->usref_qam64;
+ break;
+ case QAM_256:
+ if (state->cfg->usref_qam256)
+ usref = state->cfg->usref_qam256;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (usref) {
+ lg_dbg("set manual mode: 0x%04x\n", usref);
+
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
+
+ lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
+ 0xff & (usref >> 8));
+ lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
+ 0xff & (usref >> 0));
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param,
+ int inversion)
+{
+ int ret;
+
+ lg_dbg("(%d)\n", inversion);
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
+ inversion ? 0xf9 : 0x79);
+ break;
+ case QAM_64:
+ case QAM_256:
+ ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
+ inversion ? 0xfd : 0xff);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int lgdt3305_set_if(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 if_freq_khz;
+ u8 nco1, nco2, nco3, nco4;
+ u64 nco;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ if_freq_khz = state->cfg->vsb_if_khz;
+ break;
+ case QAM_64:
+ case QAM_256:
+ if_freq_khz = state->cfg->qam_if_khz;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ nco = if_freq_khz / 10;
+
+#define LGDT3305_64BIT_DIVISION_ENABLED 0
+ /* FIXME: 64bit division disabled to avoid linking error:
+ * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
+ */
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+ nco <<= 24;
+ nco /= 625;
+#else
+ nco *= ((1 << 24) / 625);
+#endif
+ break;
+ case QAM_64:
+ case QAM_256:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+ nco <<= 28;
+ nco /= 625;
+#else
+ nco *= ((1 << 28) / 625);
+#endif
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ nco1 = (nco >> 24) & 0x3f;
+ nco1 |= 0x40;
+ nco2 = (nco >> 16) & 0xff;
+ nco3 = (nco >> 8) & 0xff;
+ nco4 = nco & 0xff;
+
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
+
+ lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
+ if_freq_khz, nco1, nco2, nco3, nco4);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ if (state->cfg->deny_i2c_rptr)
+ return 0;
+
+ lg_dbg("(%d)\n", enable);
+
+ return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
+ enable ? 0 : 1);
+}
+
+static int lgdt3305_sleep(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u8 gen_ctrl_3, gen_ctrl_4;
+
+ lg_dbg("\n");
+
+ gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
+ gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
+
+ /* hold in software reset while sleeping */
+ gen_ctrl_3 &= ~0x01;
+ /* tristate the IF-AGC pin */
+ gen_ctrl_3 |= 0x02;
+ /* tristate the RF-AGC pin */
+ gen_ctrl_3 |= 0x04;
+
+ /* disable vsb/qam module */
+ gen_ctrl_4 &= ~0x01;
+ /* disable adc module */
+ gen_ctrl_4 &= ~0x02;
+
+ lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
+ lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
+
+ return 0;
+}
+
+static int lgdt3305_init(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ static struct lgdt3305_reg lgdt3305_init_data[] = {
+ { .reg = LGDT3305_GEN_CTRL_1,
+ .val = 0x03, },
+ { .reg = LGDT3305_GEN_CTRL_2,
+ .val = 0xb0, },
+ { .reg = LGDT3305_GEN_CTRL_3,
+ .val = 0x01, },
+ { .reg = LGDT3305_GEN_CONTROL,
+ .val = 0x6f, },
+ { .reg = LGDT3305_GEN_CTRL_4,
+ .val = 0x03, },
+ { .reg = LGDT3305_DGTL_AGC_REF_1,
+ .val = 0x32, },
+ { .reg = LGDT3305_DGTL_AGC_REF_2,
+ .val = 0xc4, },
+ { .reg = LGDT3305_CR_CTR_FREQ_1,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_3,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_4,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTRL_7,
+ .val = 0x79, },
+ { .reg = LGDT3305_AGC_POWER_REF_1,
+ .val = 0x32, },
+ { .reg = LGDT3305_AGC_POWER_REF_2,
+ .val = 0xc4, },
+ { .reg = LGDT3305_AGC_DELAY_PT_1,
+ .val = 0x0d, },
+ { .reg = LGDT3305_AGC_DELAY_PT_2,
+ .val = 0x30, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+ .val = 0x80, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_IFBW_1,
+ .val = 0x80, },
+ { .reg = LGDT3305_IFBW_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_AGC_CTRL_1,
+ .val = 0x30, },
+ { .reg = LGDT3305_AGC_CTRL_4,
+ .val = 0x61, },
+ { .reg = LGDT3305_FEC_BLOCK_CTRL,
+ .val = 0xff, },
+ { .reg = LGDT3305_TP_CTRL_1,
+ .val = 0x1b, },
+ };
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_write_regs(state, lgdt3305_init_data,
+ ARRAY_SIZE(lgdt3305_init_data));
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_soft_reset(state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_parameters(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
+
+ if (fe->ops.tuner_ops.set_params) {
+ ret = fe->ops.tuner_ops.set_params(fe, param);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ if (lg_fail(ret))
+ goto fail;
+ state->current_frequency = param->frequency;
+ }
+
+ ret = lgdt3305_set_modulation(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_passband_digital_agc(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_set_agc_power_ref(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_agc_setup(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* low if */
+ ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_set_if(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_spectral_inversion(state, param,
+ state->cfg->spectral_inversion
+ ? 1 : 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_set_filter_extension(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_modulation = param->u.vsb.modulation;
+
+ ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+ ret = lgdt3305_mpeg_mode_polarity(state,
+ state->cfg->tpclk_edge,
+ state->cfg->tpvalid_polarity);
+fail:
+ return ret;
+}
+
+static int lgdt3305_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ lg_dbg("\n");
+
+ param->u.vsb.modulation = state->current_modulation;
+ param->frequency = state->current_frequency;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
+ int *locked)
+{
+ u8 val;
+ int ret;
+ char *cr_lock_state = "";
+
+ *locked = 0;
+
+ ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ if (val & (1 << 1))
+ *locked = 1;
+
+ switch (val & 0x07) {
+ case 0:
+ cr_lock_state = "QAM UNLOCK";
+ break;
+ case 4:
+ cr_lock_state = "QAM 1stLock";
+ break;
+ case 6:
+ cr_lock_state = "QAM 2ndLock";
+ break;
+ case 7:
+ cr_lock_state = "QAM FinalLock";
+ break;
+ default:
+ cr_lock_state = "CLOCKQAM-INVALID!";
+ break;
+ }
+ break;
+ case VSB_8:
+ if (val & (1 << 7)) {
+ *locked = 1;
+ cr_lock_state = "CLOCKVSB";
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ lg_dbg("(%d) %s\n", *locked, cr_lock_state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
+ int *locked)
+{
+ u8 val;
+ int ret, mpeg_lock, fec_lock, viterbi_lock;
+
+ *locked = 0;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ ret = lgdt3305_read_reg(state,
+ LGDT3305_FEC_LOCK_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ mpeg_lock = (val & (1 << 0)) ? 1 : 0;
+ fec_lock = (val & (1 << 2)) ? 1 : 0;
+ viterbi_lock = (val & (1 << 3)) ? 1 : 0;
+
+ *locked = mpeg_lock && fec_lock && viterbi_lock;
+
+ lg_dbg("(%d) %s%s%s\n", *locked,
+ mpeg_lock ? "mpeg lock " : "",
+ fec_lock ? "fec lock " : "",
+ viterbi_lock ? "viterbi lock" : "");
+ break;
+ case VSB_8:
+ default:
+ ret = -EINVAL;
+ }
+fail:
+ return ret;
+}
+
+static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u8 val;
+ int ret, signal, inlock, nofecerr, snrgood,
+ cr_lock, fec_lock, sync_lock;
+
+ *status = 0;
+
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ signal = (val & (1 << 4)) ? 1 : 0;
+ inlock = (val & (1 << 3)) ? 0 : 1;
+ sync_lock = (val & (1 << 2)) ? 1 : 0;
+ nofecerr = (val & (1 << 1)) ? 1 : 0;
+ snrgood = (val & (1 << 0)) ? 1 : 0;
+
+ lg_dbg("%s%s%s%s%s\n",
+ signal ? "SIGNALEXIST " : "",
+ inlock ? "INLOCK " : "",
+ sync_lock ? "SYNCLOCK " : "",
+ nofecerr ? "NOFECERR " : "",
+ snrgood ? "SNRGOOD " : "");
+
+ ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
+ if (lg_fail(ret))
+ goto fail;
+
+ if (signal)
+ *status |= FE_HAS_SIGNAL;
+ if (cr_lock)
+ *status |= FE_HAS_CARRIER;
+ if (nofecerr)
+ *status |= FE_HAS_VITERBI;
+ if (sync_lock)
+ *status |= FE_HAS_SYNC;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
+ if (lg_fail(ret))
+ goto fail;
+
+ if (fec_lock)
+ *status |= FE_HAS_LOCK;
+ break;
+ case VSB_8:
+ if (inlock)
+ *status |= FE_HAS_LOCK;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* borrowed from lgdt330x.c */
+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 lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u32 noise; /* noise value */
+ u32 c; /* per-modulation SNR calculation constant */
+
+ switch (state->current_modulation) {
+ case VSB_8:
+#ifdef USE_PTMSE
+ /* Use Phase Tracker Mean-Square Error Register */
+ /* SNR for ranges from -13.11 to +44.08 */
+ noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
+ (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
+ (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
+ c = 73957994; /* log10(25*32^2)*2^24 */
+#else
+ /* Use Equalizer Mean-Square Error Register */
+ /* SNR for ranges from -16.12 to +44.08 */
+ noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
+ (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
+ (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
+ c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+ break;
+ case QAM_64:
+ case QAM_256:
+ noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
+ (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
+
+ c = (state->current_modulation == QAM_64) ?
+ 97939837 : 98026066;
+ /* log10(688128)*2^24 and log10(696320)*2^24 */
+ break;
+ default:
+ return -EINVAL;
+ }
+ state->snr = calculate_snr(noise, c);
+ /* report SNR in dB * 10 */
+ *snr = (state->snr / ((1 << 24) / 10));
+ lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
+ state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
+
+ return 0;
+}
+
+static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
+ u16 *strength)
+{
+ /* borrowed from lgdt330x.c
+ *
+ * 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 lgdt3305_state *state = fe->demodulator_priv;
+ u16 snr;
+ int ret;
+
+ *strength = 0;
+
+ ret = fe->ops.read_snr(fe, &snr);
+ if (lg_fail(ret))
+ goto fail;
+ /* 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;
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ *ber = 0;
+ return 0;
+}
+
+static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ *ucblocks =
+ (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
+ (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
+
+ return 0;
+}
+
+static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings
+ *fe_tune_settings)
+{
+ fe_tune_settings->min_delay_ms = 500;
+ lg_dbg("\n");
+ return 0;
+}
+
+static void lgdt3305_release(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ lg_dbg("\n");
+ kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3305_ops;
+
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap)
+{
+ struct lgdt3305_state *state = NULL;
+ int ret;
+ u8 val;
+
+ lg_dbg("(%d-%04x)\n",
+ i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+ config ? config->i2c_addr : 0);
+
+ state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
+ if (state == NULL)
+ goto fail;
+
+ state->cfg = config;
+ state->i2c_adap = i2c_adap;
+
+ memcpy(&state->frontend.ops, &lgdt3305_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* verify that we're talking to a lg dt3305 */
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
+ if ((lg_fail(ret)) | (val == 0))
+ goto fail;
+ ret = lgdt3305_write_reg(state, 0x0808, 0x80);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_read_reg(state, 0x0808, &val);
+ if ((lg_fail(ret)) | (val != 0x80))
+ goto fail;
+ ret = lgdt3305_write_reg(state, 0x0808, 0x00);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_frequency = -1;
+ state->current_modulation = -1;
+
+ return &state->frontend;
+fail:
+ lg_warn("unable to detect LGDT3305 hardware\n");
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(lgdt3305_attach);
+
+static struct dvb_frontend_ops lgdt3305_ops = {
+ .info = {
+ .name = "LG Electronics LGDT3305 VSB/QAM 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
+ },
+ .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
+ .init = lgdt3305_init,
+ .sleep = lgdt3305_sleep,
+ .set_frontend = lgdt3305_set_parameters,
+ .get_frontend = lgdt3305_get_frontend,
+ .get_tune_settings = lgdt3305_get_tune_settings,
+ .read_status = lgdt3305_read_status,
+ .read_ber = lgdt3305_read_ber,
+ .read_signal_strength = lgdt3305_read_signal_strength,
+ .read_snr = lgdt3305_read_snr,
+ .read_ucblocks = lgdt3305_read_ucblocks,
+ .release = lgdt3305_release,
+};
+
+MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
new file mode 100644
index 00000000000..4fa6e52d1fe
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.h
@@ -0,0 +1,85 @@
+/*
+ * Support for LGDT3305 - VSB/QAM
+ *
+ * Copyright (C) 2008, 2009 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 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 _LGDT3305_H_
+#define _LGDT3305_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+
+enum lgdt3305_mpeg_mode {
+ LGDT3305_MPEG_PARALLEL = 0,
+ LGDT3305_MPEG_SERIAL = 1,
+};
+
+enum lgdt3305_tp_clock_edge {
+ LGDT3305_TPCLK_RISING_EDGE = 0,
+ LGDT3305_TPCLK_FALLING_EDGE = 1,
+};
+
+enum lgdt3305_tp_valid_polarity {
+ LGDT3305_TP_VALID_LOW = 0,
+ LGDT3305_TP_VALID_HIGH = 1,
+};
+
+struct lgdt3305_config {
+ u8 i2c_addr;
+
+ /* user defined IF frequency in KHz */
+ u16 qam_if_khz;
+ u16 vsb_if_khz;
+
+ /* AGC Power reference - defaults are used if left unset */
+ u16 usref_8vsb; /* default: 0x32c4 */
+ u16 usref_qam64; /* default: 0x5400 */
+ u16 usref_qam256; /* default: 0x2a80 */
+
+ /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+ int deny_i2c_rptr:1;
+
+ /* spectral inversion - 0:disabled 1:enabled */
+ int spectral_inversion:1;
+
+ /* use RF AGC loop - 0:disabled 1:enabled */
+ int rf_agc_loop:1;
+
+ enum lgdt3305_mpeg_mode mpeg_mode;
+ enum lgdt3305_tp_clock_edge tpclk_edge;
+ enum lgdt3305_tp_valid_polarity tpvalid_polarity;
+};
+
+#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
+ defined(MODULE))
+extern
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_LGDT3305 */
+
+#endif /* _LGDT3305_H_ */
diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h
new file mode 100644
index 00000000000..c059b165318
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbh24.h
@@ -0,0 +1,55 @@
+/*
+ * lnbh24.h - driver for lnb supply and control ic lnbh24
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 _LNBH24_H
+#define _LNBH24_H
+
+/* system register bits */
+#define LNBH24_OLF 0x01
+#define LNBH24_OTF 0x02
+#define LNBH24_EN 0x04
+#define LNBH24_VSEL 0x08
+#define LNBH24_LLC 0x10
+#define LNBH24_TEN 0x20
+#define LNBH24_TTX 0x40
+#define LNBH24_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 *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr);
+#else
+static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index 76f935d9755..1dcc56f32bf 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -1,7 +1,8 @@
/*
- * lnbp21.h - driver for lnb supply and control ic lnbp21
+ * lnbp21.c - driver for lnb supply and control ic lnbp21
*
* Copyright (C) 2006 Oliver Endriss
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,18 +34,21 @@
#include "dvb_frontend.h"
#include "lnbp21.h"
+#include "lnbh24.h"
struct lnbp21 {
u8 config;
u8 override_or;
u8 override_and;
struct i2c_adapter *i2c;
+ u8 i2c_addr;
};
-static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+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,
+ struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -72,7 +76,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
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,
+ struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -97,15 +101,18 @@ static void lnbp21_release(struct dvb_frontend *fe)
fe->sec_priv = NULL;
}
-struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr, u8 config)
{
struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
if (!lnbp21)
return NULL;
/* default configuration */
- lnbp21->config = LNBP21_ISEL;
+ lnbp21->config = config;
lnbp21->i2c = i2c;
+ lnbp21->i2c_addr = i2c_addr;
fe->sec_priv = lnbp21;
/* bits which should be forced to '1' */
@@ -126,11 +133,29 @@ struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *
/* override frontend ops */
fe->ops.set_voltage = lnbp21_set_voltage;
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+ printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr);
return fe;
}
+
+struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr)
+{
+ return lnbx2x_attach(fe, i2c, override_set, override_clear,
+ i2c_addr, LNBH24_TTX);
+}
+EXPORT_SYMBOL(lnbh24_attach);
+
+struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear)
+{
+ return lnbx2x_attach(fe, i2c, override_set, override_clear,
+ 0x08, LNBP21_ISEL);
+}
EXPORT_SYMBOL(lnbp21_attach);
-MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
-MODULE_AUTHOR("Oliver Endriss");
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
+MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 8fe094bd968..fcdf1c650dd 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -28,26 +28,48 @@
#define _LNBP21_H
/* system register bits */
+/* [RO] 0=OK; 1=over current limit flag */
#define LNBP21_OLF 0x01
+/* [RO] 0=OK; 1=over temperature flag (150 C) */
#define LNBP21_OTF 0x02
+/* [RW] 0=disable LNB power, enable loopthrough
+ 1=enable LNB power, disable loopthrough */
#define LNBP21_EN 0x04
+/* [RW] 0=low voltage (13/14V, vert pol)
+ 1=high voltage (18/19V,horiz pol) */
#define LNBP21_VSEL 0x08
+/* [RW] increase LNB voltage by 1V:
+ 0=13/18V; 1=14/19V */
#define LNBP21_LLC 0x10
+/* [RW] 0=tone controlled by DSQIN pin
+ 1=tone enable, disable DSQIN */
#define LNBP21_TEN 0x20
+/* [RW] current limit select:
+ 0:Iout=500-650mA Isc=300mA
+ 1:Iout=400-550mA Isc=200mA */
#define LNBP21_ISEL 0x40
+/* [RW] short-circuit protect:
+ 0=pulsed (dynamic) curr limiting
+ 1=static curr limiting */
#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);
+#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)
+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
-#endif // _LNBP21_H
+#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 892af8c9ed5..3f5a0e1dfdf 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -169,7 +169,6 @@ struct dvb_frontend* s921_attach(const struct s921_config *config,
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;
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
index d3133405dc0..6314d18c797 100644
--- a/drivers/media/dvb/frontends/stb6100_cfg.h
+++ b/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
return err;
}
*frequency = t_state.frequency;
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
}
return 0;
}
@@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
return err;
}
}
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
return 0;
}
@@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
}
*bandwidth = t_state.bandwidth;
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
@@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
return err;
}
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
new file mode 100644
index 00000000000..8a1332c2031
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -0,0 +1,62 @@
+/*
+ * stv0900.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 STV0900_H
+#define STV0900_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0900_config {
+ u8 demod_address;
+ u32 xtal;
+ u8 clkmode;/* 0 for CLKI, 2 for XTALI */
+
+ u8 diseqc_mode;
+
+ u8 path1_mode;
+ u8 path2_mode;
+
+ u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
+ u8 tun2_maddress;
+ u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
+ u8 tun2_adc;
+};
+
+#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c, int demod);
+#else
+static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c, int demod)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
new file mode 100644
index 00000000000..8499bcf7f25
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -0,0 +1,1949 @@
+/*
+ * stv0900_core.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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/string.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+#include "stv0900_init.h"
+
+static int stvdebug = 1;
+module_param_named(debug, stvdebug, int, 0644);
+
+/* internal params node */
+struct stv0900_inode {
+ /* pointer for internal params, one for each pair of demods */
+ struct stv0900_internal *internal;
+ struct stv0900_inode *next_inode;
+};
+
+/* first internal params */
+static struct stv0900_inode *stv0900_first_inode;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr)
+{
+ struct stv0900_inode *temp_chip = stv0900_first_inode;
+
+ if (temp_chip != NULL) {
+ /*
+ Search of the last stv0900 chip or
+ find it by i2c adapter and i2c address */
+ while ((temp_chip != NULL) &&
+ ((temp_chip->internal->i2c_adap != i2c_adap) ||
+ (temp_chip->internal->i2c_addr != i2c_addr)))
+
+ temp_chip = temp_chip->next_inode;
+
+ }
+
+ return temp_chip;
+}
+
+/* deallocating chip */
+static void remove_inode(struct stv0900_internal *internal)
+{
+ struct stv0900_inode *prev_node = stv0900_first_inode;
+ struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
+ internal->i2c_addr);
+
+ if (del_node != NULL) {
+ if (del_node == stv0900_first_inode) {
+ stv0900_first_inode = del_node->next_inode;
+ } else {
+ while (prev_node->next_inode != del_node)
+ prev_node = prev_node->next_inode;
+
+ if (del_node->next_inode == NULL)
+ prev_node->next_inode = NULL;
+ else
+ prev_node->next_inode =
+ prev_node->next_inode->next_inode;
+ }
+
+ kfree(del_node);
+ }
+}
+
+/* allocating new chip */
+static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
+{
+ struct stv0900_inode *new_node = stv0900_first_inode;
+
+ if (new_node == NULL) {
+ new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+ stv0900_first_inode = new_node;
+ } else {
+ while (new_node->next_inode != NULL)
+ new_node = new_node->next_inode;
+
+ new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+ if (new_node->next_inode != NULL)
+ new_node = new_node->next_inode;
+ else
+ new_node = NULL;
+ }
+
+ if (new_node != NULL) {
+ new_node->internal = internal;
+ new_node->next_inode = NULL;
+ }
+
+ return new_node;
+}
+
+s32 ge2comp(s32 a, s32 width)
+{
+ if (width == 32)
+ return a;
+ else
+ return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
+}
+
+void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
+ u8 reg_data)
+{
+ u8 data[3];
+ int ret;
+ struct i2c_msg i2cmsg = {
+ .addr = i_params->i2c_addr,
+ .flags = 0,
+ .len = 3,
+ .buf = data,
+ };
+
+ data[0] = MSB(reg_addr);
+ data[1] = LSB(reg_addr);
+ data[2] = reg_data;
+
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+}
+
+u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr)
+{
+ u8 data[2];
+ int ret;
+ struct i2c_msg i2cmsg = {
+ .addr = i_params->i2c_addr,
+ .flags = 0,
+ .len = 2,
+ .buf = data,
+ };
+
+ data[0] = MSB(reg_addr);
+ data[1] = LSB(reg_addr);
+
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+ i2cmsg.flags = I2C_M_RD;
+ i2cmsg.len = 1;
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+ return data[0];
+}
+
+void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+{
+ u8 position = 0, i = 0;
+
+ (*mask) = label & 0xff;
+
+ while ((position == 0) && (i < 8)) {
+ position = ((*mask) >> i) & 0x01;
+ i++;
+ }
+
+ (*pos) = (i - 1);
+}
+
+void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val)
+{
+ u8 reg, mask, pos;
+
+ reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff);
+ extract_mask_pos(label, &mask, &pos);
+
+ val = mask & (val << pos);
+
+ reg = (reg & (~mask)) | val;
+ stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg);
+
+}
+
+u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label)
+{
+ u8 val = 0xff;
+ u8 mask, pos;
+
+ extract_mask_pos(label, &mask, &pos);
+
+ val = stv0900_read_reg(i_params, label >> 16);
+ val = (val & mask) >> pos;
+
+ return val;
+}
+
+enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
+{
+ s32 i;
+ enum fe_stv0900_error error;
+
+ if (i_params != NULL) {
+ i_params->chip_id = stv0900_read_reg(i_params, R0900_MID);
+ if (i_params->errs == STV0900_NO_ERROR) {
+ /*Startup sequence*/
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
+ stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
+ stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24);
+ stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24);
+ stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
+ msleep(3);
+ stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
+
+ switch (i_params->clkmode) {
+ case 0:
+ case 2:
+ stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20
+ | i_params->clkmode);
+ break;
+ default:
+ /* preserve SELOSCI bit */
+ i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL);
+ stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i);
+ break;
+ }
+
+ msleep(3);
+ for (i = 0; i < 182; i++)
+ stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
+
+ if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) {
+ stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c);
+ for (i = 0; i < 32; i++)
+ stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_TSTRES0, 0x80);
+ stv0900_write_reg(i_params, R0900_TSTRES0, 0x00);
+ }
+ error = i_params->errs;
+ } else
+ error = STV0900_INVALID_HANDLE;
+
+ return error;
+
+}
+
+u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk)
+{
+ u32 mclk = 90000000, div = 0, ad_div = 0;
+
+ div = stv0900_get_bits(i_params, F0900_M_DIV);
+ ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+
+ mclk = (div + 1) * ext_clk / ad_div;
+
+ dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk);
+
+ return mclk;
+}
+
+enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk)
+{
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+ u32 m_div, clk_sel;
+
+ dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+ i_params->quartz);
+
+ if (i_params == NULL)
+ error = STV0900_INVALID_HANDLE;
+ else {
+ if (i_params->errs)
+ error = STV0900_I2C_ERROR;
+ else {
+ clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+ m_div = ((clk_sel * mclk) / i_params->quartz) - 1;
+ stv0900_write_bits(i_params, F0900_M_DIV, m_div);
+ i_params->mclk = stv0900_get_mclk_freq(i_params,
+ i_params->quartz);
+
+ /*Set the DiseqC frequency to 22KHz */
+ /*
+ Formula:
+ DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
+ DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
+ */
+ m_div = i_params->mclk / 704000;
+ stv0900_write_reg(i_params, R0900_P1_F22TX, m_div);
+ stv0900_write_reg(i_params, R0900_P1_F22RX, m_div);
+
+ stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
+ stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
+
+ if ((i_params->errs))
+ error = STV0900_I2C_ERROR;
+ }
+ }
+
+ return error;
+}
+
+u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 lsb, msb, hsb, err_val;
+ s32 err1field_hsb, err1field_msb, err1field_lsb;
+ s32 err2field_hsb, err2field_msb, err2field_lsb;
+
+ dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12);
+ dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11);
+ dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10);
+
+ dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22);
+ dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21);
+ dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20);
+
+ switch (cntr) {
+ case 0:
+ default:
+ hsb = stv0900_get_bits(i_params, err1field_hsb);
+ msb = stv0900_get_bits(i_params, err1field_msb);
+ lsb = stv0900_get_bits(i_params, err1field_lsb);
+ break;
+ case 1:
+ hsb = stv0900_get_bits(i_params, err2field_hsb);
+ msb = stv0900_get_bits(i_params, err2field_msb);
+ lsb = stv0900_get_bits(i_params, err2field_lsb);
+ break;
+ }
+
+ err_val = (hsb << 16) + (msb << 8) + (lsb);
+
+ return err_val;
+}
+
+static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ u32 fi2c;
+
+ dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
+ if (enable)
+ stv0900_write_bits(i_params, fi2c, 1);
+
+ return 0;
+}
+
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
+ enum fe_stv0900_clock_type path1_ts,
+ enum fe_stv0900_clock_type path2_ts)
+{
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id >= 0x20) {
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL,
+ 0x00);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL,
+ 0x06);
+ stv0900_write_bits(i_params,
+ F0900_P1_TSFIFO_MANSPEED, 3);
+ stv0900_write_bits(i_params,
+ F0900_P2_TSFIFO_MANSPEED, 0);
+ stv0900_write_reg(i_params,
+ R0900_P1_TSSPEED, 0x14);
+ stv0900_write_reg(i_params,
+ R0900_P2_TSSPEED, 0x28);
+ break;
+ }
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params,
+ R0900_TSGENERAL, 0x0C);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params,
+ R0900_TSGENERAL, 0x0A);
+ dprintk(KERN_INFO "%s: 0x0a\n", __func__);
+ break;
+ }
+ break;
+ }
+ } else {
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x10);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x16);
+ stv0900_write_bits(i_params,
+ F0900_P1_TSFIFO_MANSPEED, 3);
+ stv0900_write_bits(i_params,
+ F0900_P2_TSFIFO_MANSPEED, 0);
+ stv0900_write_reg(i_params, R0900_P1_TSSPEED,
+ 0x14);
+ stv0900_write_reg(i_params, R0900_P2_TSSPEED,
+ 0x28);
+ break;
+ }
+
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x14);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x12);
+ dprintk(KERN_INFO "%s: 0x12\n", __func__);
+ break;
+ }
+
+ break;
+ }
+ }
+
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_SERIAL_CONT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+ break;
+ default:
+ break;
+ }
+
+ switch (path2_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_SERIAL_CONT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0);
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0);
+}
+
+void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+ u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->set_frequency) {
+ if ((tuner_ops->set_frequency(fe, frequency)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+ }
+
+ if (tuner_ops->set_bandwidth) {
+ if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+ }
+}
+
+void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->set_bandwidth) {
+ if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+ }
+}
+
+static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
+ const struct stv0900_table *lookup,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 agc_gain = 0,
+ imin,
+ imax,
+ i,
+ rf_lvl = 0;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if ((lookup != NULL) && lookup->size) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1),
+ stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0));
+ break;
+ case STV0900_DEMOD_2:
+ agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1),
+ stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0));
+ break;
+ }
+
+ imin = 0;
+ imax = lookup->size - 1;
+ if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) {
+ while ((imax - imin) > 1) {
+ i = (imax + imin) >> 1;
+
+ if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval))
+ imax = i;
+ else
+ imin = i;
+ }
+
+ rf_lvl = (((s32)agc_gain - lookup->table[imin].regval)
+ * (lookup->table[imax].realval - lookup->table[imin].realval)
+ / (lookup->table[imax].regval - lookup->table[imin].regval))
+ + lookup->table[imin].realval;
+ } else if (agc_gain > lookup->table[0].regval)
+ rf_lvl = 5;
+ else if (agc_gain < lookup->table[lookup->size-1].regval)
+ rf_lvl = -100;
+
+ }
+
+ dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl);
+
+ return rf_lvl;
+}
+
+static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *internal = state->internal;
+ s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
+ state->demod);
+
+ *strength = (rflevel + 100) * (16383 / 105);
+
+ return 0;
+}
+
+
+static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
+ const struct stv0900_table *lookup)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 c_n = -100,
+ regval, imin, imax,
+ i,
+ lock_flag_field,
+ noise_field1,
+ noise_field0;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF,
+ F0900_P2_LOCK_DEFINITIF);
+ if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
+ dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1,
+ F0900_P2_NOSPLHT_NORMED1);
+ dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0,
+ F0900_P2_NOSPLHT_NORMED0);
+ } else {
+ dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1,
+ F0900_P2_NOSDATAT_NORMED1);
+ dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0,
+ F0900_P2_NOSDATAT_NORMED0);
+ }
+
+ if (stv0900_get_bits(i_params, lock_flag_field)) {
+ if ((lookup != NULL) && lookup->size) {
+ regval = 0;
+ msleep(5);
+ for (i = 0; i < 16; i++) {
+ regval += MAKEWORD(stv0900_get_bits(i_params,
+ noise_field1),
+ stv0900_get_bits(i_params,
+ noise_field0));
+ msleep(1);
+ }
+
+ regval /= 16;
+ imin = 0;
+ imax = lookup->size - 1;
+ if (INRANGE(lookup->table[imin].regval,
+ regval,
+ lookup->table[imax].regval)) {
+ while ((imax - imin) > 1) {
+ i = (imax + imin) >> 1;
+ if (INRANGE(lookup->table[imin].regval,
+ regval,
+ lookup->table[i].regval))
+ imax = i;
+ else
+ imin = i;
+ }
+
+ c_n = ((regval - lookup->table[imin].regval)
+ * (lookup->table[imax].realval
+ - lookup->table[imin].realval)
+ / (lookup->table[imax].regval
+ - lookup->table[imin].regval))
+ + lookup->table[imin].realval;
+ } else if (regval < lookup->table[imin].regval)
+ c_n = 1000;
+ }
+ }
+
+ return c_n;
+}
+
+static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ *snr = stv0900_carr_get_quality(fe,
+ (const struct stv0900_table *)&stv0900_s2_cn);
+ *snr += 30;
+ *snr *= (16383 / 1030);
+
+ return 0;
+}
+
+static u32 stv0900_get_ber(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 ber = 10000000, i;
+ s32 dmd_state_reg;
+ s32 demod_state;
+ s32 vstatus_reg;
+ s32 prvit_field;
+ s32 pdel_status_reg;
+ s32 pdel_lock_field;
+
+ dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT);
+ dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT);
+ dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1);
+ dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK,
+ F0900_P2_PKTDELIN_LOCK);
+
+ demod_state = stv0900_get_bits(i_params, dmd_state_reg);
+
+ switch (demod_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ ber = 10000000;
+ break;
+ case STV0900_DVBS_FOUND:
+ ber = 0;
+ for (i = 0; i < 5; i++) {
+ msleep(5);
+ ber += stv0900_get_err_count(i_params, 0, demod);
+ }
+
+ ber /= 5;
+ if (stv0900_get_bits(i_params, prvit_field)) {
+ ber *= 9766;
+ ber = ber >> 13;
+ }
+
+ break;
+ case STV0900_DVBS2_FOUND:
+ ber = 0;
+ for (i = 0; i < 5; i++) {
+ msleep(5);
+ ber += stv0900_get_err_count(i_params, 0, demod);
+ }
+
+ ber /= 5;
+ if (stv0900_get_bits(i_params, pdel_lock_field)) {
+ ber *= 9766;
+ ber = ber >> 13;
+ }
+
+ break;
+ }
+
+ return ber;
+}
+
+static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *internal = state->internal;
+
+ *ber = stv0900_get_ber(internal, state->demod);
+
+ return 0;
+}
+
+int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod, s32 time_out)
+{
+ s32 timer = 0,
+ lock = 0,
+ header_field,
+ lock_field;
+
+ enum fe_stv0900_search_state dmd_state;
+
+ dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
+ while ((timer < time_out) && (lock == 0)) {
+ dmd_state = stv0900_get_bits(i_params, header_field);
+ dprintk("Demod State = %d\n", dmd_state);
+ switch (dmd_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ lock = 0;
+ break;
+ case STV0900_DVBS2_FOUND:
+ case STV0900_DVBS_FOUND:
+ lock = stv0900_get_bits(i_params, lock_field);
+ break;
+ }
+
+ if (lock == 0)
+ msleep(10);
+
+ timer += 10;
+ }
+
+ if (lock)
+ dprintk("DEMOD LOCK OK\n");
+ else
+ dprintk("DEMOD LOCK FAIL\n");
+
+ return lock;
+}
+
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 regflist,
+ i;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0);
+
+ for (i = 0; i < 16; i++)
+ stv0900_write_reg(i_params, regflist + i, 0xff);
+}
+
+void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 matype,
+ mod_code,
+ fmod,
+ reg_index,
+ field_index;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id <= 0x11) {
+ msleep(5);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ mod_code = stv0900_read_reg(i_params,
+ R0900_P1_PLHMODCOD);
+ matype = mod_code & 0x3;
+ mod_code = (mod_code & 0x7f) >> 2;
+
+ reg_index = R0900_P1_MODCODLSTF - mod_code / 2;
+ field_index = mod_code % 2;
+ break;
+ case STV0900_DEMOD_2:
+ mod_code = stv0900_read_reg(i_params,
+ R0900_P2_PLHMODCOD);
+ matype = mod_code & 0x3;
+ mod_code = (mod_code & 0x7f) >> 2;
+
+ reg_index = R0900_P2_MODCODLSTF - mod_code / 2;
+ field_index = mod_code % 2;
+ break;
+ }
+
+
+ switch (matype) {
+ case 0:
+ default:
+ fmod = 14;
+ break;
+ case 1:
+ fmod = 13;
+ break;
+ case 2:
+ fmod = 11;
+ break;
+ case 3:
+ fmod = 7;
+ break;
+ }
+
+ if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
+ && (matype <= 1)) {
+ if (field_index == 0)
+ stv0900_write_reg(i_params, reg_index,
+ 0xf0 | fmod);
+ else
+ stv0900_write_reg(i_params, reg_index,
+ (fmod << 4) | 0xf);
+ }
+ } else if (i_params->chip_id >= 0x12) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ for (reg_index = 0; reg_index < 7; reg_index++)
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff);
+
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf);
+ for (reg_index = 0; reg_index < 8; reg_index++)
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc);
+
+ break;
+ case STV0900_DEMOD_2:
+ for (reg_index = 0; reg_index < 7; reg_index++)
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff);
+
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf);
+ for (reg_index = 0; reg_index < 8; reg_index++)
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc);
+
+ break;
+ }
+
+ }
+}
+
+void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 reg_index;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f);
+ for (reg_index = 0; reg_index < 13; reg_index++)
+ stv0900_write_reg(i_params,
+ R0900_P1_MODCODLST2 + reg_index, 0);
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f);
+ for (reg_index = 0; reg_index < 13; reg_index++)
+ stv0900_write_reg(i_params,
+ R0900_P2_MODCODLST2 + reg_index, 0);
+
+ break;
+ }
+}
+
+static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_CUSTOM;
+}
+
+static int stb0900_set_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk(KERN_INFO "%s(..)\n", __func__);
+
+ return 0;
+}
+
+static int stb0900_get_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk(KERN_INFO "%s(..)\n", __func__);
+
+ return 0;
+}
+
+void stv0900_start_search(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+
+ if (i_params->dmd1_symbol_rate <= 5000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44);
+ stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f);
+ stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
+
+ if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
+ if (i_params->chip_id >= 0x20) {
+ if (i_params->dmd1_symbol_rate < 2000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40);
+ }
+
+ if (i_params->dmd1_symbol_rate < 10000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
+ }
+
+ } else {
+ if (i_params->dmd1_symbol_rate < 10000000)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+ }
+
+ switch (i_params->dmd1_srch_algo) {
+ case STV0900_WARM_START:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ break;
+ case STV0900_COLD_START:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f);
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+ if (i_params->dmd2_symbol_rate <= 5000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44);
+ stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f);
+ stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
+ if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
+ if (i_params->chip_id >= 0x20) {
+ if (i_params->dmd2_symbol_rate < 2000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40);
+ }
+
+ if (i_params->dmd2_symbol_rate < 10000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
+ }
+
+ } else {
+ if (i_params->dmd2_symbol_rate < 10000000)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+ }
+
+ switch (i_params->dmd2_srch_algo) {
+ case STV0900_WARM_START:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ break;
+ case STV0900_COLD_START:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+}
+
+u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
+ s32 pilot, u8 chip_id)
+{
+ u8 aclc_value = 0x29;
+ s32 i;
+ const struct stv0900_car_loop_optim *car_loop_s2;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (chip_id <= 0x12)
+ car_loop_s2 = FE_STV0900_S2CarLoop;
+ else if (chip_id == 0x20)
+ car_loop_s2 = FE_STV0900_S2CarLoopCut20;
+ else
+ car_loop_s2 = FE_STV0900_S2CarLoop;
+
+ if (modcode < STV0900_QPSK_12) {
+ i = 0;
+ while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode))
+ i++;
+
+ if (i >= 3)
+ i = 2;
+ } else {
+ i = 0;
+ while ((i < 14) && (modcode != car_loop_s2[i].modcode))
+ i++;
+
+ if (i >= 14) {
+ i = 0;
+ while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode))
+ i++;
+
+ if (i >= 11)
+ i = 10;
+ }
+ }
+
+ if (modcode <= STV0900_QPSK_25) {
+ if (pilot) {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20;
+ else
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30;
+ } else {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20;
+ else
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30;
+ }
+
+ } else if (modcode <= STV0900_8PSK_910) {
+ if (pilot) {
+ if (srate <= 3000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_20;
+ else
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_30;
+ } else {
+ if (srate <= 3000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_2;
+ else if (srate <= 7000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_5;
+ else if (srate <= 15000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_10;
+ else if (srate <= 25000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_20;
+ else
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_30;
+ }
+
+ } else {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20;
+ else
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30;
+ }
+
+ return aclc_value;
+}
+
+u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id)
+{
+ s32 mod_index = 0;
+
+ u8 aclc_value = 0x0b;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (modulation) {
+ case STV0900_QPSK:
+ default:
+ mod_index = 0;
+ break;
+ case STV0900_8PSK:
+ mod_index = 1;
+ break;
+ case STV0900_16APSK:
+ mod_index = 2;
+ break;
+ case STV0900_32APSK:
+ mod_index = 3;
+ break;
+ }
+
+ switch (chip_id) {
+ case 0x20:
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20;
+ else
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30;
+
+ break;
+ case 0x12:
+ default:
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20;
+ else
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30;
+
+ break;
+ }
+
+ return aclc_value;
+}
+
+static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_mode LDPC_Mode,
+ enum fe_stv0900_demod_num demod)
+{
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (LDPC_Mode) {
+ case STV0900_DUAL:
+ default:
+ if ((i_params->demod_mode != STV0900_DUAL)
+ || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) {
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x1d);
+
+ i_params->demod_mode = STV0900_DUAL;
+
+ stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+ stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+ }
+
+ break;
+ case STV0900_SINGLE:
+ if (demod == STV0900_DEMOD_2)
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x06);
+ else
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x04);
+
+ i_params->demod_mode = STV0900_SINGLE;
+
+ stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+ stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+ break;
+ }
+
+ return error;
+}
+
+static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
+ struct stv0900_init_params *p_init)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+ enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+ int selosci;
+
+ struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
+ state->config->demod_address);
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (temp_int != NULL) {
+ state->internal = temp_int->internal;
+ (state->internal->dmds_used)++;
+ dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__);
+ return STV0900_NO_ERROR;
+ } else {
+ state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL);
+ temp_int = append_internal(state->internal);
+ state->internal->dmds_used = 1;
+ state->internal->i2c_adap = state->i2c_adap;
+ state->internal->i2c_addr = state->config->demod_address;
+ state->internal->clkmode = state->config->clkmode;
+ state->internal->errs = STV0900_NO_ERROR;
+ dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__);
+ }
+
+ if (state->internal != NULL) {
+ demodError = stv0900_initialize(state->internal);
+ if (demodError == STV0900_NO_ERROR) {
+ error = STV0900_NO_ERROR;
+ } else {
+ if (demodError == STV0900_INVALID_HANDLE)
+ error = STV0900_INVALID_HANDLE;
+ else
+ error = STV0900_I2C_ERROR;
+ }
+
+ if (state->internal != NULL) {
+ if (error == STV0900_NO_ERROR) {
+ state->internal->demod_mode = p_init->demod_mode;
+
+ stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1);
+
+ state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID);
+ state->internal->rolloff = p_init->rolloff;
+ state->internal->quartz = p_init->dmd_ref_clk;
+
+ stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+ stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+
+ stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock);
+ stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
+ switch (p_init->tuner1_adc) {
+ case 1:
+ stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
+ switch (p_init->tuner2_adc) {
+ case 1:
+ stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion);
+ stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion);
+ stv0900_set_mclk(state->internal, 135000000);
+ msleep(3);
+
+ switch (state->internal->clkmode) {
+ case 0:
+ case 2:
+ stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode);
+ break;
+ default:
+ selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL);
+ stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci);
+ break;
+ }
+ msleep(3);
+
+ state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz);
+ if (state->internal->errs)
+ error = STV0900_I2C_ERROR;
+ }
+ } else {
+ error = STV0900_INVALID_HANDLE;
+ }
+ }
+
+ return error;
+}
+
+static int stv0900_status(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ enum fe_stv0900_search_state demod_state;
+ s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field;
+ int locked = FALSE;
+
+ dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
+ dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
+ dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+ dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+
+ demod_state = stv0900_get_bits(i_params, mode_field);
+ switch (demod_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ locked = FALSE;
+ break;
+ case STV0900_DVBS2_FOUND:
+ locked = stv0900_get_bits(i_params, lock_field) &&
+ stv0900_get_bits(i_params, delin_field) &&
+ stv0900_get_bits(i_params, fifo_field);
+ break;
+ case STV0900_DVBS_FOUND:
+ locked = stv0900_get_bits(i_params, lock_field) &&
+ stv0900_get_bits(i_params, lockedvit_field) &&
+ stv0900_get_bits(i_params, fifo_field);
+ break;
+ }
+
+ return locked;
+}
+
+static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ struct stv0900_search_params p_search;
+ struct stv0900_signal_info p_result;
+
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+ dprintk(KERN_INFO "%s: ", __func__);
+
+ p_result.locked = FALSE;
+ p_search.path = state->demod;
+ p_search.frequency = c->frequency;
+ p_search.symbol_rate = c->symbol_rate;
+ p_search.search_range = 10000000;
+ p_search.fec = STV0900_FEC_UNKNOWN;
+ p_search.standard = STV0900_AUTO_SEARCH;
+ p_search.iq_inversion = STV0900_IQ_AUTO;
+ p_search.search_algo = STV0900_BLIND_SEARCH;
+
+ if ((INRANGE(100000, p_search.symbol_rate, 70000000)) &&
+ (INRANGE(100000, p_search.search_range, 50000000))) {
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_srch_standard = p_search.standard;
+ i_params->dmd1_symbol_rate = p_search.symbol_rate;
+ i_params->dmd1_srch_range = p_search.search_range;
+ i_params->tuner1_freq = p_search.frequency;
+ i_params->dmd1_srch_algo = p_search.search_algo;
+ i_params->dmd1_srch_iq_inv = p_search.iq_inversion;
+ i_params->dmd1_fec = p_search.fec;
+ break;
+
+ case STV0900_DEMOD_2:
+ i_params->dmd2_srch_stndrd = p_search.standard;
+ i_params->dmd2_symbol_rate = p_search.symbol_rate;
+ i_params->dmd2_srch_range = p_search.search_range;
+ i_params->tuner2_freq = p_search.frequency;
+ i_params->dmd2_srch_algo = p_search.search_algo;
+ i_params->dmd2_srch_iq_inv = p_search.iq_inversion;
+ i_params->dmd2_fec = p_search.fec;
+ break;
+ }
+
+ if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
+ (i_params->errs == STV0900_NO_ERROR)) {
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ default:
+ p_result.locked = i_params->dmd1_rslts.locked;
+ p_result.standard = i_params->dmd1_rslts.standard;
+ p_result.frequency = i_params->dmd1_rslts.frequency;
+ p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate;
+ p_result.fec = i_params->dmd1_rslts.fec;
+ p_result.modcode = i_params->dmd1_rslts.modcode;
+ p_result.pilot = i_params->dmd1_rslts.pilot;
+ p_result.frame_length = i_params->dmd1_rslts.frame_length;
+ p_result.spectrum = i_params->dmd1_rslts.spectrum;
+ p_result.rolloff = i_params->dmd1_rslts.rolloff;
+ p_result.modulation = i_params->dmd1_rslts.modulation;
+ break;
+ case STV0900_DEMOD_2:
+ p_result.locked = i_params->dmd2_rslts.locked;
+ p_result.standard = i_params->dmd2_rslts.standard;
+ p_result.frequency = i_params->dmd2_rslts.frequency;
+ p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate;
+ p_result.fec = i_params->dmd2_rslts.fec;
+ p_result.modcode = i_params->dmd2_rslts.modcode;
+ p_result.pilot = i_params->dmd2_rslts.pilot;
+ p_result.frame_length = i_params->dmd2_rslts.frame_length;
+ p_result.spectrum = i_params->dmd2_rslts.spectrum;
+ p_result.rolloff = i_params->dmd2_rslts.rolloff;
+ p_result.modulation = i_params->dmd2_rslts.modulation;
+ break;
+ }
+
+ } else {
+ p_result.locked = FALSE;
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ switch (i_params->dmd1_err) {
+ case STV0900_I2C_ERROR:
+ error = STV0900_I2C_ERROR;
+ break;
+ case STV0900_NO_ERROR:
+ default:
+ error = STV0900_SEARCH_FAILED;
+ break;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_err) {
+ case STV0900_I2C_ERROR:
+ error = STV0900_I2C_ERROR;
+ break;
+ case STV0900_NO_ERROR:
+ default:
+ error = STV0900_SEARCH_FAILED;
+ break;
+ }
+ break;
+ }
+ }
+
+ } else
+ error = STV0900_BAD_PARAMETER;
+
+ if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
+ dprintk(KERN_INFO "Search Success\n");
+ return DVBFE_ALGO_SEARCH_SUCCESS;
+ } else {
+ dprintk(KERN_INFO "Search Fail\n");
+ return DVBFE_ALGO_SEARCH_FAILED;
+ }
+
+ return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ dprintk("%s: ", __func__);
+
+ if ((stv0900_status(state->internal, state->demod)) == TRUE) {
+ dprintk("DEMOD LOCK OK\n");
+ *status = FE_HAS_CARRIER
+ | FE_HAS_VITERBI
+ | FE_HAS_SYNC
+ | FE_HAS_LOCK;
+ } else
+ dprintk("DEMOD LOCK FAIL\n");
+
+ return 0;
+}
+
+static int stv0900_track(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ return 0;
+}
+
+static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
+{
+
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 rst_field;
+
+ dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
+
+ if (stop_ts == TRUE)
+ stv0900_write_bits(i_params, rst_field, 1);
+ else
+ stv0900_write_bits(i_params, rst_field, 0);
+
+ return 0;
+}
+
+static int stv0900_diseqc_init(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field, reset_field;
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+
+ stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode);
+ stv0900_write_bits(i_params, reset_field, 1);
+ stv0900_write_bits(i_params, reset_field, 0);
+
+ return 0;
+}
+
+static int stv0900_init(struct dvb_frontend *fe)
+{
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ stv0900_stop_ts(fe, 1);
+ stv0900_diseqc_init(fe);
+
+ return 0;
+}
+
+static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data,
+ u32 NbData, enum fe_stv0900_demod_num demod)
+{
+ s32 i = 0;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1);
+ while (i < NbData) {
+ while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL))
+ ;/* checkpatch complains */
+ stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]);
+ i++;
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0);
+ i = 0;
+ while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1);
+
+ while (i < NbData) {
+ while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL))
+ ;/* checkpatch complains */
+ stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]);
+ i++;
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0);
+ i = 0;
+ while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ return stv0900_diseqc_send(state->internal,
+ cmd->msg,
+ cmd->msg_len,
+ state->demod);
+}
+
+static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field;
+ u32 diseqc_fifo;
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA);
+
+ switch (burst) {
+ case SEC_MINI_A:
+ stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */
+ stv0900_write_reg(i_params, diseqc_fifo, 0x00);
+ break;
+ case SEC_MINI_B:
+ stv0900_write_bits(i_params, mode_field, 2);/* Modulated */
+ stv0900_write_reg(i_params, diseqc_fifo, 0xff);
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
+ struct dvb_diseqc_slave_reply *reply)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ s32 i = 0;
+
+ switch (state->demod) {
+ case STV0900_DEMOD_1:
+ default:
+ reply->msg_len = 0;
+
+ while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ if (stv0900_get_bits(i_params, F0900_P1_RX_END)) {
+ reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR);
+
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ reply->msg_len = 0;
+
+ while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ if (stv0900_get_bits(i_params, F0900_P2_RX_END)) {
+ reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR);
+
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field, reset_field;
+
+ dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On"));
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+
+ if (tone) {
+ /*Set the DiseqC mode to 22Khz continues tone*/
+ stv0900_write_bits(i_params, mode_field, 0);
+ stv0900_write_bits(i_params, reset_field, 1);
+ /*release DiseqC reset to enable the 22KHz tone*/
+ stv0900_write_bits(i_params, reset_field, 0);
+ } else {
+ stv0900_write_bits(i_params, mode_field, 0);
+ /*maintain the DiseqC reset to disable the 22KHz tone*/
+ stv0900_write_bits(i_params, reset_field, 1);
+ }
+
+ return 0;
+}
+
+static void stv0900_release(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if ((--(state->internal->dmds_used)) <= 0) {
+
+ dprintk(KERN_INFO "%s: Actually removing\n", __func__);
+
+ remove_inode(state->internal);
+ kfree(state->internal);
+ }
+
+ kfree(state);
+}
+
+static struct dvb_frontend_ops stv0900_ops = {
+
+ .info = {
+ .name = "STV0900 frontend",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 125,
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500,
+ .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_2G_MODULATION |
+ FE_CAN_FEC_AUTO
+ },
+ .release = stv0900_release,
+ .init = stv0900_init,
+ .get_frontend_algo = stv0900_frontend_algo,
+ .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
+ .diseqc_send_master_cmd = stv0900_send_master_cmd,
+ .diseqc_send_burst = stv0900_send_burst,
+ .diseqc_recv_slave_reply = stv0900_recv_slave_reply,
+ .set_tone = stv0900_set_tone,
+ .set_property = stb0900_set_property,
+ .get_property = stb0900_get_property,
+ .search = stv0900_search,
+ .track = stv0900_track,
+ .read_status = stv0900_read_status,
+ .read_ber = stv0900_read_ber,
+ .read_signal_strength = stv0900_read_signal_strength,
+ .read_snr = stv0900_read_snr,
+};
+
+struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c,
+ int demod)
+{
+ struct stv0900_state *state = NULL;
+ struct stv0900_init_params init_params;
+ enum fe_stv0900_error err_stv0900;
+
+ state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ state->demod = demod;
+ state->config = config;
+ state->i2c_adap = i2c;
+
+ memcpy(&state->frontend.ops, &stv0900_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ switch (demod) {
+ case 0:
+ case 1:
+ init_params.dmd_ref_clk = config->xtal;
+ init_params.demod_mode = STV0900_DUAL;
+ init_params.rolloff = STV0900_35;
+ init_params.path1_ts_clock = config->path1_mode;
+ init_params.tun1_maddress = config->tun1_maddress;
+ init_params.tun1_iq_inversion = STV0900_IQ_NORMAL;
+ init_params.tuner1_adc = config->tun1_adc;
+ init_params.path2_ts_clock = config->path2_mode;
+ init_params.tun2_maddress = config->tun2_maddress;
+ init_params.tuner2_adc = config->tun2_adc;
+ init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED;
+
+ err_stv0900 = stv0900_init_internal(&state->frontend,
+ &init_params);
+
+ if (err_stv0900)
+ goto error;
+
+ break;
+ default:
+ goto error;
+ break;
+ }
+
+ dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
+ return &state->frontend;
+
+error:
+ dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
+ __func__, demod);
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(stv0900_attach);
+
+MODULE_PARM_DESC(debug, "Set debug");
+
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_DESCRIPTION("ST STV0900 frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
new file mode 100644
index 00000000000..ff388b47a4e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_init.h
@@ -0,0 +1,441 @@
+/*
+ * stv0900_init.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 STV0900_INIT_H
+#define STV0900_INIT_H
+
+#include "stv0900_priv.h"
+
+/* DVBS2 C/N Look-Up table */
+static const struct stv0900_table stv0900_s2_cn = {
+ 55,
+ {
+ { -30, 13348 }, /*C/N=-3dB*/
+ { -20, 12640 }, /*C/N=-2dB*/
+ { -10, 11883 }, /*C/N=-1dB*/
+ { 0, 11101 }, /*C/N=-0dB*/
+ { 5, 10718 }, /*C/N=0.5dB*/
+ { 10, 10339 }, /*C/N=1.0dB*/
+ { 15, 9947 }, /*C/N=1.5dB*/
+ { 20, 9552 }, /*C/N=2.0dB*/
+ { 25, 9183 }, /*C/N=2.5dB*/
+ { 30, 8799 }, /*C/N=3.0dB*/
+ { 35, 8422 }, /*C/N=3.5dB*/
+ { 40, 8062 }, /*C/N=4.0dB*/
+ { 45, 7707 }, /*C/N=4.5dB*/
+ { 50, 7353 }, /*C/N=5.0dB*/
+ { 55, 7025 }, /*C/N=5.5dB*/
+ { 60, 6684 }, /*C/N=6.0dB*/
+ { 65, 6331 }, /*C/N=6.5dB*/
+ { 70, 6036 }, /*C/N=7.0dB*/
+ { 75, 5727 }, /*C/N=7.5dB*/
+ { 80, 5437 }, /*C/N=8.0dB*/
+ { 85, 5164 }, /*C/N=8.5dB*/
+ { 90, 4902 }, /*C/N=9.0dB*/
+ { 95, 4653 }, /*C/N=9.5dB*/
+ { 100, 4408 }, /*C/N=10.0dB*/
+ { 105, 4187 }, /*C/N=10.5dB*/
+ { 110, 3961 }, /*C/N=11.0dB*/
+ { 115, 3751 }, /*C/N=11.5dB*/
+ { 120, 3558 }, /*C/N=12.0dB*/
+ { 125, 3368 }, /*C/N=12.5dB*/
+ { 130, 3191 }, /*C/N=13.0dB*/
+ { 135, 3017 }, /*C/N=13.5dB*/
+ { 140, 2862 }, /*C/N=14.0dB*/
+ { 145, 2710 }, /*C/N=14.5dB*/
+ { 150, 2565 }, /*C/N=15.0dB*/
+ { 160, 2300 }, /*C/N=16.0dB*/
+ { 170, 2058 }, /*C/N=17.0dB*/
+ { 180, 1849 }, /*C/N=18.0dB*/
+ { 190, 1663 }, /*C/N=19.0dB*/
+ { 200, 1495 }, /*C/N=20.0dB*/
+ { 210, 1349 }, /*C/N=21.0dB*/
+ { 220, 1222 }, /*C/N=22.0dB*/
+ { 230, 1110 }, /*C/N=23.0dB*/
+ { 240, 1011 }, /*C/N=24.0dB*/
+ { 250, 925 }, /*C/N=25.0dB*/
+ { 260, 853 }, /*C/N=26.0dB*/
+ { 270, 789 }, /*C/N=27.0dB*/
+ { 280, 734 }, /*C/N=28.0dB*/
+ { 290, 690 }, /*C/N=29.0dB*/
+ { 300, 650 }, /*C/N=30.0dB*/
+ { 310, 619 }, /*C/N=31.0dB*/
+ { 320, 593 }, /*C/N=32.0dB*/
+ { 330, 571 }, /*C/N=33.0dB*/
+ { 400, 498 }, /*C/N=40.0dB*/
+ { 450, 484 }, /*C/N=45.0dB*/
+ { 500, 481 } /*C/N=50.0dB*/
+ }
+};
+
+/* RF level C/N Look-Up table */
+static const struct stv0900_table stv0900_rf = {
+ 14,
+ {
+ { -5, 0xCAA1 }, /*-5dBm*/
+ { -10, 0xC229 }, /*-10dBm*/
+ { -15, 0xBB08 }, /*-15dBm*/
+ { -20, 0xB4BC }, /*-20dBm*/
+ { -25, 0xAD5A }, /*-25dBm*/
+ { -30, 0xA298 }, /*-30dBm*/
+ { -35, 0x98A8 }, /*-35dBm*/
+ { -40, 0x8389 }, /*-40dBm*/
+ { -45, 0x59BE }, /*-45dBm*/
+ { -50, 0x3A14 }, /*-50dBm*/
+ { -55, 0x2D11 }, /*-55dBm*/
+ { -60, 0x210D }, /*-60dBm*/
+ { -65, 0xA14F }, /*-65dBm*/
+ { -70, 0x7AA } /*-70dBm*/
+ }
+};
+
+struct stv0900_car_loop_optim {
+ enum fe_stv0900_modcode modcode;
+ u8 car_loop_pilots_on_2;
+ u8 car_loop_pilots_off_2;
+ u8 car_loop_pilots_on_5;
+ u8 car_loop_pilots_off_5;
+ u8 car_loop_pilots_on_10;
+ u8 car_loop_pilots_off_10;
+ u8 car_loop_pilots_on_20;
+ u8 car_loop_pilots_off_20;
+ u8 car_loop_pilots_on_30;
+ u8 car_loop_pilots_off_30;
+
+};
+
+struct stv0900_short_frames_car_loop_optim {
+ enum fe_stv0900_modulation modulation;
+ u8 car_loop_cut12_2; /* Cut 1.2, SR<=3msps */
+ u8 car_loop_cut20_2; /* Cut 2.0, SR<3msps */
+ u8 car_loop_cut12_5; /* Cut 1.2, 3<SR<=7msps */
+ u8 car_loop_cut20_5; /* Cut 2.0, 3<SR<=7msps */
+ u8 car_loop_cut12_10; /* Cut 1.2, 7<SR<=15msps */
+ u8 car_loop_cut20_10; /* Cut 2.0, 7<SR<=15msps */
+ u8 car_loop_cut12_20; /* Cut 1.2, 10<SR<=25msps */
+ u8 car_loop_cut20_20; /* Cut 2.0, 10<SR<=25msps */
+ u8 car_loop_cut12_30; /* Cut 1.2, 25<SR<=45msps */
+ u8 car_loop_cut20_30; /* Cut 2.0, 10<SR<=45msps */
+
+};
+
+/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A, 0x1C, 0x2A, 0x3B, 0x2A, 0x1B },
+ { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, 0x2A, 0x0B },
+ { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B, 0x0C, 0x3A, 0x1B, 0x2A, 0x3A },
+ { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38, 0x0B, 0x18, 0x1A, 0x08, 0x0A },
+ { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19, 0x0B, 0x38, 0x1A, 0x18, 0x0A },
+ { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39, 0x0B, 0x19, 0x1A, 0x38, 0x0A },
+ { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A, 0x0B, 0x39, 0x1A, 0x19, 0x0A },
+ { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 },
+ { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x1E },
+ { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D, 0x0F, 0x0E, 0x2E, 0x3D, 0x0E },
+ { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E, 0x0F, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c, 0x3b, 0x2b, 0x2b, 0x1b, 0x2b },
+ { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x3b, 0x0c, 0x2b, 0x2b, 0x2b },
+ { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d, 0x3b, 0x2c, 0x3b, 0x0c, 0x2b },
+ { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
+ { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
+ { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
+};
+
+
+
+/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x0C, 0x3C, 0x0C, 0x2C, 0x0C },
+ { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0C, 0x2D, 0x0C, 0x1D, 0x0C },
+ { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
+ { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
+ { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
+ { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
+ { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x2D, 0x1F, 0x3D, 0x3E },
+ { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x3D, 0x0F, 0x3D, 0x2E },
+ { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x2E }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */
+static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
+ /*Mod 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */
+ { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B, 0x0E, 0x3A, 0x0E, 0x2A, 0x3D },
+ { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A, 0x2D, 0x19, 0x0D, 0x09, 0x3C },
+ { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D },
+ { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }
+};
+
+static const u16 STV0900_InitVal[182][2] = {
+ { R0900_OUTCFG , 0x00 },
+ { R0900_MODECFG , 0xff },
+ { R0900_AGCRF1CFG , 0x11 },
+ { R0900_AGCRF2CFG , 0x13 },
+ { R0900_TSGENERAL1X , 0x14 },
+ { R0900_TSTTNR2 , 0x21 },
+ { R0900_TSTTNR4 , 0x21 },
+ { R0900_P2_DISTXCTL , 0x22 },
+ { R0900_P2_F22TX , 0xc0 },
+ { R0900_P2_F22RX , 0xc0 },
+ { R0900_P2_DISRXCTL , 0x00 },
+ { R0900_P2_TNRSTEPS , 0x87 },
+ { R0900_P2_TNRGAIN , 0x09 },
+ { R0900_P2_DMDCFGMD , 0xF9 },
+ { R0900_P2_DEMOD , 0x08 },
+ { R0900_P2_DMDCFG3 , 0xc4 },
+ { R0900_P2_CARFREQ , 0xed },
+ { R0900_P2_TNRCFG2 , 0x02 },
+ { R0900_P2_TNRCFG3 , 0x02 },
+ { R0900_P2_LDT , 0xd0 },
+ { R0900_P2_LDT2 , 0xb8 },
+ { R0900_P2_TMGCFG , 0xd2 },
+ { R0900_P2_TMGTHRISE , 0x20 },
+ { R0900_P2_TMGTHFALL , 0x00 },
+ { R0900_P2_FECSPY , 0x88 },
+ { R0900_P2_FSPYDATA , 0x3a },
+ { R0900_P2_FBERCPT4 , 0x00 },
+ { R0900_P2_FSPYBER , 0x10 },
+ { R0900_P2_ERRCTRL1 , 0x35 },
+ { R0900_P2_ERRCTRL2 , 0xc1 },
+ { R0900_P2_CFRICFG , 0xf8 },
+ { R0900_P2_NOSCFG , 0x1c },
+ { R0900_P2_DMDT0M , 0x20 },
+ { R0900_P2_CORRELMANT , 0x70 },
+ { R0900_P2_CORRELABS , 0x88 },
+ { R0900_P2_AGC2O , 0x5b },
+ { R0900_P2_AGC2REF , 0x38 },
+ { R0900_P2_CARCFG , 0xe4 },
+ { R0900_P2_ACLC , 0x1A },
+ { R0900_P2_BCLC , 0x09 },
+ { R0900_P2_CARHDR , 0x08 },
+ { R0900_P2_KREFTMG , 0xc1 },
+ { R0900_P2_SFRUPRATIO , 0xf0 },
+ { R0900_P2_SFRLOWRATIO , 0x70 },
+ { R0900_P2_SFRSTEP , 0x58 },
+ { R0900_P2_TMGCFG2 , 0x01 },
+ { R0900_P2_CAR2CFG , 0x26 },
+ { R0900_P2_BCLC2S2Q , 0x86 },
+ { R0900_P2_BCLC2S28 , 0x86 },
+ { R0900_P2_SMAPCOEF7 , 0x77 },
+ { R0900_P2_SMAPCOEF6 , 0x85 },
+ { R0900_P2_SMAPCOEF5 , 0x77 },
+ { R0900_P2_TSCFGL , 0x20 },
+ { R0900_P2_DMDCFG2 , 0x3b },
+ { R0900_P2_MODCODLST0 , 0xff },
+ { R0900_P2_MODCODLST1 , 0xff },
+ { R0900_P2_MODCODLST2 , 0xff },
+ { R0900_P2_MODCODLST3 , 0xff },
+ { R0900_P2_MODCODLST4 , 0xff },
+ { R0900_P2_MODCODLST5 , 0xff },
+ { R0900_P2_MODCODLST6 , 0xff },
+ { R0900_P2_MODCODLST7 , 0xcc },
+ { R0900_P2_MODCODLST8 , 0xcc },
+ { R0900_P2_MODCODLST9 , 0xcc },
+ { R0900_P2_MODCODLSTA , 0xcc },
+ { R0900_P2_MODCODLSTB , 0xcc },
+ { R0900_P2_MODCODLSTC , 0xcc },
+ { R0900_P2_MODCODLSTD , 0xcc },
+ { R0900_P2_MODCODLSTE , 0xcc },
+ { R0900_P2_MODCODLSTF , 0xcf },
+ { R0900_P1_DISTXCTL , 0x22 },
+ { R0900_P1_F22TX , 0xc0 },
+ { R0900_P1_F22RX , 0xc0 },
+ { R0900_P1_DISRXCTL , 0x00 },
+ { R0900_P1_TNRSTEPS , 0x87 },
+ { R0900_P1_TNRGAIN , 0x09 },
+ { R0900_P1_DMDCFGMD , 0xf9 },
+ { R0900_P1_DEMOD , 0x08 },
+ { R0900_P1_DMDCFG3 , 0xc4 },
+ { R0900_P1_DMDT0M , 0x20 },
+ { R0900_P1_CARFREQ , 0xed },
+ { R0900_P1_TNRCFG2 , 0x82 },
+ { R0900_P1_TNRCFG3 , 0x02 },
+ { R0900_P1_LDT , 0xd0 },
+ { R0900_P1_LDT2 , 0xb8 },
+ { R0900_P1_TMGCFG , 0xd2 },
+ { R0900_P1_TMGTHRISE , 0x20 },
+ { R0900_P1_TMGTHFALL , 0x00 },
+ { R0900_P1_SFRUPRATIO , 0xf0 },
+ { R0900_P1_SFRLOWRATIO , 0x70 },
+ { R0900_P1_TSCFGL , 0x20 },
+ { R0900_P1_FECSPY , 0x88 },
+ { R0900_P1_FSPYDATA , 0x3a },
+ { R0900_P1_FBERCPT4 , 0x00 },
+ { R0900_P1_FSPYBER , 0x10 },
+ { R0900_P1_ERRCTRL1 , 0x35 },
+ { R0900_P1_ERRCTRL2 , 0xc1 },
+ { R0900_P1_CFRICFG , 0xf8 },
+ { R0900_P1_NOSCFG , 0x1c },
+ { R0900_P1_CORRELMANT , 0x70 },
+ { R0900_P1_CORRELABS , 0x88 },
+ { R0900_P1_AGC2O , 0x5b },
+ { R0900_P1_AGC2REF , 0x38 },
+ { R0900_P1_CARCFG , 0xe4 },
+ { R0900_P1_ACLC , 0x1A },
+ { R0900_P1_BCLC , 0x09 },
+ { R0900_P1_CARHDR , 0x08 },
+ { R0900_P1_KREFTMG , 0xc1 },
+ { R0900_P1_SFRSTEP , 0x58 },
+ { R0900_P1_TMGCFG2 , 0x01 },
+ { R0900_P1_CAR2CFG , 0x26 },
+ { R0900_P1_BCLC2S2Q , 0x86 },
+ { R0900_P1_BCLC2S28 , 0x86 },
+ { R0900_P1_SMAPCOEF7 , 0x77 },
+ { R0900_P1_SMAPCOEF6 , 0x85 },
+ { R0900_P1_SMAPCOEF5 , 0x77 },
+ { R0900_P1_DMDCFG2 , 0x3b },
+ { R0900_P1_MODCODLST0 , 0xff },
+ { R0900_P1_MODCODLST1 , 0xff },
+ { R0900_P1_MODCODLST2 , 0xff },
+ { R0900_P1_MODCODLST3 , 0xff },
+ { R0900_P1_MODCODLST4 , 0xff },
+ { R0900_P1_MODCODLST5 , 0xff },
+ { R0900_P1_MODCODLST6 , 0xff },
+ { R0900_P1_MODCODLST7 , 0xcc },
+ { R0900_P1_MODCODLST8 , 0xcc },
+ { R0900_P1_MODCODLST9 , 0xcc },
+ { R0900_P1_MODCODLSTA , 0xcc },
+ { R0900_P1_MODCODLSTB , 0xcc },
+ { R0900_P1_MODCODLSTC , 0xcc },
+ { R0900_P1_MODCODLSTD , 0xcc },
+ { R0900_P1_MODCODLSTE , 0xcc },
+ { R0900_P1_MODCODLSTF , 0xcf },
+ { R0900_GENCFG , 0x1d },
+ { R0900_NBITER_NF4 , 0x37 },
+ { R0900_NBITER_NF5 , 0x29 },
+ { R0900_NBITER_NF6 , 0x37 },
+ { R0900_NBITER_NF7 , 0x33 },
+ { R0900_NBITER_NF8 , 0x31 },
+ { R0900_NBITER_NF9 , 0x2f },
+ { R0900_NBITER_NF10 , 0x39 },
+ { R0900_NBITER_NF11 , 0x3a },
+ { R0900_NBITER_NF12 , 0x29 },
+ { R0900_NBITER_NF13 , 0x37 },
+ { R0900_NBITER_NF14 , 0x33 },
+ { R0900_NBITER_NF15 , 0x2f },
+ { R0900_NBITER_NF16 , 0x39 },
+ { R0900_NBITER_NF17 , 0x3a },
+ { R0900_NBITERNOERR , 0x04 },
+ { R0900_GAINLLR_NF4 , 0x0C },
+ { R0900_GAINLLR_NF5 , 0x0F },
+ { R0900_GAINLLR_NF6 , 0x11 },
+ { R0900_GAINLLR_NF7 , 0x14 },
+ { R0900_GAINLLR_NF8 , 0x17 },
+ { R0900_GAINLLR_NF9 , 0x19 },
+ { R0900_GAINLLR_NF10 , 0x20 },
+ { R0900_GAINLLR_NF11 , 0x21 },
+ { R0900_GAINLLR_NF12 , 0x0D },
+ { R0900_GAINLLR_NF13 , 0x0F },
+ { R0900_GAINLLR_NF14 , 0x13 },
+ { R0900_GAINLLR_NF15 , 0x1A },
+ { R0900_GAINLLR_NF16 , 0x1F },
+ { R0900_GAINLLR_NF17 , 0x21 },
+ { R0900_RCCFGH , 0x20 },
+ { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/
+ { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/
+ { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
+ { R0900_P2_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
+ { R0900_STROUT1CFG , 0x4c },
+ { R0900_STROUT2CFG , 0x4c },
+ { R0900_CLKOUT1CFG , 0x50 },
+ { R0900_CLKOUT2CFG , 0x50 },
+ { R0900_DPN1CFG , 0x4a },
+ { R0900_DPN2CFG , 0x4a },
+ { R0900_DATA71CFG , 0x52 },
+ { R0900_DATA72CFG , 0x52 },
+ { R0900_P1_TSCFGM , 0xc0 },
+ { R0900_P2_TSCFGM , 0xc0 },
+ { R0900_P1_TSCFGH , 0xe0 }, /* DVB-CI timings */
+ { R0900_P2_TSCFGH , 0xe0 }, /* DVB-CI timings */
+ { R0900_P1_TSSPEED , 0x40 },
+ { R0900_P2_TSSPEED , 0x40 },
+};
+
+static const u16 STV0900_Cut20_AddOnVal[32][2] = {
+ { R0900_P2_DMDCFG3 , 0xe8 },
+ { R0900_P2_DMDCFG4 , 0x10 },
+ { R0900_P2_CARFREQ , 0x38 },
+ { R0900_P2_CARHDR , 0x20 },
+ { R0900_P2_KREFTMG , 0x5a },
+ { R0900_P2_SMAPCOEF7 , 0x06 },
+ { R0900_P2_SMAPCOEF6 , 0x00 },
+ { R0900_P2_SMAPCOEF5 , 0x04 },
+ { R0900_P2_NOSCFG , 0x0c },
+ { R0900_P1_DMDCFG3 , 0xe8 },
+ { R0900_P1_DMDCFG4 , 0x10 },
+ { R0900_P1_CARFREQ , 0x38 },
+ { R0900_P1_CARHDR , 0x20 },
+ { R0900_P1_KREFTMG , 0x5a },
+ { R0900_P1_SMAPCOEF7 , 0x06 },
+ { R0900_P1_SMAPCOEF6 , 0x00 },
+ { R0900_P1_SMAPCOEF5 , 0x04 },
+ { R0900_P1_NOSCFG , 0x0c },
+ { R0900_GAINLLR_NF4 , 0x21 },
+ { R0900_GAINLLR_NF5 , 0x21 },
+ { R0900_GAINLLR_NF6 , 0x20 },
+ { R0900_GAINLLR_NF7 , 0x1F },
+ { R0900_GAINLLR_NF8 , 0x1E },
+ { R0900_GAINLLR_NF9 , 0x1E },
+ { R0900_GAINLLR_NF10 , 0x1D },
+ { R0900_GAINLLR_NF11 , 0x1B },
+ { R0900_GAINLLR_NF12 , 0x20 },
+ { R0900_GAINLLR_NF13 , 0x20 },
+ { R0900_GAINLLR_NF14 , 0x20 },
+ { R0900_GAINLLR_NF15 , 0x20 },
+ { R0900_GAINLLR_NF16 , 0x20 },
+ { R0900_GAINLLR_NF17 , 0x21 }
+
+};
+
+#endif
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
new file mode 100644
index 00000000000..762d5af62d7
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -0,0 +1,430 @@
+/*
+ * stv0900_priv.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 STV0900_PRIV_H
+#define STV0900_PRIV_H
+
+#include <linux/i2c.h>
+
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
+ || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
+
+#ifndef MAKEWORD
+#define MAKEWORD(X, Y) (((X) << 8) + (Y))
+#endif
+
+#define LSB(X) (((X) & 0xFF))
+#define MSB(Y) (((Y) >> 8) & 0xFF)
+
+#ifndef TRUE
+#define TRUE (1 == 1)
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+#define dmd_reg(a, b, c) \
+ do { \
+ a = 0; \
+ switch (demod) { \
+ case STV0900_DEMOD_1: \
+ default: \
+ a = b; \
+ break; \
+ case STV0900_DEMOD_2: \
+ a = c; \
+ break; \
+ } \
+ } while (0)
+
+#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a))
+
+static int stvdebug;
+
+#define dprintk(args...) \
+ do { \
+ if (stvdebug) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+#define STV0900_MAXLOOKUPSIZE 500
+#define STV0900_BLIND_SEARCH_AGC2_TH 700
+
+/* One point of the lookup table */
+struct stv000_lookpoint {
+ s32 realval;/* real value */
+ s32 regval;/* binary value */
+};
+
+/* Lookup table definition */
+struct stv0900_table{
+ s32 size;/* Size of the lookup table */
+ struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
+};
+
+enum fe_stv0900_error {
+ STV0900_NO_ERROR = 0,
+ STV0900_INVALID_HANDLE,
+ STV0900_BAD_PARAMETER,
+ STV0900_I2C_ERROR,
+ STV0900_SEARCH_FAILED,
+};
+
+enum fe_stv0900_clock_type {
+ STV0900_USE_REGISTERS_DEFAULT,
+ STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
+ STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
+ STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
+ STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
+};
+
+enum fe_stv0900_search_state {
+ STV0900_SEARCH = 0,
+ STV0900_PLH_DETECTED,
+ STV0900_DVBS2_FOUND,
+ STV0900_DVBS_FOUND
+
+};
+
+enum fe_stv0900_ldpc_state {
+ STV0900_PATH1_OFF_PATH2_OFF = 0,
+ STV0900_PATH1_ON_PATH2_OFF = 1,
+ STV0900_PATH1_OFF_PATH2_ON = 2,
+ STV0900_PATH1_ON_PATH2_ON = 3
+};
+
+enum fe_stv0900_signal_type {
+ STV0900_NOAGC1 = 0,
+ STV0900_AGC1OK,
+ STV0900_NOTIMING,
+ STV0900_ANALOGCARRIER,
+ STV0900_TIMINGOK,
+ STV0900_NOAGC2,
+ STV0900_AGC2OK,
+ STV0900_NOCARRIER,
+ STV0900_CARRIEROK,
+ STV0900_NODATA,
+ STV0900_DATAOK,
+ STV0900_OUTOFRANGE,
+ STV0900_RANGEOK
+};
+
+enum fe_stv0900_demod_num {
+ STV0900_DEMOD_1,
+ STV0900_DEMOD_2
+};
+
+enum fe_stv0900_tracking_standard {
+ STV0900_DVBS1_STANDARD,/* Found Standard*/
+ STV0900_DVBS2_STANDARD,
+ STV0900_DSS_STANDARD,
+ STV0900_TURBOCODE_STANDARD,
+ STV0900_UNKNOWN_STANDARD
+};
+
+enum fe_stv0900_search_standard {
+ STV0900_AUTO_SEARCH,
+ STV0900_SEARCH_DVBS1,/* Search Standard*/
+ STV0900_SEARCH_DVBS2,
+ STV0900_SEARCH_DSS,
+ STV0900_SEARCH_TURBOCODE
+};
+
+enum fe_stv0900_search_algo {
+ STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
+ STV0900_COLD_START,/* only the SR is known */
+ STV0900_WARM_START/* offset freq and SR are known */
+};
+
+enum fe_stv0900_modulation {
+ STV0900_QPSK,
+ STV0900_8PSK,
+ STV0900_16APSK,
+ STV0900_32APSK,
+ STV0900_UNKNOWN
+};
+
+enum fe_stv0900_modcode {
+ STV0900_DUMMY_PLF,
+ STV0900_QPSK_14,
+ STV0900_QPSK_13,
+ STV0900_QPSK_25,
+ STV0900_QPSK_12,
+ STV0900_QPSK_35,
+ STV0900_QPSK_23,
+ STV0900_QPSK_34,
+ STV0900_QPSK_45,
+ STV0900_QPSK_56,
+ STV0900_QPSK_89,
+ STV0900_QPSK_910,
+ STV0900_8PSK_35,
+ STV0900_8PSK_23,
+ STV0900_8PSK_34,
+ STV0900_8PSK_56,
+ STV0900_8PSK_89,
+ STV0900_8PSK_910,
+ STV0900_16APSK_23,
+ STV0900_16APSK_34,
+ STV0900_16APSK_45,
+ STV0900_16APSK_56,
+ STV0900_16APSK_89,
+ STV0900_16APSK_910,
+ STV0900_32APSK_34,
+ STV0900_32APSK_45,
+ STV0900_32APSK_56,
+ STV0900_32APSK_89,
+ STV0900_32APSK_910,
+ STV0900_MODCODE_UNKNOWN
+};
+
+enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
+ STV0900_FEC_1_2 = 0,
+ STV0900_FEC_2_3,
+ STV0900_FEC_3_4,
+ STV0900_FEC_4_5,/*for turbo code only*/
+ STV0900_FEC_5_6,
+ STV0900_FEC_6_7,/*for DSS only */
+ STV0900_FEC_7_8,
+ STV0900_FEC_8_9,/*for turbo code only*/
+ STV0900_FEC_UNKNOWN
+};
+
+enum fe_stv0900_frame_length {
+ STV0900_LONG_FRAME,
+ STV0900_SHORT_FRAME
+};
+
+enum fe_stv0900_pilot {
+ STV0900_PILOTS_OFF,
+ STV0900_PILOTS_ON
+};
+
+enum fe_stv0900_rolloff {
+ STV0900_35,
+ STV0900_25,
+ STV0900_20
+};
+
+enum fe_stv0900_search_iq {
+ STV0900_IQ_AUTO,
+ STV0900_IQ_AUTO_NORMAL_FIRST,
+ STV0900_IQ_FORCE_NORMAL,
+ STV0900_IQ_FORCE_SWAPPED
+};
+
+enum stv0900_iq_inversion {
+ STV0900_IQ_NORMAL,
+ STV0900_IQ_SWAPPED
+};
+
+enum fe_stv0900_diseqc_mode {
+ STV0900_22KHZ_Continues = 0,
+ STV0900_DISEQC_2_3_PWM = 2,
+ STV0900_DISEQC_3_3_PWM = 3,
+ STV0900_DISEQC_2_3_ENVELOP = 4,
+ STV0900_DISEQC_3_3_ENVELOP = 5
+};
+
+enum fe_stv0900_demod_mode {
+ STV0900_SINGLE = 0,
+ STV0900_DUAL
+};
+
+struct stv0900_init_params{
+ u32 dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */
+
+ /* Demodulator Type (single demod or dual demod) */
+ enum fe_stv0900_demod_mode demod_mode;
+ enum fe_stv0900_rolloff rolloff;
+ enum fe_stv0900_clock_type path1_ts_clock;
+
+ u8 tun1_maddress;
+ int tuner1_adc;
+
+ /* IQ from the tuner1 to the demod */
+ enum stv0900_iq_inversion tun1_iq_inversion;
+ enum fe_stv0900_clock_type path2_ts_clock;
+
+ u8 tun2_maddress;
+ int tuner2_adc;
+
+ /* IQ from the tuner2 to the demod */
+ enum stv0900_iq_inversion tun2_iq_inversion;
+};
+
+struct stv0900_search_params {
+ enum fe_stv0900_demod_num path;/* Path Used demod1 or 2 */
+
+ u32 frequency;/* Transponder frequency (in KHz) */
+ u32 symbol_rate;/* Transponder symbol rate (in bds)*/
+ u32 search_range;/* Range of the search (in Hz) */
+
+ enum fe_stv0900_search_standard standard;
+ enum fe_stv0900_modulation modulation;
+ enum fe_stv0900_fec fec;
+ enum fe_stv0900_modcode modcode;
+ enum fe_stv0900_search_iq iq_inversion;
+ enum fe_stv0900_search_algo search_algo;
+
+};
+
+struct stv0900_signal_info {
+ int locked;/* Transponder locked */
+ u32 frequency;/* Transponder frequency (in KHz) */
+ u32 symbol_rate;/* Transponder symbol rate (in Mbds) */
+
+ enum fe_stv0900_tracking_standard standard;
+ enum fe_stv0900_fec fec;
+ enum fe_stv0900_modcode modcode;
+ enum fe_stv0900_modulation modulation;
+ enum fe_stv0900_pilot pilot;
+ enum fe_stv0900_frame_length frame_length;
+ enum stv0900_iq_inversion spectrum;
+ enum fe_stv0900_rolloff rolloff;
+
+ s32 Power;/* Power of the RF signal (dBm) */
+ s32 C_N;/* Carrier to noise ratio (dB x10)*/
+ u32 BER;/* Bit error rate (x10^7) */
+
+};
+
+struct stv0900_internal{
+ s32 quartz;
+ s32 mclk;
+ /* manual RollOff for DVBS1/DSS only */
+ enum fe_stv0900_rolloff rolloff;
+ /* Demodulator use for single demod or for dual demod) */
+ enum fe_stv0900_demod_mode demod_mode;
+
+ /*Demod 1*/
+ s32 tuner1_freq;
+ s32 tuner1_bw;
+ s32 dmd1_symbol_rate;
+ s32 dmd1_srch_range;
+
+ /* algorithm for search Blind, Cold or Warm*/
+ enum fe_stv0900_search_algo dmd1_srch_algo;
+ /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
+ enum fe_stv0900_search_standard dmd1_srch_standard;
+ /* inversion search : auto, auto norma first, normal or inverted */
+ enum fe_stv0900_search_iq dmd1_srch_iq_inv;
+ enum fe_stv0900_modcode dmd1_modcode;
+ enum fe_stv0900_modulation dmd1_modulation;
+ enum fe_stv0900_fec dmd1_fec;
+
+ struct stv0900_signal_info dmd1_rslts;
+ enum fe_stv0900_signal_type dmd1_state;
+
+ enum fe_stv0900_error dmd1_err;
+
+ /*Demod 2*/
+ s32 tuner2_freq;
+ s32 tuner2_bw;
+ s32 dmd2_symbol_rate;
+ s32 dmd2_srch_range;
+
+ enum fe_stv0900_search_algo dmd2_srch_algo;
+ enum fe_stv0900_search_standard dmd2_srch_stndrd;
+ /* inversion search : auto, auto normal first, normal or inverted */
+ enum fe_stv0900_search_iq dmd2_srch_iq_inv;
+ enum fe_stv0900_modcode dmd2_modcode;
+ enum fe_stv0900_modulation dmd2_modulation;
+ enum fe_stv0900_fec dmd2_fec;
+
+ /* results of the search*/
+ struct stv0900_signal_info dmd2_rslts;
+ /* current state of the search algorithm */
+ enum fe_stv0900_signal_type dmd2_state;
+
+ enum fe_stv0900_error dmd2_err;
+
+ struct i2c_adapter *i2c_adap;
+ u8 i2c_addr;
+ u8 clkmode;/* 0 for CLKI, 2 for XTALI */
+ u8 chip_id;
+ enum fe_stv0900_error errs;
+ int dmds_used;
+};
+
+/* state for each demod */
+struct stv0900_state {
+ /* pointer for internal params, one for each pair of demods */
+ struct stv0900_internal *internal;
+ struct i2c_adapter *i2c_adap;
+ const struct stv0900_config *config;
+ struct dvb_frontend frontend;
+ int demod;
+};
+
+extern s32 ge2comp(s32 a, s32 width);
+
+extern void stv0900_write_reg(struct stv0900_internal *i_params,
+ u16 reg_addr, u8 reg_data);
+
+extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
+ u16 reg_addr);
+
+extern void stv0900_write_bits(struct stv0900_internal *i_params,
+ u32 label, u8 val);
+
+extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
+ u32 label);
+
+extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod, s32 time_out);
+extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
+
+extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+ u32 bandwidth);
+extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
+
+extern void stv0900_start_search(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern u8 stv0900_get_optim_carr_loop(s32 srate,
+ enum fe_stv0900_modcode modcode,
+ s32 pilot, u8 chip_id);
+
+extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
+ enum fe_stv0900_modulation modulation,
+ u8 chip_id);
+
+extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+ enum fe_stv0900_demod_num demod);
+
+#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
new file mode 100644
index 00000000000..264f9cf9a17
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -0,0 +1,3787 @@
+/*
+ * stv0900_reg.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 STV0900_REG_H
+#define STV0900_REG_H
+
+/*MID*/
+#define R0900_MID 0xf100
+#define F0900_MCHIP_IDENT 0xf10000f0
+#define F0900_MRELEASE 0xf100000f
+
+/*DACR1*/
+#define R0900_DACR1 0xf113
+#define F0900_DAC_MODE 0xf11300e0
+#define F0900_DAC_VALUE1 0xf113000f
+
+/*DACR2*/
+#define R0900_DACR2 0xf114
+#define F0900_DAC_VALUE0 0xf11400ff
+
+/*OUTCFG*/
+#define R0900_OUTCFG 0xf11c
+#define F0900_INV_DATA6 0xf11c0080
+#define F0900_OUTSERRS1_HZ 0xf11c0040
+#define F0900_OUTSERRS2_HZ 0xf11c0020
+#define F0900_OUTSERRS3_HZ 0xf11c0010
+#define F0900_OUTPARRS3_HZ 0xf11c0008
+#define F0900_OUTHZ3_CONTROL 0xf11c0007
+
+/*MODECFG*/
+#define R0900_MODECFG 0xf11d
+#define F0900_FECSPY_SEL_2 0xf11d0020
+#define F0900_HWARE_SEL_2 0xf11d0010
+#define F0900_PKTDEL_SEL_2 0xf11d0008
+#define F0900_DISEQC_SEL_2 0xf11d0004
+#define F0900_VIT_SEL_2 0xf11d0002
+#define F0900_DEMOD_SEL_2 0xf11d0001
+
+/*IRQSTATUS3*/
+#define R0900_IRQSTATUS3 0xf120
+#define F0900_SPLL_LOCK 0xf1200020
+#define F0900_SSTREAM_LCK_3 0xf1200010
+#define F0900_SSTREAM_LCK_2 0xf1200008
+#define F0900_SSTREAM_LCK_1 0xf1200004
+#define F0900_SDVBS1_PRF_2 0xf1200002
+#define F0900_SDVBS1_PRF_1 0xf1200001
+
+/*IRQSTATUS2*/
+#define R0900_IRQSTATUS2 0xf121
+#define F0900_SSPY_ENDSIM_3 0xf1210080
+#define F0900_SSPY_ENDSIM_2 0xf1210040
+#define F0900_SSPY_ENDSIM_1 0xf1210020
+#define F0900_SPKTDEL_ERROR_2 0xf1210010
+#define F0900_SPKTDEL_LOCKB_2 0xf1210008
+#define F0900_SPKTDEL_LOCK_2 0xf1210004
+#define F0900_SPKTDEL_ERROR_1 0xf1210002
+#define F0900_SPKTDEL_LOCKB_1 0xf1210001
+
+/*IRQSTATUS1*/
+#define R0900_IRQSTATUS1 0xf122
+#define F0900_SPKTDEL_LOCK_1 0xf1220080
+#define F0900_SEXTPINB2 0xf1220040
+#define F0900_SEXTPIN2 0xf1220020
+#define F0900_SEXTPINB1 0xf1220010
+#define F0900_SEXTPIN1 0xf1220008
+#define F0900_SDEMOD_LOCKB_2 0xf1220004
+#define F0900_SDEMOD_LOCK_2 0xf1220002
+#define F0900_SDEMOD_IRQ_2 0xf1220001
+
+/*IRQSTATUS0*/
+#define R0900_IRQSTATUS0 0xf123
+#define F0900_SDEMOD_LOCKB_1 0xf1230080
+#define F0900_SDEMOD_LOCK_1 0xf1230040
+#define F0900_SDEMOD_IRQ_1 0xf1230020
+#define F0900_SBCH_ERRFLAG 0xf1230010
+#define F0900_SDISEQC2RX_IRQ 0xf1230008
+#define F0900_SDISEQC2TX_IRQ 0xf1230004
+#define F0900_SDISEQC1RX_IRQ 0xf1230002
+#define F0900_SDISEQC1TX_IRQ 0xf1230001
+
+/*IRQMASK3*/
+#define R0900_IRQMASK3 0xf124
+#define F0900_MPLL_LOCK 0xf1240020
+#define F0900_MSTREAM_LCK_3 0xf1240010
+#define F0900_MSTREAM_LCK_2 0xf1240008
+#define F0900_MSTREAM_LCK_1 0xf1240004
+#define F0900_MDVBS1_PRF_2 0xf1240002
+#define F0900_MDVBS1_PRF_1 0xf1240001
+
+/*IRQMASK2*/
+#define R0900_IRQMASK2 0xf125
+#define F0900_MSPY_ENDSIM_3 0xf1250080
+#define F0900_MSPY_ENDSIM_2 0xf1250040
+#define F0900_MSPY_ENDSIM_1 0xf1250020
+#define F0900_MPKTDEL_ERROR_2 0xf1250010
+#define F0900_MPKTDEL_LOCKB_2 0xf1250008
+#define F0900_MPKTDEL_LOCK_2 0xf1250004
+#define F0900_MPKTDEL_ERROR_1 0xf1250002
+#define F0900_MPKTDEL_LOCKB_1 0xf1250001
+
+/*IRQMASK1*/
+#define R0900_IRQMASK1 0xf126
+#define F0900_MPKTDEL_LOCK_1 0xf1260080
+#define F0900_MEXTPINB2 0xf1260040
+#define F0900_MEXTPIN2 0xf1260020
+#define F0900_MEXTPINB1 0xf1260010
+#define F0900_MEXTPIN1 0xf1260008
+#define F0900_MDEMOD_LOCKB_2 0xf1260004
+#define F0900_MDEMOD_LOCK_2 0xf1260002
+#define F0900_MDEMOD_IRQ_2 0xf1260001
+
+/*IRQMASK0*/
+#define R0900_IRQMASK0 0xf127
+#define F0900_MDEMOD_LOCKB_1 0xf1270080
+#define F0900_MDEMOD_LOCK_1 0xf1270040
+#define F0900_MDEMOD_IRQ_1 0xf1270020
+#define F0900_MBCH_ERRFLAG 0xf1270010
+#define F0900_MDISEQC2RX_IRQ 0xf1270008
+#define F0900_MDISEQC2TX_IRQ 0xf1270004
+#define F0900_MDISEQC1RX_IRQ 0xf1270002
+#define F0900_MDISEQC1TX_IRQ 0xf1270001
+
+/*I2CCFG*/
+#define R0900_I2CCFG 0xf129
+#define F0900_I2C2_FASTMODE 0xf1290080
+#define F0900_STATUS_WR2 0xf1290040
+#define F0900_I2C2ADDR_INC 0xf1290030
+#define F0900_I2C_FASTMODE 0xf1290008
+#define F0900_STATUS_WR 0xf1290004
+#define F0900_I2CADDR_INC 0xf1290003
+
+/*P1_I2CRPT*/
+#define R0900_P1_I2CRPT 0xf12a
+#define F0900_P1_I2CT_ON 0xf12a0080
+#define F0900_P1_ENARPT_LEVEL 0xf12a0070
+#define F0900_P1_SCLT_DELAY 0xf12a0008
+#define F0900_P1_STOP_ENABLE 0xf12a0004
+#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
+
+/*P2_I2CRPT*/
+#define R0900_P2_I2CRPT 0xf12b
+#define F0900_P2_I2CT_ON 0xf12b0080
+#define F0900_P2_ENARPT_LEVEL 0xf12b0070
+#define F0900_P2_SCLT_DELAY 0xf12b0008
+#define F0900_P2_STOP_ENABLE 0xf12b0004
+#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
+
+/*CLKI2CFG*/
+#define R0900_CLKI2CFG 0xf140
+#define F0900_CLKI2_OPD 0xf1400080
+#define F0900_CLKI2_CONFIG 0xf140007e
+#define F0900_CLKI2_XOR 0xf1400001
+
+/*GPIO1CFG*/
+#define R0900_GPIO1CFG 0xf141
+#define F0900_GPIO1_OPD 0xf1410080
+#define F0900_GPIO1_CONFIG 0xf141007e
+#define F0900_GPIO1_XOR 0xf1410001
+
+/*GPIO2CFG*/
+#define R0900_GPIO2CFG 0xf142
+#define F0900_GPIO2_OPD 0xf1420080
+#define F0900_GPIO2_CONFIG 0xf142007e
+#define F0900_GPIO2_XOR 0xf1420001
+
+/*GPIO3CFG*/
+#define R0900_GPIO3CFG 0xf143
+#define F0900_GPIO3_OPD 0xf1430080
+#define F0900_GPIO3_CONFIG 0xf143007e
+#define F0900_GPIO3_XOR 0xf1430001
+
+/*GPIO4CFG*/
+#define R0900_GPIO4CFG 0xf144
+#define F0900_GPIO4_OPD 0xf1440080
+#define F0900_GPIO4_CONFIG 0xf144007e
+#define F0900_GPIO4_XOR 0xf1440001
+
+/*GPIO5CFG*/
+#define R0900_GPIO5CFG 0xf145
+#define F0900_GPIO5_OPD 0xf1450080
+#define F0900_GPIO5_CONFIG 0xf145007e
+#define F0900_GPIO5_XOR 0xf1450001
+
+/*GPIO6CFG*/
+#define R0900_GPIO6CFG 0xf146
+#define F0900_GPIO6_OPD 0xf1460080
+#define F0900_GPIO6_CONFIG 0xf146007e
+#define F0900_GPIO6_XOR 0xf1460001
+
+/*GPIO7CFG*/
+#define R0900_GPIO7CFG 0xf147
+#define F0900_GPIO7_OPD 0xf1470080
+#define F0900_GPIO7_CONFIG 0xf147007e
+#define F0900_GPIO7_XOR 0xf1470001
+
+/*GPIO8CFG*/
+#define R0900_GPIO8CFG 0xf148
+#define F0900_GPIO8_OPD 0xf1480080
+#define F0900_GPIO8_CONFIG 0xf148007e
+#define F0900_GPIO8_XOR 0xf1480001
+
+/*GPIO9CFG*/
+#define R0900_GPIO9CFG 0xf149
+#define F0900_GPIO9_OPD 0xf1490080
+#define F0900_GPIO9_CONFIG 0xf149007e
+#define F0900_GPIO9_XOR 0xf1490001
+
+/*GPIO10CFG*/
+#define R0900_GPIO10CFG 0xf14a
+#define F0900_GPIO10_OPD 0xf14a0080
+#define F0900_GPIO10_CONFIG 0xf14a007e
+#define F0900_GPIO10_XOR 0xf14a0001
+
+/*GPIO11CFG*/
+#define R0900_GPIO11CFG 0xf14b
+#define F0900_GPIO11_OPD 0xf14b0080
+#define F0900_GPIO11_CONFIG 0xf14b007e
+#define F0900_GPIO11_XOR 0xf14b0001
+
+/*GPIO12CFG*/
+#define R0900_GPIO12CFG 0xf14c
+#define F0900_GPIO12_OPD 0xf14c0080
+#define F0900_GPIO12_CONFIG 0xf14c007e
+#define F0900_GPIO12_XOR 0xf14c0001
+
+/*GPIO13CFG*/
+#define R0900_GPIO13CFG 0xf14d
+#define F0900_GPIO13_OPD 0xf14d0080
+#define F0900_GPIO13_CONFIG 0xf14d007e
+#define F0900_GPIO13_XOR 0xf14d0001
+
+/*CS0CFG*/
+#define R0900_CS0CFG 0xf14e
+#define F0900_CS0_OPD 0xf14e0080
+#define F0900_CS0_CONFIG 0xf14e007e
+#define F0900_CS0_XOR 0xf14e0001
+
+/*CS1CFG*/
+#define R0900_CS1CFG 0xf14f
+#define F0900_CS1_OPD 0xf14f0080
+#define F0900_CS1_CONFIG 0xf14f007e
+#define F0900_CS1_XOR 0xf14f0001
+
+/*STDBYCFG*/
+#define R0900_STDBYCFG 0xf150
+#define F0900_STDBY_OPD 0xf1500080
+#define F0900_STDBY_CONFIG 0xf150007e
+#define F0900_STBDY_XOR 0xf1500001
+
+/*DIRCLKCFG*/
+#define R0900_DIRCLKCFG 0xf151
+#define F0900_DIRCLK_OPD 0xf1510080
+#define F0900_DIRCLK_CONFIG 0xf151007e
+#define F0900_DIRCLK_XOR 0xf1510001
+
+/*AGCRF1CFG*/
+#define R0900_AGCRF1CFG 0xf152
+#define F0900_AGCRF1_OPD 0xf1520080
+#define F0900_AGCRF1_CONFIG 0xf152007e
+#define F0900_AGCRF1_XOR 0xf1520001
+
+/*SDAT1CFG*/
+#define R0900_SDAT1CFG 0xf153
+#define F0900_SDAT1_OPD 0xf1530080
+#define F0900_SDAT1_CONFIG 0xf153007e
+#define F0900_SDAT1_XOR 0xf1530001
+
+/*SCLT1CFG*/
+#define R0900_SCLT1CFG 0xf154
+#define F0900_SCLT1_OPD 0xf1540080
+#define F0900_SCLT1_CONFIG 0xf154007e
+#define F0900_SCLT1_XOR 0xf1540001
+
+/*DISEQCO1CFG*/
+#define R0900_DISEQCO1CFG 0xf155
+#define F0900_DISEQCO1_OPD 0xf1550080
+#define F0900_DISEQCO1_CONFIG 0xf155007e
+#define F0900_DISEQC1_XOR 0xf1550001
+
+/*AGCRF2CFG*/
+#define R0900_AGCRF2CFG 0xf156
+#define F0900_AGCRF2_OPD 0xf1560080
+#define F0900_AGCRF2_CONFIG 0xf156007e
+#define F0900_AGCRF2_XOR 0xf1560001
+
+/*SDAT2CFG*/
+#define R0900_SDAT2CFG 0xf157
+#define F0900_SDAT2_OPD 0xf1570080
+#define F0900_SDAT2_CONFIG 0xf157007e
+#define F0900_SDAT2_XOR 0xf1570001
+
+/*SCLT2CFG*/
+#define R0900_SCLT2CFG 0xf158
+#define F0900_SCLT2_OPD 0xf1580080
+#define F0900_SCLT2_CONFIG 0xf158007e
+#define F0900_SCLT2_XOR 0xf1580001
+
+/*DISEQCO2CFG*/
+#define R0900_DISEQCO2CFG 0xf159
+#define F0900_DISEQCO2_OPD 0xf1590080
+#define F0900_DISEQCO2_CONFIG 0xf159007e
+#define F0900_DISEQC2_XOR 0xf1590001
+
+/*CLKOUT27CFG*/
+#define R0900_CLKOUT27CFG 0xf15a
+#define F0900_CLKOUT27_OPD 0xf15a0080
+#define F0900_CLKOUT27_CONFIG 0xf15a007e
+#define F0900_CLKOUT27_XOR 0xf15a0001
+
+/*ERROR1CFG*/
+#define R0900_ERROR1CFG 0xf15b
+#define F0900_ERROR1_OPD 0xf15b0080
+#define F0900_ERROR1_CONFIG 0xf15b007e
+#define F0900_ERROR1_XOR 0xf15b0001
+
+/*DPN1CFG*/
+#define R0900_DPN1CFG 0xf15c
+#define F0900_DPN1_OPD 0xf15c0080
+#define F0900_DPN1_CONFIG 0xf15c007e
+#define F0900_DPN1_XOR 0xf15c0001
+
+/*STROUT1CFG*/
+#define R0900_STROUT1CFG 0xf15d
+#define F0900_STROUT1_OPD 0xf15d0080
+#define F0900_STROUT1_CONFIG 0xf15d007e
+#define F0900_STROUT1_XOR 0xf15d0001
+
+/*CLKOUT1CFG*/
+#define R0900_CLKOUT1CFG 0xf15e
+#define F0900_CLKOUT1_OPD 0xf15e0080
+#define F0900_CLKOUT1_CONFIG 0xf15e007e
+#define F0900_CLKOUT1_XOR 0xf15e0001
+
+/*DATA71CFG*/
+#define R0900_DATA71CFG 0xf15f
+#define F0900_DATA71_OPD 0xf15f0080
+#define F0900_DATA71_CONFIG 0xf15f007e
+#define F0900_DATA71_XOR 0xf15f0001
+
+/*ERROR2CFG*/
+#define R0900_ERROR2CFG 0xf160
+#define F0900_ERROR2_OPD 0xf1600080
+#define F0900_ERROR2_CONFIG 0xf160007e
+#define F0900_ERROR2_XOR 0xf1600001
+
+/*DPN2CFG*/
+#define R0900_DPN2CFG 0xf161
+#define F0900_DPN2_OPD 0xf1610080
+#define F0900_DPN2_CONFIG 0xf161007e
+#define F0900_DPN2_XOR 0xf1610001
+
+/*STROUT2CFG*/
+#define R0900_STROUT2CFG 0xf162
+#define F0900_STROUT2_OPD 0xf1620080
+#define F0900_STROUT2_CONFIG 0xf162007e
+#define F0900_STROUT2_XOR 0xf1620001
+
+/*CLKOUT2CFG*/
+#define R0900_CLKOUT2CFG 0xf163
+#define F0900_CLKOUT2_OPD 0xf1630080
+#define F0900_CLKOUT2_CONFIG 0xf163007e
+#define F0900_CLKOUT2_XOR 0xf1630001
+
+/*DATA72CFG*/
+#define R0900_DATA72CFG 0xf164
+#define F0900_DATA72_OPD 0xf1640080
+#define F0900_DATA72_CONFIG 0xf164007e
+#define F0900_DATA72_XOR 0xf1640001
+
+/*ERROR3CFG*/
+#define R0900_ERROR3CFG 0xf165
+#define F0900_ERROR3_OPD 0xf1650080
+#define F0900_ERROR3_CONFIG 0xf165007e
+#define F0900_ERROR3_XOR 0xf1650001
+
+/*DPN3CFG*/
+#define R0900_DPN3CFG 0xf166
+#define F0900_DPN3_OPD 0xf1660080
+#define F0900_DPN3_CONFIG 0xf166007e
+#define F0900_DPN3_XOR 0xf1660001
+
+/*STROUT3CFG*/
+#define R0900_STROUT3CFG 0xf167
+#define F0900_STROUT3_OPD 0xf1670080
+#define F0900_STROUT3_CONFIG 0xf167007e
+#define F0900_STROUT3_XOR 0xf1670001
+
+/*CLKOUT3CFG*/
+#define R0900_CLKOUT3CFG 0xf168
+#define F0900_CLKOUT3_OPD 0xf1680080
+#define F0900_CLKOUT3_CONFIG 0xf168007e
+#define F0900_CLKOUT3_XOR 0xf1680001
+
+/*DATA73CFG*/
+#define R0900_DATA73CFG 0xf169
+#define F0900_DATA73_OPD 0xf1690080
+#define F0900_DATA73_CONFIG 0xf169007e
+#define F0900_DATA73_XOR 0xf1690001
+
+/*FSKTFC2*/
+#define R0900_FSKTFC2 0xf170
+#define F0900_FSKT_KMOD 0xf17000fc
+#define F0900_FSKT_CAR2 0xf1700003
+
+/*FSKTFC1*/
+#define R0900_FSKTFC1 0xf171
+#define F0900_FSKT_CAR1 0xf17100ff
+
+/*FSKTFC0*/
+#define R0900_FSKTFC0 0xf172
+#define F0900_FSKT_CAR0 0xf17200ff
+
+/*FSKTDELTAF1*/
+#define R0900_FSKTDELTAF1 0xf173
+#define F0900_FSKT_DELTAF1 0xf173000f
+
+/*FSKTDELTAF0*/
+#define R0900_FSKTDELTAF0 0xf174
+#define F0900_FSKT_DELTAF0 0xf17400ff
+
+/*FSKTCTRL*/
+#define R0900_FSKTCTRL 0xf175
+#define F0900_FSKT_EN_SGN 0xf1750040
+#define F0900_FSKT_MOD_SGN 0xf1750020
+#define F0900_FSKT_MOD_EN 0xf175001c
+#define F0900_FSKT_DACMODE 0xf1750003
+
+/*FSKRFC2*/
+#define R0900_FSKRFC2 0xf176
+#define F0900_FSKR_DETSGN 0xf1760040
+#define F0900_FSKR_OUTSGN 0xf1760020
+#define F0900_FSKR_KAGC 0xf176001c
+#define F0900_FSKR_CAR2 0xf1760003
+
+/*FSKRFC1*/
+#define R0900_FSKRFC1 0xf177
+#define F0900_FSKR_CAR1 0xf17700ff
+
+/*FSKRFC0*/
+#define R0900_FSKRFC0 0xf178
+#define F0900_FSKR_CAR0 0xf17800ff
+
+/*FSKRK1*/
+#define R0900_FSKRK1 0xf179
+#define F0900_FSKR_K1_EXP 0xf17900e0
+#define F0900_FSKR_K1_MANT 0xf179001f
+
+/*FSKRK2*/
+#define R0900_FSKRK2 0xf17a
+#define F0900_FSKR_K2_EXP 0xf17a00e0
+#define F0900_FSKR_K2_MANT 0xf17a001f
+
+/*FSKRAGCR*/
+#define R0900_FSKRAGCR 0xf17b
+#define F0900_FSKR_OUTCTL 0xf17b00c0
+#define F0900_FSKR_AGC_REF 0xf17b003f
+
+/*FSKRAGC*/
+#define R0900_FSKRAGC 0xf17c
+#define F0900_FSKR_AGC_ACCU 0xf17c00ff
+
+/*FSKRALPHA*/
+#define R0900_FSKRALPHA 0xf17d
+#define F0900_FSKR_ALPHA_EXP 0xf17d001c
+#define F0900_FSKR_ALPHA_M 0xf17d0003
+
+/*FSKRPLTH1*/
+#define R0900_FSKRPLTH1 0xf17e
+#define F0900_FSKR_BETA 0xf17e00f0
+#define F0900_FSKR_PLL_TRESH1 0xf17e000f
+
+/*FSKRPLTH0*/
+#define R0900_FSKRPLTH0 0xf17f
+#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
+
+/*FSKRDF1*/
+#define R0900_FSKRDF1 0xf180
+#define F0900_FSKR_OUT 0xf1800080
+#define F0900_FSKR_DELTAF1 0xf180001f
+
+/*FSKRDF0*/
+#define R0900_FSKRDF0 0xf181
+#define F0900_FSKR_DELTAF0 0xf18100ff
+
+/*FSKRSTEPP*/
+#define R0900_FSKRSTEPP 0xf182
+#define F0900_FSKR_STEP_PLUS 0xf18200ff
+
+/*FSKRSTEPM*/
+#define R0900_FSKRSTEPM 0xf183
+#define F0900_FSKR_STEP_MINUS 0xf18300ff
+
+/*FSKRDET1*/
+#define R0900_FSKRDET1 0xf184
+#define F0900_FSKR_DETECT 0xf1840080
+#define F0900_FSKR_CARDET_ACCU1 0xf184000f
+
+/*FSKRDET0*/
+#define R0900_FSKRDET0 0xf185
+#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
+
+/*FSKRDTH1*/
+#define R0900_FSKRDTH1 0xf186
+#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define F0900_FSKR_CARDET_THRESH1 0xf186000f
+
+/*FSKRDTH0*/
+#define R0900_FSKRDTH0 0xf187
+#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
+
+/*FSKRLOSS*/
+#define R0900_FSKRLOSS 0xf188
+#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
+
+/*P2_DISTXCTL*/
+#define R0900_P2_DISTXCTL 0xf190
+#define F0900_P2_TIM_OFF 0xf1900080
+#define F0900_P2_DISEQC_RESET 0xf1900040
+#define F0900_P2_TIM_CMD 0xf1900030
+#define F0900_P2_DIS_PRECHARGE 0xf1900008
+#define F0900_P2_DISTX_MODE 0xf1900007
+
+/*P2_DISRXCTL*/
+#define R0900_P2_DISRXCTL 0xf191
+#define F0900_P2_RECEIVER_ON 0xf1910080
+#define F0900_P2_IGNO_SHORT22K 0xf1910040
+#define F0900_P2_ONECHIP_TRX 0xf1910020
+#define F0900_P2_EXT_ENVELOP 0xf1910010
+#define F0900_P2_PIN_SELECT 0xf191000c
+#define F0900_P2_IRQ_RXEND 0xf1910002
+#define F0900_P2_IRQ_4NBYTES 0xf1910001
+
+/*P2_DISRX_ST0*/
+#define R0900_P2_DISRX_ST0 0xf194
+#define F0900_P2_RX_END 0xf1940080
+#define F0900_P2_RX_ACTIVE 0xf1940040
+#define F0900_P2_SHORT_22KHZ 0xf1940020
+#define F0900_P2_CONT_TONE 0xf1940010
+#define F0900_P2_FIFO_4BREADY 0xf1940008
+#define F0900_P2_FIFO_EMPTY 0xf1940004
+#define F0900_P2_ABORT_DISRX 0xf1940001
+
+/*P2_DISRX_ST1*/
+#define R0900_P2_DISRX_ST1 0xf195
+#define F0900_P2_RX_FAIL 0xf1950080
+#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
+#define F0900_P2_RX_NONBYTE 0xf1950020
+#define F0900_P2_FIFO_OVERFLOW 0xf1950010
+#define F0900_P2_FIFO_BYTENBR 0xf195000f
+
+/*P2_DISRXDATA*/
+#define R0900_P2_DISRXDATA 0xf196
+#define F0900_P2_DISRX_DATA 0xf19600ff
+
+/*P2_DISTXDATA*/
+#define R0900_P2_DISTXDATA 0xf197
+#define F0900_P2_DISEQC_FIFO 0xf19700ff
+
+/*P2_DISTXSTATUS*/
+#define R0900_P2_DISTXSTATUS 0xf198
+#define F0900_P2_TX_FAIL 0xf1980080
+#define F0900_P2_FIFO_FULL 0xf1980040
+#define F0900_P2_TX_IDLE 0xf1980020
+#define F0900_P2_GAP_BURST 0xf1980010
+#define F0900_P2_TXFIFO_BYTES 0xf198000f
+
+/*P2_F22TX*/
+#define R0900_P2_F22TX 0xf199
+#define F0900_P2_F22_REG 0xf19900ff
+
+/*P2_F22RX*/
+#define R0900_P2_F22RX 0xf19a
+#define F0900_P2_F22RX_REG 0xf19a00ff
+
+/*P2_ACRPRESC*/
+#define R0900_P2_ACRPRESC 0xf19c
+#define F0900_P2_ACR_CODFRDY 0xf19c0008
+#define F0900_P2_ACR_PRESC 0xf19c0007
+
+/*P2_ACRDIV*/
+#define R0900_P2_ACRDIV 0xf19d
+#define F0900_P2_ACR_DIV 0xf19d00ff
+
+/*P1_DISTXCTL*/
+#define R0900_P1_DISTXCTL 0xf1a0
+#define F0900_P1_TIM_OFF 0xf1a00080
+#define F0900_P1_DISEQC_RESET 0xf1a00040
+#define F0900_P1_TIM_CMD 0xf1a00030
+#define F0900_P1_DIS_PRECHARGE 0xf1a00008
+#define F0900_P1_DISTX_MODE 0xf1a00007
+
+/*P1_DISRXCTL*/
+#define R0900_P1_DISRXCTL 0xf1a1
+#define F0900_P1_RECEIVER_ON 0xf1a10080
+#define F0900_P1_IGNO_SHORT22K 0xf1a10040
+#define F0900_P1_ONECHIP_TRX 0xf1a10020
+#define F0900_P1_EXT_ENVELOP 0xf1a10010
+#define F0900_P1_PIN_SELECT 0xf1a1000c
+#define F0900_P1_IRQ_RXEND 0xf1a10002
+#define F0900_P1_IRQ_4NBYTES 0xf1a10001
+
+/*P1_DISRX_ST0*/
+#define R0900_P1_DISRX_ST0 0xf1a4
+#define F0900_P1_RX_END 0xf1a40080
+#define F0900_P1_RX_ACTIVE 0xf1a40040
+#define F0900_P1_SHORT_22KHZ 0xf1a40020
+#define F0900_P1_CONT_TONE 0xf1a40010
+#define F0900_P1_FIFO_4BREADY 0xf1a40008
+#define F0900_P1_FIFO_EMPTY 0xf1a40004
+#define F0900_P1_ABORT_DISRX 0xf1a40001
+
+/*P1_DISRX_ST1*/
+#define R0900_P1_DISRX_ST1 0xf1a5
+#define F0900_P1_RX_FAIL 0xf1a50080
+#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
+#define F0900_P1_RX_NONBYTE 0xf1a50020
+#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
+#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
+
+/*P1_DISRXDATA*/
+#define R0900_P1_DISRXDATA 0xf1a6
+#define F0900_P1_DISRX_DATA 0xf1a600ff
+
+/*P1_DISTXDATA*/
+#define R0900_P1_DISTXDATA 0xf1a7
+#define F0900_P1_DISEQC_FIFO 0xf1a700ff
+
+/*P1_DISTXSTATUS*/
+#define R0900_P1_DISTXSTATUS 0xf1a8
+#define F0900_P1_TX_FAIL 0xf1a80080
+#define F0900_P1_FIFO_FULL 0xf1a80040
+#define F0900_P1_TX_IDLE 0xf1a80020
+#define F0900_P1_GAP_BURST 0xf1a80010
+#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
+
+/*P1_F22TX*/
+#define R0900_P1_F22TX 0xf1a9
+#define F0900_P1_F22_REG 0xf1a900ff
+
+/*P1_F22RX*/
+#define R0900_P1_F22RX 0xf1aa
+#define F0900_P1_F22RX_REG 0xf1aa00ff
+
+/*P1_ACRPRESC*/
+#define R0900_P1_ACRPRESC 0xf1ac
+#define F0900_P1_ACR_CODFRDY 0xf1ac0008
+#define F0900_P1_ACR_PRESC 0xf1ac0007
+
+/*P1_ACRDIV*/
+#define R0900_P1_ACRDIV 0xf1ad
+#define F0900_P1_ACR_DIV 0xf1ad00ff
+
+/*NCOARSE*/
+#define R0900_NCOARSE 0xf1b3
+#define F0900_M_DIV 0xf1b300ff
+
+/*SYNTCTRL*/
+#define R0900_SYNTCTRL 0xf1b6
+#define F0900_STANDBY 0xf1b60080
+#define F0900_BYPASSPLLCORE 0xf1b60040
+#define F0900_SELX1RATIO 0xf1b60020
+#define F0900_I2C_TUD 0xf1b60010
+#define F0900_STOP_PLL 0xf1b60008
+#define F0900_BYPASSPLLFSK 0xf1b60004
+#define F0900_SELOSCI 0xf1b60002
+#define F0900_BYPASSPLLADC 0xf1b60001
+
+/*FILTCTRL*/
+#define R0900_FILTCTRL 0xf1b7
+#define F0900_INV_CLK135 0xf1b70080
+#define F0900_PERM_BYPDIS 0xf1b70040
+#define F0900_SEL_FSKCKDIV 0xf1b70004
+#define F0900_INV_CLKFSK 0xf1b70002
+#define F0900_BYPASS_APPLI 0xf1b70001
+
+/*PLLSTAT*/
+#define R0900_PLLSTAT 0xf1b8
+#define F0900_ACM_SEL 0xf1b80080
+#define F0900_DTV_SEL 0xf1b80040
+#define F0900_PLLLOCK 0xf1b80001
+
+/*STOPCLK1*/
+#define R0900_STOPCLK1 0xf1c2
+#define F0900_STOP_CLKPKDT2 0xf1c20040
+#define F0900_STOP_CLKPKDT1 0xf1c20020
+#define F0900_STOP_CLKFEC 0xf1c20010
+#define F0900_STOP_CLKADCI2 0xf1c20008
+#define F0900_INV_CLKADCI2 0xf1c20004
+#define F0900_STOP_CLKADCI1 0xf1c20002
+#define F0900_INV_CLKADCI1 0xf1c20001
+
+/*STOPCLK2*/
+#define R0900_STOPCLK2 0xf1c3
+#define F0900_STOP_CLKSAMP2 0xf1c30010
+#define F0900_STOP_CLKSAMP1 0xf1c30008
+#define F0900_STOP_CLKVIT2 0xf1c30004
+#define F0900_STOP_CLKVIT1 0xf1c30002
+#define F0900_STOP_CLKTS 0xf1c30001
+
+/*TSTTNR0*/
+#define R0900_TSTTNR0 0xf1df
+#define F0900_SEL_FSK 0xf1df0080
+#define F0900_FSK_PON 0xf1df0004
+#define F0900_FSK_OPENLOOP 0xf1df0002
+
+/*TSTTNR1*/
+#define R0900_TSTTNR1 0xf1e0
+#define F0900_BYPASS_ADC1 0xf1e00080
+#define F0900_INVADC1_CKOUT 0xf1e00040
+#define F0900_SELIQSRC1 0xf1e00030
+#define F0900_ADC1_PON 0xf1e00002
+#define F0900_ADC1_INMODE 0xf1e00001
+
+/*TSTTNR2*/
+#define R0900_TSTTNR2 0xf1e1
+#define F0900_DISEQC1_PON 0xf1e10020
+#define F0900_DISEQC1_TEST 0xf1e1001f
+
+/*TSTTNR3*/
+#define R0900_TSTTNR3 0xf1e2
+#define F0900_BYPASS_ADC2 0xf1e20080
+#define F0900_INVADC2_CKOUT 0xf1e20040
+#define F0900_SELIQSRC2 0xf1e20030
+#define F0900_ADC2_PON 0xf1e20002
+#define F0900_ADC2_INMODE 0xf1e20001
+
+/*TSTTNR4*/
+#define R0900_TSTTNR4 0xf1e3
+#define F0900_DISEQC2_PON 0xf1e30020
+#define F0900_DISEQC2_TEST 0xf1e3001f
+
+/*P2_IQCONST*/
+#define R0900_P2_IQCONST 0xf200
+#define F0900_P2_CONSTEL_SELECT 0xf2000060
+#define F0900_P2_IQSYMB_SEL 0xf200001f
+
+/*P2_NOSCFG*/
+#define R0900_P2_NOSCFG 0xf201
+#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
+#define F0900_P2_NOSPLH_BETA 0xf2010018
+#define F0900_P2_NOSDATA_BETA 0xf2010007
+
+/*P2_ISYMB*/
+#define R0900_P2_ISYMB 0xf202
+#define F0900_P2_I_SYMBOL 0xf20201ff
+
+/*P2_QSYMB*/
+#define R0900_P2_QSYMB 0xf203
+#define F0900_P2_Q_SYMBOL 0xf20301ff
+
+/*P2_AGC1CFG*/
+#define R0900_P2_AGC1CFG 0xf204
+#define F0900_P2_DC_FROZEN 0xf2040080
+#define F0900_P2_DC_CORRECT 0xf2040040
+#define F0900_P2_AMM_FROZEN 0xf2040020
+#define F0900_P2_AMM_CORRECT 0xf2040010
+#define F0900_P2_QUAD_FROZEN 0xf2040008
+#define F0900_P2_QUAD_CORRECT 0xf2040004
+#define F0900_P2_DCCOMP_SLOW 0xf2040002
+#define F0900_P2_IQMISM_SLOW 0xf2040001
+
+/*P2_AGC1CN*/
+#define R0900_P2_AGC1CN 0xf206
+#define F0900_P2_AGC1_LOCKED 0xf2060080
+#define F0900_P2_AGC1_OVERFLOW 0xf2060040
+#define F0900_P2_AGC1_NOSLOWLK 0xf2060020
+#define F0900_P2_AGC1_MINPOWER 0xf2060010
+#define F0900_P2_AGCOUT_FAST 0xf2060008
+#define F0900_P2_AGCIQ_BETA 0xf2060007
+
+/*P2_AGC1REF*/
+#define R0900_P2_AGC1REF 0xf207
+#define F0900_P2_AGCIQ_REF 0xf20700ff
+
+/*P2_IDCCOMP*/
+#define R0900_P2_IDCCOMP 0xf208
+#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
+
+/*P2_QDCCOMP*/
+#define R0900_P2_QDCCOMP 0xf209
+#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
+
+/*P2_POWERI*/
+#define R0900_P2_POWERI 0xf20a
+#define F0900_P2_POWER_I 0xf20a00ff
+
+/*P2_POWERQ*/
+#define R0900_P2_POWERQ 0xf20b
+#define F0900_P2_POWER_Q 0xf20b00ff
+
+/*P2_AGC1AMM*/
+#define R0900_P2_AGC1AMM 0xf20c
+#define F0900_P2_AMM_VALUE 0xf20c00ff
+
+/*P2_AGC1QUAD*/
+#define R0900_P2_AGC1QUAD 0xf20d
+#define F0900_P2_QUAD_VALUE 0xf20d01ff
+
+/*P2_AGCIQIN1*/
+#define R0900_P2_AGCIQIN1 0xf20e
+#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
+
+/*P2_AGCIQIN0*/
+#define R0900_P2_AGCIQIN0 0xf20f
+#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
+
+/*P2_DEMOD*/
+#define R0900_P2_DEMOD 0xf210
+#define F0900_P2_DEMOD_STOP 0xf2100040
+#define F0900_P2_SPECINV_CONTROL 0xf2100030
+#define F0900_P2_FORCE_ENASAMP 0xf2100008
+#define F0900_P2_MANUAL_ROLLOFF 0xf2100004
+#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
+
+/*P2_DMDMODCOD*/
+#define R0900_P2_DMDMODCOD 0xf211
+#define F0900_P2_MANUAL_MODCOD 0xf2110080
+#define F0900_P2_DEMOD_MODCOD 0xf211007c
+#define F0900_P2_DEMOD_TYPE 0xf2110003
+
+/*P2_DSTATUS*/
+#define R0900_P2_DSTATUS 0xf212
+#define F0900_P2_CAR_LOCK 0xf2120080
+#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
+#define F0900_P2_SDVBS1_ENABLE 0xf2120010
+#define F0900_P2_LOCK_DEFINITIF 0xf2120008
+#define F0900_P2_TIMING_IS_LOCKED 0xf2120004
+#define F0900_P2_COARSE_TMGLOCK 0xf2120002
+#define F0900_P2_COARSE_CARLOCK 0xf2120001
+
+/*P2_DSTATUS2*/
+#define R0900_P2_DSTATUS2 0xf213
+#define F0900_P2_DEMOD_DELOCK 0xf2130080
+#define F0900_P2_DEMOD_TIMEOUT 0xf2130040
+#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020
+#define F0900_P2_POLYPH_SATEVENT 0xf2130010
+#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
+#define F0900_P2_AGC2_OVERFLOW 0xf2130004
+#define F0900_P2_CFR_OVERFLOW 0xf2130002
+#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
+
+/*P2_DMDCFGMD*/
+#define R0900_P2_DMDCFGMD 0xf214
+#define F0900_P2_DVBS2_ENABLE 0xf2140080
+#define F0900_P2_DVBS1_ENABLE 0xf2140040
+#define F0900_P2_CFR_AUTOSCAN 0xf2140020
+#define F0900_P2_SCAN_ENABLE 0xf2140010
+#define F0900_P2_TUN_AUTOSCAN 0xf2140008
+#define F0900_P2_NOFORCE_RELOCK 0xf2140004
+#define F0900_P2_TUN_RNG 0xf2140003
+
+/*P2_DMDCFG2*/
+#define R0900_P2_DMDCFG2 0xf215
+#define F0900_P2_AGC1_WAITLOCK 0xf2150080
+#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
+#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020
+#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010
+#define F0900_P2_DMDTOUT_BACK 0xf2150008
+#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004
+#define F0900_P2_COARSE_LK3MODE 0xf2150002
+#define F0900_P2_COARSE_LK2MODE 0xf2150001
+
+/*P2_DMDISTATE*/
+#define R0900_P2_DMDISTATE 0xf216
+#define F0900_P2_I2C_NORESETDMODE 0xf2160080
+#define F0900_P2_FORCE_ETAPED 0xf2160040
+#define F0900_P2_SDMDRST_DIRCLK 0xf2160020
+#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
+
+/*P2_DMDT0M*/
+#define R0900_P2_DMDT0M 0xf217
+#define F0900_P2_DMDT0_MIN 0xf21700ff
+
+/*P2_DMDSTATE*/
+#define R0900_P2_DMDSTATE 0xf21b
+#define F0900_P2_DEMOD_LOCKED 0xf21b0080
+#define F0900_P2_HEADER_MODE 0xf21b0060
+#define F0900_P2_DEMOD_MODE 0xf21b001f
+
+/*P2_DMDFLYW*/
+#define R0900_P2_DMDFLYW 0xf21c
+#define F0900_P2_I2C_IRQVAL 0xf21c00f0
+#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
+
+/*P2_DSTATUS3*/
+#define R0900_P2_DSTATUS3 0xf21d
+#define F0900_P2_CFR_ZIGZAG 0xf21d0080
+#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
+#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010
+#define F0900_P2_RELOCK_MODE 0xf21d0008
+#define F0900_P2_DEMOD_FAIL 0xf21d0004
+#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003
+
+/*P2_DMDCFG3*/
+#define R0900_P2_DMDCFG3 0xf21e
+#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080
+#define F0900_P2_NO_BWCENTERING 0xf21e0040
+#define F0900_P2_INV_SEQSRCH 0xf21e0020
+#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010
+#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
+#define F0900_P2_LOCKTIME_MODE 0xf21e0007
+
+/*P2_DMDCFG4*/
+#define R0900_P2_DMDCFG4 0xf21f
+#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
+#define F0900_P2_DIS_CLKENABLE 0xf21f0004
+#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002
+#define F0900_P2_NO_TNRWBINIT 0xf21f0001
+
+/*P2_CORRELMANT*/
+#define R0900_P2_CORRELMANT 0xf220
+#define F0900_P2_CORREL_MANT 0xf22000ff
+
+/*P2_CORRELABS*/
+#define R0900_P2_CORRELABS 0xf221
+#define F0900_P2_CORREL_ABS 0xf22100ff
+
+/*P2_CORRELEXP*/
+#define R0900_P2_CORRELEXP 0xf222
+#define F0900_P2_CORREL_ABSEXP 0xf22200f0
+#define F0900_P2_CORREL_EXP 0xf222000f
+
+/*P2_PLHMODCOD*/
+#define R0900_P2_PLHMODCOD 0xf224
+#define F0900_P2_SPECINV_DEMOD 0xf2240080
+#define F0900_P2_PLH_MODCOD 0xf224007c
+#define F0900_P2_PLH_TYPE 0xf2240003
+
+/*P2_AGCK32*/
+#define R0900_P2_AGCK32 0xf22b
+#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080
+#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040
+#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020
+#define F0900_P2_RADJ_32APSK 0xf22b001f
+
+/*P2_AGC2O*/
+#define R0900_P2_AGC2O 0xf22c
+#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080
+#define F0900_P2_AGC2_COARSEFAST 0xf22c0040
+#define F0900_P2_AGC2_LKSQRT 0xf22c0020
+#define F0900_P2_AGC2_LKMODE 0xf22c0010
+#define F0900_P2_AGC2_LKEQUA 0xf22c0008
+#define F0900_P2_AGC2_COEF 0xf22c0007
+
+/*P2_AGC2REF*/
+#define R0900_P2_AGC2REF 0xf22d
+#define F0900_P2_AGC2_REF 0xf22d00ff
+
+/*P2_AGC1ADJ*/
+#define R0900_P2_AGC1ADJ 0xf22e
+#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080
+#define F0900_P2_AGC1_ADJUSTED 0xf22e017f
+
+/*P2_AGC2I1*/
+#define R0900_P2_AGC2I1 0xf236
+#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
+
+/*P2_AGC2I0*/
+#define R0900_P2_AGC2I0 0xf237
+#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
+
+/*P2_CARCFG*/
+#define R0900_P2_CARCFG 0xf238
+#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
+#define F0900_P2_CFRUPLOW_TEST 0xf2380040
+#define F0900_P2_EN_CAR2CENTER 0xf2380020
+#define F0900_P2_CARHDR_NODIV8 0xf2380010
+#define F0900_P2_I2C_ROTA 0xf2380008
+#define F0900_P2_ROTAON 0xf2380004
+#define F0900_P2_PH_DET_ALGO 0xf2380003
+
+/*P2_ACLC*/
+#define R0900_P2_ACLC 0xf239
+#define F0900_P2_STOP_S2ALPHA 0xf23900c0
+#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
+#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
+
+/*P2_BCLC*/
+#define R0900_P2_BCLC 0xf23a
+#define F0900_P2_STOP_S2BETA 0xf23a00c0
+#define F0900_P2_CAR_BETA_MANT 0xf23a0030
+#define F0900_P2_CAR_BETA_EXP 0xf23a000f
+
+/*P2_CARFREQ*/
+#define R0900_P2_CARFREQ 0xf23d
+#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
+#define F0900_P2_BETA_FREQ 0xf23d000f
+
+/*P2_CARHDR*/
+#define R0900_P2_CARHDR 0xf23e
+#define F0900_P2_K_FREQ_HDR 0xf23e00ff
+
+/*P2_LDT*/
+#define R0900_P2_LDT 0xf23f
+#define F0900_P2_CARLOCK_THRES 0xf23f01ff
+
+/*P2_LDT2*/
+#define R0900_P2_LDT2 0xf240
+#define F0900_P2_CARLOCK_THRES2 0xf24001ff
+
+/*P2_CFRICFG*/
+#define R0900_P2_CFRICFG 0xf241
+#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080
+#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040
+#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020
+#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010
+#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008
+#define F0900_P2_CFRINIT_CSTINC 0xf2410004
+#define F0900_P2_NEG_CFRSTEP 0xf2410001
+
+/*P2_CFRUP1*/
+#define R0900_P2_CFRUP1 0xf242
+#define F0900_P2_CFR_UP1 0xf24201ff
+
+/*P2_CFRUP0*/
+#define R0900_P2_CFRUP0 0xf243
+#define F0900_P2_CFR_UP0 0xf24300ff
+
+/*P2_CFRLOW1*/
+#define R0900_P2_CFRLOW1 0xf246
+#define F0900_P2_CFR_LOW1 0xf24601ff
+
+/*P2_CFRLOW0*/
+#define R0900_P2_CFRLOW0 0xf247
+#define F0900_P2_CFR_LOW0 0xf24700ff
+
+/*P2_CFRINIT1*/
+#define R0900_P2_CFRINIT1 0xf248
+#define F0900_P2_CFR_INIT1 0xf24801ff
+
+/*P2_CFRINIT0*/
+#define R0900_P2_CFRINIT0 0xf249
+#define F0900_P2_CFR_INIT0 0xf24900ff
+
+/*P2_CFRINC1*/
+#define R0900_P2_CFRINC1 0xf24a
+#define F0900_P2_MANUAL_CFRINC 0xf24a0080
+#define F0900_P2_CFR_INC1 0xf24a017f
+
+/*P2_CFRINC0*/
+#define R0900_P2_CFRINC0 0xf24b
+#define F0900_P2_CFR_INC0 0xf24b00f0
+
+/*P2_CFR2*/
+#define R0900_P2_CFR2 0xf24c
+#define F0900_P2_CAR_FREQ2 0xf24c01ff
+
+/*P2_CFR1*/
+#define R0900_P2_CFR1 0xf24d
+#define F0900_P2_CAR_FREQ1 0xf24d00ff
+
+/*P2_CFR0*/
+#define R0900_P2_CFR0 0xf24e
+#define F0900_P2_CAR_FREQ0 0xf24e00ff
+
+/*P2_LDI*/
+#define R0900_P2_LDI 0xf24f
+#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
+
+/*P2_TMGCFG*/
+#define R0900_P2_TMGCFG 0xf250
+#define F0900_P2_TMGLOCK_BETA 0xf25000c0
+#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020
+#define F0900_P2_DO_TIMING_CORR 0xf2500010
+#define F0900_P2_MANUAL_SCAN 0xf250000c
+#define F0900_P2_TMG_MINFREQ 0xf2500003
+
+/*P2_RTC*/
+#define R0900_P2_RTC 0xf251
+#define F0900_P2_TMGALPHA_EXP 0xf25100f0
+#define F0900_P2_TMGBETA_EXP 0xf251000f
+
+/*P2_RTCS2*/
+#define R0900_P2_RTCS2 0xf252
+#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
+#define F0900_P2_TMGBETAS2_EXP 0xf252000f
+
+/*P2_TMGTHRISE*/
+#define R0900_P2_TMGTHRISE 0xf253
+#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
+
+/*P2_TMGTHFALL*/
+#define R0900_P2_TMGTHFALL 0xf254
+#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
+
+/*P2_SFRUPRATIO*/
+#define R0900_P2_SFRUPRATIO 0xf255
+#define F0900_P2_SFR_UPRATIO 0xf25500ff
+
+/*P2_SFRLOWRATIO*/
+#define R0900_P2_SFRLOWRATIO 0xf256
+#define F0900_P2_SFR_LOWRATIO 0xf25600ff
+
+/*P2_KREFTMG*/
+#define R0900_P2_KREFTMG 0xf258
+#define F0900_P2_KREF_TMG 0xf25800ff
+
+/*P2_SFRSTEP*/
+#define R0900_P2_SFRSTEP 0xf259
+#define F0900_P2_SFR_SCANSTEP 0xf25900f0
+#define F0900_P2_SFR_CENTERSTEP 0xf259000f
+
+/*P2_TMGCFG2*/
+#define R0900_P2_TMGCFG2 0xf25a
+#define F0900_P2_DIS_AUTOSAMP 0xf25a0008
+#define F0900_P2_SCANINIT_QUART 0xf25a0004
+#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002
+#define F0900_P2_SFRRATIO_FINE 0xf25a0001
+
+/*P2_SFRINIT1*/
+#define R0900_P2_SFRINIT1 0xf25e
+#define F0900_P2_SFR_INIT1 0xf25e00ff
+
+/*P2_SFRINIT0*/
+#define R0900_P2_SFRINIT0 0xf25f
+#define F0900_P2_SFR_INIT0 0xf25f00ff
+
+/*P2_SFRUP1*/
+#define R0900_P2_SFRUP1 0xf260
+#define F0900_P2_AUTO_GUP 0xf2600080
+#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
+
+/*P2_SFRUP0*/
+#define R0900_P2_SFRUP0 0xf261
+#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
+
+/*P2_SFRLOW1*/
+#define R0900_P2_SFRLOW1 0xf262
+#define F0900_P2_AUTO_GLOW 0xf2620080
+#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
+
+/*P2_SFRLOW0*/
+#define R0900_P2_SFRLOW0 0xf263
+#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
+
+/*P2_SFR3*/
+#define R0900_P2_SFR3 0xf264
+#define F0900_P2_SYMB_FREQ3 0xf26400ff
+
+/*P2_SFR2*/
+#define R0900_P2_SFR2 0xf265
+#define F0900_P2_SYMB_FREQ2 0xf26500ff
+
+/*P2_SFR1*/
+#define R0900_P2_SFR1 0xf266
+#define F0900_P2_SYMB_FREQ1 0xf26600ff
+
+/*P2_SFR0*/
+#define R0900_P2_SFR0 0xf267
+#define F0900_P2_SYMB_FREQ0 0xf26700ff
+
+/*P2_TMGREG2*/
+#define R0900_P2_TMGREG2 0xf268
+#define F0900_P2_TMGREG2 0xf26800ff
+
+/*P2_TMGREG1*/
+#define R0900_P2_TMGREG1 0xf269
+#define F0900_P2_TMGREG1 0xf26900ff
+
+/*P2_TMGREG0*/
+#define R0900_P2_TMGREG0 0xf26a
+#define F0900_P2_TMGREG0 0xf26a00ff
+
+/*P2_TMGLOCK1*/
+#define R0900_P2_TMGLOCK1 0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
+
+/*P2_TMGLOCK0*/
+#define R0900_P2_TMGLOCK0 0xf26c
+#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
+
+/*P2_TMGOBS*/
+#define R0900_P2_TMGOBS 0xf26d
+#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
+#define F0900_P2_SCAN_SIGN 0xf26d0030
+#define F0900_P2_TMG_SCANNING 0xf26d0008
+#define F0900_P2_CHCENTERING_MODE 0xf26d0004
+#define F0900_P2_TMG_SCANFAIL 0xf26d0002
+
+/*P2_EQUALCFG*/
+#define R0900_P2_EQUALCFG 0xf26f
+#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080
+#define F0900_P2_EQUAL_ON 0xf26f0040
+#define F0900_P2_SEL_EQUALCOR 0xf26f0038
+#define F0900_P2_MU_EQUALDFE 0xf26f0007
+
+/*P2_EQUAI1*/
+#define R0900_P2_EQUAI1 0xf270
+#define F0900_P2_EQUA_ACCI1 0xf27001ff
+
+/*P2_EQUAQ1*/
+#define R0900_P2_EQUAQ1 0xf271
+#define F0900_P2_EQUA_ACCQ1 0xf27101ff
+
+/*P2_EQUAI2*/
+#define R0900_P2_EQUAI2 0xf272
+#define F0900_P2_EQUA_ACCI2 0xf27201ff
+
+/*P2_EQUAQ2*/
+#define R0900_P2_EQUAQ2 0xf273
+#define F0900_P2_EQUA_ACCQ2 0xf27301ff
+
+/*P2_EQUAI3*/
+#define R0900_P2_EQUAI3 0xf274
+#define F0900_P2_EQUA_ACCI3 0xf27401ff
+
+/*P2_EQUAQ3*/
+#define R0900_P2_EQUAQ3 0xf275
+#define F0900_P2_EQUA_ACCQ3 0xf27501ff
+
+/*P2_EQUAI4*/
+#define R0900_P2_EQUAI4 0xf276
+#define F0900_P2_EQUA_ACCI4 0xf27601ff
+
+/*P2_EQUAQ4*/
+#define R0900_P2_EQUAQ4 0xf277
+#define F0900_P2_EQUA_ACCQ4 0xf27701ff
+
+/*P2_EQUAI5*/
+#define R0900_P2_EQUAI5 0xf278
+#define F0900_P2_EQUA_ACCI5 0xf27801ff
+
+/*P2_EQUAQ5*/
+#define R0900_P2_EQUAQ5 0xf279
+#define F0900_P2_EQUA_ACCQ5 0xf27901ff
+
+/*P2_EQUAI6*/
+#define R0900_P2_EQUAI6 0xf27a
+#define F0900_P2_EQUA_ACCI6 0xf27a01ff
+
+/*P2_EQUAQ6*/
+#define R0900_P2_EQUAQ6 0xf27b
+#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
+
+/*P2_EQUAI7*/
+#define R0900_P2_EQUAI7 0xf27c
+#define F0900_P2_EQUA_ACCI7 0xf27c01ff
+
+/*P2_EQUAQ7*/
+#define R0900_P2_EQUAQ7 0xf27d
+#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
+
+/*P2_EQUAI8*/
+#define R0900_P2_EQUAI8 0xf27e
+#define F0900_P2_EQUA_ACCI8 0xf27e01ff
+
+/*P2_EQUAQ8*/
+#define R0900_P2_EQUAQ8 0xf27f
+#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
+
+/*P2_NNOSDATAT1*/
+#define R0900_P2_NNOSDATAT1 0xf280
+#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
+
+/*P2_NNOSDATAT0*/
+#define R0900_P2_NNOSDATAT0 0xf281
+#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
+
+/*P2_NNOSDATA1*/
+#define R0900_P2_NNOSDATA1 0xf282
+#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
+
+/*P2_NNOSDATA0*/
+#define R0900_P2_NNOSDATA0 0xf283
+#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
+
+/*P2_NNOSPLHT1*/
+#define R0900_P2_NNOSPLHT1 0xf284
+#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
+
+/*P2_NNOSPLHT0*/
+#define R0900_P2_NNOSPLHT0 0xf285
+#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
+
+/*P2_NNOSPLH1*/
+#define R0900_P2_NNOSPLH1 0xf286
+#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
+
+/*P2_NNOSPLH0*/
+#define R0900_P2_NNOSPLH0 0xf287
+#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
+
+/*P2_NOSDATAT1*/
+#define R0900_P2_NOSDATAT1 0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
+
+/*P2_NOSDATAT0*/
+#define R0900_P2_NOSDATAT0 0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
+
+/*P2_NOSDATA1*/
+#define R0900_P2_NOSDATA1 0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
+
+/*P2_NOSDATA0*/
+#define R0900_P2_NOSDATA0 0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
+
+/*P2_NOSPLHT1*/
+#define R0900_P2_NOSPLHT1 0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
+
+/*P2_NOSPLHT0*/
+#define R0900_P2_NOSPLHT0 0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
+
+/*P2_NOSPLH1*/
+#define R0900_P2_NOSPLH1 0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
+
+/*P2_NOSPLH0*/
+#define R0900_P2_NOSPLH0 0xf28f
+#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
+
+/*P2_CAR2CFG*/
+#define R0900_P2_CAR2CFG 0xf290
+#define F0900_P2_DESCRAMB_OFF 0xf2900080
+#define F0900_P2_PN4_SELECT 0xf2900040
+#define F0900_P2_CFR2_STOPDVBS1 0xf2900020
+#define F0900_P2_STOP_CFR2UPDATE 0xf2900010
+#define F0900_P2_STOP_NCO2UPDATE 0xf2900008
+#define F0900_P2_ROTA2ON 0xf2900004
+#define F0900_P2_PH_DET_ALGO2 0xf2900003
+
+/*P2_ACLC2*/
+#define R0900_P2_ACLC2 0xf291
+#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040
+#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030
+#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f
+
+/*P2_BCLC2*/
+#define R0900_P2_BCLC2 0xf292
+#define F0900_P2_DVBS2_NIP 0xf2920080
+#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040
+#define F0900_P2_CAR2_BETA_MANT 0xf2920030
+#define F0900_P2_CAR2_BETA_EXP 0xf292000f
+
+/*P2_CFR22*/
+#define R0900_P2_CFR22 0xf293
+#define F0900_P2_CAR2_FREQ2 0xf29301ff
+
+/*P2_CFR21*/
+#define R0900_P2_CFR21 0xf294
+#define F0900_P2_CAR2_FREQ1 0xf29400ff
+
+/*P2_CFR20*/
+#define R0900_P2_CFR20 0xf295
+#define F0900_P2_CAR2_FREQ0 0xf29500ff
+
+/*P2_ACLC2S2Q*/
+#define R0900_P2_ACLC2S2Q 0xf297
+#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
+#define F0900_P2_CAR2S2_QADERAT 0xf2970040
+#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
+
+/*P2_ACLC2S28*/
+#define R0900_P2_ACLC2S28 0xf298
+#define F0900_P2_OLDI3Q_MODE 0xf2980080
+#define F0900_P2_CAR2S2_8ADERAT 0xf2980040
+#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
+
+/*P2_ACLC2S216A*/
+#define R0900_P2_ACLC2S216A 0xf299
+#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
+#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
+
+/*P2_ACLC2S232A*/
+#define R0900_P2_ACLC2S232A 0xf29a
+#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
+#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
+
+/*P2_BCLC2S2Q*/
+#define R0900_P2_BCLC2S2Q 0xf29c
+#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080
+#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040
+#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
+
+/*P2_BCLC2S28*/
+#define R0900_P2_BCLC2S28 0xf29d
+#define F0900_P2_DVBS2S28_NIP 0xf29d0080
+#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040
+#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
+
+/*P2_BCLC2S216A*/
+#define R0900_P2_BCLC2S216A 0xf29e
+#define F0900_P2_DVBS2S216A_NIP 0xf29e0080
+#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040
+#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030
+#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f
+
+/*P2_BCLC2S232A*/
+#define R0900_P2_BCLC2S232A 0xf29f
+#define F0900_P2_DVBS2S232A_NIP 0xf29f0080
+#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040
+#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030
+#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f
+
+/*P2_PLROOT2*/
+#define R0900_P2_PLROOT2 0xf2ac
+#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080
+#define F0900_P2_LONGFR_DISABLE 0xf2ac0040
+#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020
+#define F0900_P2_SHORTFR_AVOID 0xf2ac0010
+#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
+#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
+
+/*P2_PLROOT1*/
+#define R0900_P2_PLROOT1 0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
+
+/*P2_PLROOT0*/
+#define R0900_P2_PLROOT0 0xf2ae
+#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
+
+/*P2_MODCODLST0*/
+#define R0900_P2_MODCODLST0 0xf2b0
+#define F0900_P2_EN_TOKEN31 0xf2b00080
+#define F0900_P2_SYNCTAG_SELECT 0xf2b00040
+#define F0900_P2_MODCODRQ_MODE 0xf2b00030
+
+/*P2_MODCODLST1*/
+#define R0900_P2_MODCODLST1 0xf2b1
+#define F0900_P2_DIS_MODCOD29 0xf2b100f0
+#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
+
+/*P2_MODCODLST2*/
+#define R0900_P2_MODCODLST2 0xf2b2
+#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
+#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
+
+/*P2_MODCODLST3*/
+#define R0900_P2_MODCODLST3 0xf2b3
+#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
+#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
+
+/*P2_MODCODLST4*/
+#define R0900_P2_MODCODLST4 0xf2b4
+#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
+#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
+
+/*P2_MODCODLST5*/
+#define R0900_P2_MODCODLST5 0xf2b5
+#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
+#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
+
+/*P2_MODCODLST6*/
+#define R0900_P2_MODCODLST6 0xf2b6
+#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
+#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
+
+/*P2_MODCODLST7*/
+#define R0900_P2_MODCODLST7 0xf2b7
+#define F0900_P2_DIS_8P_9_10 0xf2b700f0
+#define F0900_P2_DIS_8P_8_9 0xf2b7000f
+
+/*P2_MODCODLST8*/
+#define R0900_P2_MODCODLST8 0xf2b8
+#define F0900_P2_DIS_8P_5_6 0xf2b800f0
+#define F0900_P2_DIS_8P_3_4 0xf2b8000f
+
+/*P2_MODCODLST9*/
+#define R0900_P2_MODCODLST9 0xf2b9
+#define F0900_P2_DIS_8P_2_3 0xf2b900f0
+#define F0900_P2_DIS_8P_3_5 0xf2b9000f
+
+/*P2_MODCODLSTA*/
+#define R0900_P2_MODCODLSTA 0xf2ba
+#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
+#define F0900_P2_DIS_QP_8_9 0xf2ba000f
+
+/*P2_MODCODLSTB*/
+#define R0900_P2_MODCODLSTB 0xf2bb
+#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
+#define F0900_P2_DIS_QP_4_5 0xf2bb000f
+
+/*P2_MODCODLSTC*/
+#define R0900_P2_MODCODLSTC 0xf2bc
+#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
+#define F0900_P2_DIS_QP_2_3 0xf2bc000f
+
+/*P2_MODCODLSTD*/
+#define R0900_P2_MODCODLSTD 0xf2bd
+#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
+#define F0900_P2_DIS_QP_1_2 0xf2bd000f
+
+/*P2_MODCODLSTE*/
+#define R0900_P2_MODCODLSTE 0xf2be
+#define F0900_P2_DIS_QP_2_5 0xf2be00f0
+#define F0900_P2_DIS_QP_1_3 0xf2be000f
+
+/*P2_MODCODLSTF*/
+#define R0900_P2_MODCODLSTF 0xf2bf
+#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
+#define F0900_P2_DDEMOD_SET 0xf2bf0002
+#define F0900_P2_DDEMOD_MASK 0xf2bf0001
+
+/*P2_DMDRESCFG*/
+#define R0900_P2_DMDRESCFG 0xf2c6
+#define F0900_P2_DMDRES_RESET 0xf2c60080
+#define F0900_P2_DMDRES_NOISESQR 0xf2c60010
+#define F0900_P2_DMDRES_STRALL 0xf2c60008
+#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
+#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
+#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001
+
+/*P2_DMDRESADR*/
+#define R0900_P2_DMDRESADR 0xf2c7
+#define F0900_P2_SUSP_PREDCANAL 0xf2c70080
+#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
+#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
+#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
+
+/*P2_DMDRESDATA7*/
+#define R0900_P2_DMDRESDATA7 0xf2c8
+#define F0900_P2_DMDRES_DATA7 0xf2c800ff
+
+/*P2_DMDRESDATA6*/
+#define R0900_P2_DMDRESDATA6 0xf2c9
+#define F0900_P2_DMDRES_DATA6 0xf2c900ff
+
+/*P2_DMDRESDATA5*/
+#define R0900_P2_DMDRESDATA5 0xf2ca
+#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
+
+/*P2_DMDRESDATA4*/
+#define R0900_P2_DMDRESDATA4 0xf2cb
+#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
+
+/*P2_DMDRESDATA3*/
+#define R0900_P2_DMDRESDATA3 0xf2cc
+#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
+
+/*P2_DMDRESDATA2*/
+#define R0900_P2_DMDRESDATA2 0xf2cd
+#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
+
+/*P2_DMDRESDATA1*/
+#define R0900_P2_DMDRESDATA1 0xf2ce
+#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
+
+/*P2_DMDRESDATA0*/
+#define R0900_P2_DMDRESDATA0 0xf2cf
+#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
+
+/*P2_FFEI1*/
+#define R0900_P2_FFEI1 0xf2d0
+#define F0900_P2_FFE_ACCI1 0xf2d001ff
+
+/*P2_FFEQ1*/
+#define R0900_P2_FFEQ1 0xf2d1
+#define F0900_P2_FFE_ACCQ1 0xf2d101ff
+
+/*P2_FFEI2*/
+#define R0900_P2_FFEI2 0xf2d2
+#define F0900_P2_FFE_ACCI2 0xf2d201ff
+
+/*P2_FFEQ2*/
+#define R0900_P2_FFEQ2 0xf2d3
+#define F0900_P2_FFE_ACCQ2 0xf2d301ff
+
+/*P2_FFEI3*/
+#define R0900_P2_FFEI3 0xf2d4
+#define F0900_P2_FFE_ACCI3 0xf2d401ff
+
+/*P2_FFEQ3*/
+#define R0900_P2_FFEQ3 0xf2d5
+#define F0900_P2_FFE_ACCQ3 0xf2d501ff
+
+/*P2_FFEI4*/
+#define R0900_P2_FFEI4 0xf2d6
+#define F0900_P2_FFE_ACCI4 0xf2d601ff
+
+/*P2_FFEQ4*/
+#define R0900_P2_FFEQ4 0xf2d7
+#define F0900_P2_FFE_ACCQ4 0xf2d701ff
+
+/*P2_FFECFG*/
+#define R0900_P2_FFECFG 0xf2d8
+#define F0900_P2_EQUALFFE_ON 0xf2d80040
+#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030
+#define F0900_P2_MU_EQUALFFE 0xf2d80007
+
+/*P2_TNRCFG*/
+#define R0900_P2_TNRCFG 0xf2e0
+#define F0900_P2_TUN_ACKFAIL 0xf2e00080
+#define F0900_P2_TUN_TYPE 0xf2e00070
+#define F0900_P2_TUN_SECSTOP 0xf2e00008
+#define F0900_P2_TUN_VCOSRCH 0xf2e00004
+#define F0900_P2_TUN_MADDRESS 0xf2e00003
+
+/*P2_TNRCFG2*/
+#define R0900_P2_TNRCFG2 0xf2e1
+#define F0900_P2_TUN_IQSWAP 0xf2e10080
+#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040
+#define F0900_P2_STB6120_DBLI2C 0xf2e10020
+#define F0900_P2_DIS_FCCK 0xf2e10010
+#define F0900_P2_DIS_LPEN 0xf2e10008
+#define F0900_P2_DIS_BWCALC 0xf2e10004
+#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
+#define F0900_P2_DIS_2BWAGC1 0xf2e10001
+
+/*P2_TNRXTAL*/
+#define R0900_P2_TNRXTAL 0xf2e4
+#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0
+#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
+
+/*P2_TNRSTEPS*/
+#define R0900_P2_TNRSTEPS 0xf2e7
+#define F0900_P2_TUNER_BW1P6 0xf2e70080
+#define F0900_P2_BWINC_OFFSET 0xf2e70070
+#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
+#define F0900_P2_TUN_BWOFFSET 0xf2e70107
+
+/*P2_TNRGAIN*/
+#define R0900_P2_TNRGAIN 0xf2e8
+#define F0900_P2_TUN_KDIVEN 0xf2e800c0
+#define F0900_P2_STB6X00_OCK 0xf2e80030
+#define F0900_P2_TUN_GAIN 0xf2e8000f
+
+/*P2_TNRRF1*/
+#define R0900_P2_TNRRF1 0xf2e9
+#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
+
+/*P2_TNRRF0*/
+#define R0900_P2_TNRRF0 0xf2ea
+#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
+
+/*P2_TNRBW*/
+#define R0900_P2_TNRBW 0xf2eb
+#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
+#define F0900_P2_TUN_BW 0xf2eb003f
+
+/*P2_TNRADJ*/
+#define R0900_P2_TNRADJ 0xf2ec
+#define F0900_P2_STB61X0_RCLK 0xf2ec0080
+#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
+#define F0900_P2_STB6X00_DLB 0xf2ec0038
+#define F0900_P2_STB6000_FCL 0xf2ec0007
+
+/*P2_TNRCTL2*/
+#define R0900_P2_TNRCTL2 0xf2ed
+#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080
+#define F0900_P2_STB61X0_LCP0 0xf2ed0040
+#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020
+#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010
+#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008
+#define F0900_P2_STB6110_LPT 0xf2ed0004
+#define F0900_P2_STB6110_RX 0xf2ed0002
+#define F0900_P2_STB6110_SYN 0xf2ed0001
+
+/*P2_TNRCFG3*/
+#define R0900_P2_TNRCFG3 0xf2ee
+#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080
+#define F0900_P2_STB6120_INVORDER 0xf2ee0040
+#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020
+#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
+#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
+
+/*P2_TNRLAUNCH*/
+#define R0900_P2_TNRLAUNCH 0xf2f0
+
+/*P2_TNRLD*/
+#define R0900_P2_TNRLD 0xf2f0
+#define F0900_P2_TUNLD_VCOING 0xf2f00080
+#define F0900_P2_TUN_REG1FAIL 0xf2f00040
+#define F0900_P2_TUN_REG2FAIL 0xf2f00020
+#define F0900_P2_TUN_REG3FAIL 0xf2f00010
+#define F0900_P2_TUN_REG4FAIL 0xf2f00008
+#define F0900_P2_TUN_REG5FAIL 0xf2f00004
+#define F0900_P2_TUN_BWING 0xf2f00002
+#define F0900_P2_TUN_LOCKED 0xf2f00001
+
+/*P2_TNROBSL*/
+#define R0900_P2_TNROBSL 0xf2f6
+#define F0900_P2_TUN_I2CABORTED 0xf2f60080
+#define F0900_P2_TUN_LPEN 0xf2f60040
+#define F0900_P2_TUN_FCCK 0xf2f60020
+#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
+#define F0900_P2_TUN_PROGDONE 0xf2f6000c
+#define F0900_P2_TUN_RFRESTE1 0xf2f60003
+
+/*P2_TNRRESTE*/
+#define R0900_P2_TNRRESTE 0xf2f7
+#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
+
+/*P2_SMAPCOEF7*/
+#define R0900_P2_SMAPCOEF7 0xf300
+#define F0900_P2_DIS_QSCALE 0xf3000080
+#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
+
+/*P2_SMAPCOEF6*/
+#define R0900_P2_SMAPCOEF6 0xf301
+#define F0900_P2_DIS_NEWSCALE 0xf3010008
+#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
+#define F0900_P2_OLD_8PSKLLR1 0xf3010002
+#define F0900_P2_DIS_AB8PSK 0xf3010001
+
+/*P2_SMAPCOEF5*/
+#define R0900_P2_SMAPCOEF5 0xf302
+#define F0900_P2_DIS_8SCALE 0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
+
+/*P2_DMDPLHSTAT*/
+#define R0900_P2_DMDPLHSTAT 0xf320
+#define F0900_P2_PLH_STATISTIC 0xf32000ff
+
+/*P2_LOCKTIME3*/
+#define R0900_P2_LOCKTIME3 0xf322
+#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
+
+/*P2_LOCKTIME2*/
+#define R0900_P2_LOCKTIME2 0xf323
+#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
+
+/*P2_LOCKTIME1*/
+#define R0900_P2_LOCKTIME1 0xf324
+#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
+
+/*P2_LOCKTIME0*/
+#define R0900_P2_LOCKTIME0 0xf325
+#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
+
+/*P2_VITSCALE*/
+#define R0900_P2_VITSCALE 0xf332
+#define F0900_P2_NVTH_NOSRANGE 0xf3320080
+#define F0900_P2_VERROR_MAXMODE 0xf3320040
+#define F0900_P2_KDIV_MODE 0xf3320030
+#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
+#define F0900_P2_DELOCK_PRFLOSS 0xf3320004
+#define F0900_P2_DIS_RSFLOCK 0xf3320002
+
+/*P2_FECM*/
+#define R0900_P2_FECM 0xf333
+#define F0900_P2_DSS_DVB 0xf3330080
+#define F0900_P2_DEMOD_BYPASS 0xf3330040
+#define F0900_P2_CMP_SLOWMODE 0xf3330020
+#define F0900_P2_DSS_SRCH 0xf3330010
+#define F0900_P2_DIFF_MODEVIT 0xf3330004
+#define F0900_P2_SYNCVIT 0xf3330002
+#define F0900_P2_IQINV 0xf3330001
+
+/*P2_VTH12*/
+#define R0900_P2_VTH12 0xf334
+#define F0900_P2_VTH12 0xf33400ff
+
+/*P2_VTH23*/
+#define R0900_P2_VTH23 0xf335
+#define F0900_P2_VTH23 0xf33500ff
+
+/*P2_VTH34*/
+#define R0900_P2_VTH34 0xf336
+#define F0900_P2_VTH34 0xf33600ff
+
+/*P2_VTH56*/
+#define R0900_P2_VTH56 0xf337
+#define F0900_P2_VTH56 0xf33700ff
+
+/*P2_VTH67*/
+#define R0900_P2_VTH67 0xf338
+#define F0900_P2_VTH67 0xf33800ff
+
+/*P2_VTH78*/
+#define R0900_P2_VTH78 0xf339
+#define F0900_P2_VTH78 0xf33900ff
+
+/*P2_VITCURPUN*/
+#define R0900_P2_VITCURPUN 0xf33a
+#define F0900_P2_VIT_MAPPING 0xf33a00e0
+#define F0900_P2_VIT_CURPUN 0xf33a001f
+
+/*P2_VERROR*/
+#define R0900_P2_VERROR 0xf33b
+#define F0900_P2_REGERR_VIT 0xf33b00ff
+
+/*P2_PRVIT*/
+#define R0900_P2_PRVIT 0xf33c
+#define F0900_P2_DIS_VTHLOCK 0xf33c0040
+#define F0900_P2_E7_8VIT 0xf33c0020
+#define F0900_P2_E6_7VIT 0xf33c0010
+#define F0900_P2_E5_6VIT 0xf33c0008
+#define F0900_P2_E3_4VIT 0xf33c0004
+#define F0900_P2_E2_3VIT 0xf33c0002
+#define F0900_P2_E1_2VIT 0xf33c0001
+
+/*P2_VAVSRVIT*/
+#define R0900_P2_VAVSRVIT 0xf33d
+#define F0900_P2_AMVIT 0xf33d0080
+#define F0900_P2_FROZENVIT 0xf33d0040
+#define F0900_P2_SNVIT 0xf33d0030
+#define F0900_P2_TOVVIT 0xf33d000c
+#define F0900_P2_HYPVIT 0xf33d0003
+
+/*P2_VSTATUSVIT*/
+#define R0900_P2_VSTATUSVIT 0xf33e
+#define F0900_P2_VITERBI_ON 0xf33e0080
+#define F0900_P2_END_LOOPVIT 0xf33e0040
+#define F0900_P2_VITERBI_DEPRF 0xf33e0020
+#define F0900_P2_PRFVIT 0xf33e0010
+#define F0900_P2_LOCKEDVIT 0xf33e0008
+#define F0900_P2_VITERBI_DELOCK 0xf33e0004
+#define F0900_P2_VIT_DEMODSEL 0xf33e0002
+#define F0900_P2_VITERBI_COMPOUT 0xf33e0001
+
+/*P2_VTHINUSE*/
+#define R0900_P2_VTHINUSE 0xf33f
+#define F0900_P2_VIT_INUSE 0xf33f00ff
+
+/*P2_KDIV12*/
+#define R0900_P2_KDIV12 0xf340
+#define F0900_P2_KDIV12_MANUAL 0xf3400080
+#define F0900_P2_K_DIVIDER_12 0xf340007f
+
+/*P2_KDIV23*/
+#define R0900_P2_KDIV23 0xf341
+#define F0900_P2_KDIV23_MANUAL 0xf3410080
+#define F0900_P2_K_DIVIDER_23 0xf341007f
+
+/*P2_KDIV34*/
+#define R0900_P2_KDIV34 0xf342
+#define F0900_P2_KDIV34_MANUAL 0xf3420080
+#define F0900_P2_K_DIVIDER_34 0xf342007f
+
+/*P2_KDIV56*/
+#define R0900_P2_KDIV56 0xf343
+#define F0900_P2_KDIV56_MANUAL 0xf3430080
+#define F0900_P2_K_DIVIDER_56 0xf343007f
+
+/*P2_KDIV67*/
+#define R0900_P2_KDIV67 0xf344
+#define F0900_P2_KDIV67_MANUAL 0xf3440080
+#define F0900_P2_K_DIVIDER_67 0xf344007f
+
+/*P2_KDIV78*/
+#define R0900_P2_KDIV78 0xf345
+#define F0900_P2_KDIV78_MANUAL 0xf3450080
+#define F0900_P2_K_DIVIDER_78 0xf345007f
+
+/*P2_PDELCTRL1*/
+#define R0900_P2_PDELCTRL1 0xf350
+#define F0900_P2_INV_MISMASK 0xf3500080
+#define F0900_P2_FORCE_ACCEPTED 0xf3500040
+#define F0900_P2_FILTER_EN 0xf3500020
+#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010
+#define F0900_P2_HYSTEN 0xf3500008
+#define F0900_P2_HYSTSWRST 0xf3500004
+#define F0900_P2_EN_MIS00 0xf3500002
+#define F0900_P2_ALGOSWRST 0xf3500001
+
+/*P2_PDELCTRL2*/
+#define R0900_P2_PDELCTRL2 0xf351
+#define F0900_P2_FORCE_CONTINUOUS 0xf3510080
+#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
+#define F0900_P2_USER_PKTDELIN_NB 0xf3510020
+#define F0900_P2_FORCE_LOCKED 0xf3510010
+#define F0900_P2_DATA_UNBBSCRAM 0xf3510008
+#define F0900_P2_FORCE_LONGPKT 0xf3510004
+#define F0900_P2_FRAME_MODE 0xf3510002
+
+/*P2_HYSTTHRESH*/
+#define R0900_P2_HYSTTHRESH 0xf354
+#define F0900_P2_UNLCK_THRESH 0xf35400f0
+#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
+
+/*P2_ISIENTRY*/
+#define R0900_P2_ISIENTRY 0xf35e
+#define F0900_P2_ISI_ENTRY 0xf35e00ff
+
+/*P2_ISIBITENA*/
+#define R0900_P2_ISIBITENA 0xf35f
+#define F0900_P2_ISI_BIT_EN 0xf35f00ff
+
+/*P2_MATSTR1*/
+#define R0900_P2_MATSTR1 0xf360
+#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
+
+/*P2_MATSTR0*/
+#define R0900_P2_MATSTR0 0xf361
+#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
+
+/*P2_UPLSTR1*/
+#define R0900_P2_UPLSTR1 0xf362
+#define F0900_P2_UPL_CURRENT1 0xf36200ff
+
+/*P2_UPLSTR0*/
+#define R0900_P2_UPLSTR0 0xf363
+#define F0900_P2_UPL_CURRENT0 0xf36300ff
+
+/*P2_DFLSTR1*/
+#define R0900_P2_DFLSTR1 0xf364
+#define F0900_P2_DFL_CURRENT1 0xf36400ff
+
+/*P2_DFLSTR0*/
+#define R0900_P2_DFLSTR0 0xf365
+#define F0900_P2_DFL_CURRENT0 0xf36500ff
+
+/*P2_SYNCSTR*/
+#define R0900_P2_SYNCSTR 0xf366
+#define F0900_P2_SYNC_CURRENT 0xf36600ff
+
+/*P2_SYNCDSTR1*/
+#define R0900_P2_SYNCDSTR1 0xf367
+#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
+
+/*P2_SYNCDSTR0*/
+#define R0900_P2_SYNCDSTR0 0xf368
+#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
+
+/*P2_PDELSTATUS1*/
+#define R0900_P2_PDELSTATUS1 0xf369
+#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
+#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
+#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
+#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
+#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
+#define F0900_P2_BBHCRCKO 0xf3690004
+#define F0900_P2_PKTDELIN_LOCK 0xf3690002
+#define F0900_P2_FIRST_LOCK 0xf3690001
+
+/*P2_PDELSTATUS2*/
+#define R0900_P2_PDELSTATUS2 0xf36a
+#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080
+#define F0900_P2_FRAME_MODCOD 0xf36a007c
+#define F0900_P2_FRAME_TYPE 0xf36a0003
+
+/*P2_BBFCRCKO1*/
+#define R0900_P2_BBFCRCKO1 0xf36b
+#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
+
+/*P2_BBFCRCKO0*/
+#define R0900_P2_BBFCRCKO0 0xf36c
+#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
+
+/*P2_UPCRCKO1*/
+#define R0900_P2_UPCRCKO1 0xf36d
+#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
+
+/*P2_UPCRCKO0*/
+#define R0900_P2_UPCRCKO0 0xf36e
+#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
+
+/*P2_TSSTATEM*/
+#define R0900_P2_TSSTATEM 0xf370
+#define F0900_P2_TSDIL_ON 0xf3700080
+#define F0900_P2_TSSKIPRS_ON 0xf3700040
+#define F0900_P2_TSRS_ON 0xf3700020
+#define F0900_P2_TSDESCRAMB_ON 0xf3700010
+#define F0900_P2_TSFRAME_MODE 0xf3700008
+#define F0900_P2_TS_DISABLE 0xf3700004
+#define F0900_P2_TSACM_MODE 0xf3700002
+#define F0900_P2_TSOUT_NOSYNC 0xf3700001
+
+/*P2_TSCFGH*/
+#define R0900_P2_TSCFGH 0xf372
+#define F0900_P2_TSFIFO_DVBCI 0xf3720080
+#define F0900_P2_TSFIFO_SERIAL 0xf3720040
+#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
+#define F0900_P2_TSFIFO_DUTY50 0xf3720010
+#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
+#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
+#define F0900_P2_RST_HWARE 0xf3720001
+
+/*P2_TSCFGM*/
+#define R0900_P2_TSCFGM 0xf373
+#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
+#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
+#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010
+#define F0900_P2_TSFIFO_BITSPEED 0xf3730008
+#define F0900_P2_NPD_SPECDVBS2 0xf3730004
+#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002
+#define F0900_P2_TSFIFO_INVDATA 0xf3730001
+
+/*P2_TSCFGL*/
+#define R0900_P2_TSCFGL 0xf374
+#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
+#define F0900_P2_BCHERROR_MODE 0xf3740030
+#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
+#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
+#define F0900_P2_TSFIFO_DPUNACT 0xf3740002
+#define F0900_P2_TSFIFO_NPDOFF 0xf3740001
+
+/*P2_TSINSDELH*/
+#define R0900_P2_TSINSDELH 0xf376
+#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
+#define F0900_P2_TSDEL_XXHEADER 0xf3760040
+#define F0900_P2_TSDEL_BBHEADER 0xf3760020
+#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
+#define F0900_P2_TSINSDEL_ISCR 0xf3760008
+#define F0900_P2_TSINSDEL_NPD 0xf3760004
+#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
+#define F0900_P2_TSINSDEL_CRC8 0xf3760001
+
+/*P2_TSSPEED*/
+#define R0900_P2_TSSPEED 0xf380
+#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
+
+/*P2_TSSTATUS*/
+#define R0900_P2_TSSTATUS 0xf381
+#define F0900_P2_TSFIFO_LINEOK 0xf3810080
+#define F0900_P2_TSFIFO_ERROR 0xf3810040
+#define F0900_P2_TSFIFO_DATA7 0xf3810020
+#define F0900_P2_TSFIFO_NOSYNC 0xf3810010
+#define F0900_P2_ISCR_INITIALIZED 0xf3810008
+#define F0900_P2_ISCR_UPDATED 0xf3810004
+#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002
+#define F0900_P2_DIL_READY 0xf3810001
+
+/*P2_TSSTATUS2*/
+#define R0900_P2_TSSTATUS2 0xf382
+#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
+#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
+#define F0900_P2_DILXX_RESET 0xf3820020
+#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
+#define F0900_P2_TSFIFO_LINENOK 0xf3820008
+#define F0900_P2_BITSPEED_EVENT 0xf3820004
+#define F0900_P2_SCRAMBDETECT 0xf3820002
+#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001
+
+/*P2_TSBITRATE1*/
+#define R0900_P2_TSBITRATE1 0xf383
+#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
+
+/*P2_TSBITRATE0*/
+#define R0900_P2_TSBITRATE0 0xf384
+#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
+
+/*P2_ERRCTRL1*/
+#define R0900_P2_ERRCTRL1 0xf398
+#define F0900_P2_ERR_SOURCE1 0xf39800f0
+#define F0900_P2_NUM_EVENT1 0xf3980007
+
+/*P2_ERRCNT12*/
+#define R0900_P2_ERRCNT12 0xf399
+#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define F0900_P2_ERR_CNT12 0xf399007f
+
+/*P2_ERRCNT11*/
+#define R0900_P2_ERRCNT11 0xf39a
+#define F0900_P2_ERR_CNT11 0xf39a00ff
+
+/*P2_ERRCNT10*/
+#define R0900_P2_ERRCNT10 0xf39b
+#define F0900_P2_ERR_CNT10 0xf39b00ff
+
+/*P2_ERRCTRL2*/
+#define R0900_P2_ERRCTRL2 0xf39c
+#define F0900_P2_ERR_SOURCE2 0xf39c00f0
+#define F0900_P2_NUM_EVENT2 0xf39c0007
+
+/*P2_ERRCNT22*/
+#define R0900_P2_ERRCNT22 0xf39d
+#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define F0900_P2_ERR_CNT22 0xf39d007f
+
+/*P2_ERRCNT21*/
+#define R0900_P2_ERRCNT21 0xf39e
+#define F0900_P2_ERR_CNT21 0xf39e00ff
+
+/*P2_ERRCNT20*/
+#define R0900_P2_ERRCNT20 0xf39f
+#define F0900_P2_ERR_CNT20 0xf39f00ff
+
+/*P2_FECSPY*/
+#define R0900_P2_FECSPY 0xf3a0
+#define F0900_P2_SPY_ENABLE 0xf3a00080
+#define F0900_P2_NO_SYNCBYTE 0xf3a00040
+#define F0900_P2_SERIAL_MODE 0xf3a00020
+#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
+#define F0900_P2_BER_PACKMODE 0xf3a00008
+#define F0900_P2_BERMETER_LMODE 0xf3a00002
+#define F0900_P2_BERMETER_RESET 0xf3a00001
+
+/*P2_FSPYCFG*/
+#define R0900_P2_FSPYCFG 0xf3a1
+#define F0900_P2_FECSPY_INPUT 0xf3a100c0
+#define F0900_P2_RST_ON_ERROR 0xf3a10020
+#define F0900_P2_ONE_SHOT 0xf3a10010
+#define F0900_P2_I2C_MODE 0xf3a1000c
+#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
+
+/*P2_FSPYDATA*/
+#define R0900_P2_FSPYDATA 0xf3a2
+#define F0900_P2_SPY_STUFFING 0xf3a20080
+#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040
+#define F0900_P2_SPY_CNULLPKT 0xf3a20020
+#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
+
+/*P2_FSPYOUT*/
+#define R0900_P2_FSPYOUT 0xf3a3
+#define F0900_P2_FSPY_DIRECT 0xf3a30080
+#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038
+#define F0900_P2_STUFF_MODE 0xf3a30007
+
+/*P2_FSTATUS*/
+#define R0900_P2_FSTATUS 0xf3a4
+#define F0900_P2_SPY_ENDSIM 0xf3a40080
+#define F0900_P2_VALID_SIM 0xf3a40040
+#define F0900_P2_FOUND_SIGNAL 0xf3a40020
+#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
+#define F0900_P2_RESULT_STATE 0xf3a4000f
+
+/*P2_FBERCPT4*/
+#define R0900_P2_FBERCPT4 0xf3a8
+#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
+
+/*P2_FBERCPT3*/
+#define R0900_P2_FBERCPT3 0xf3a9
+#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
+
+/*P2_FBERCPT2*/
+#define R0900_P2_FBERCPT2 0xf3aa
+#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
+
+/*P2_FBERCPT1*/
+#define R0900_P2_FBERCPT1 0xf3ab
+#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
+
+/*P2_FBERCPT0*/
+#define R0900_P2_FBERCPT0 0xf3ac
+#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
+
+/*P2_FBERERR2*/
+#define R0900_P2_FBERERR2 0xf3ad
+#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
+
+/*P2_FBERERR1*/
+#define R0900_P2_FBERERR1 0xf3ae
+#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
+
+/*P2_FBERERR0*/
+#define R0900_P2_FBERERR0 0xf3af
+#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
+
+/*P2_FSPYBER*/
+#define R0900_P2_FSPYBER 0xf3b2
+#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040
+#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020
+#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
+#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
+#define F0900_P2_FSPYBER_CTIME 0xf3b20007
+
+/*P1_IQCONST*/
+#define R0900_P1_IQCONST 0xf400
+#define F0900_P1_CONSTEL_SELECT 0xf4000060
+#define F0900_P1_IQSYMB_SEL 0xf400001f
+
+/*P1_NOSCFG*/
+#define R0900_P1_NOSCFG 0xf401
+#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
+#define F0900_P1_NOSPLH_BETA 0xf4010018
+#define F0900_P1_NOSDATA_BETA 0xf4010007
+
+/*P1_ISYMB*/
+#define R0900_P1_ISYMB 0xf402
+#define F0900_P1_I_SYMBOL 0xf40201ff
+
+/*P1_QSYMB*/
+#define R0900_P1_QSYMB 0xf403
+#define F0900_P1_Q_SYMBOL 0xf40301ff
+
+/*P1_AGC1CFG*/
+#define R0900_P1_AGC1CFG 0xf404
+#define F0900_P1_DC_FROZEN 0xf4040080
+#define F0900_P1_DC_CORRECT 0xf4040040
+#define F0900_P1_AMM_FROZEN 0xf4040020
+#define F0900_P1_AMM_CORRECT 0xf4040010
+#define F0900_P1_QUAD_FROZEN 0xf4040008
+#define F0900_P1_QUAD_CORRECT 0xf4040004
+#define F0900_P1_DCCOMP_SLOW 0xf4040002
+#define F0900_P1_IQMISM_SLOW 0xf4040001
+
+/*P1_AGC1CN*/
+#define R0900_P1_AGC1CN 0xf406
+#define F0900_P1_AGC1_LOCKED 0xf4060080
+#define F0900_P1_AGC1_OVERFLOW 0xf4060040
+#define F0900_P1_AGC1_NOSLOWLK 0xf4060020
+#define F0900_P1_AGC1_MINPOWER 0xf4060010
+#define F0900_P1_AGCOUT_FAST 0xf4060008
+#define F0900_P1_AGCIQ_BETA 0xf4060007
+
+/*P1_AGC1REF*/
+#define R0900_P1_AGC1REF 0xf407
+#define F0900_P1_AGCIQ_REF 0xf40700ff
+
+/*P1_IDCCOMP*/
+#define R0900_P1_IDCCOMP 0xf408
+#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
+
+/*P1_QDCCOMP*/
+#define R0900_P1_QDCCOMP 0xf409
+#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
+
+/*P1_POWERI*/
+#define R0900_P1_POWERI 0xf40a
+#define F0900_P1_POWER_I 0xf40a00ff
+
+/*P1_POWERQ*/
+#define R0900_P1_POWERQ 0xf40b
+#define F0900_P1_POWER_Q 0xf40b00ff
+
+/*P1_AGC1AMM*/
+#define R0900_P1_AGC1AMM 0xf40c
+#define F0900_P1_AMM_VALUE 0xf40c00ff
+
+/*P1_AGC1QUAD*/
+#define R0900_P1_AGC1QUAD 0xf40d
+#define F0900_P1_QUAD_VALUE 0xf40d01ff
+
+/*P1_AGCIQIN1*/
+#define R0900_P1_AGCIQIN1 0xf40e
+#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
+
+/*P1_AGCIQIN0*/
+#define R0900_P1_AGCIQIN0 0xf40f
+#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
+
+/*P1_DEMOD*/
+#define R0900_P1_DEMOD 0xf410
+#define F0900_P1_DEMOD_STOP 0xf4100040
+#define F0900_P1_SPECINV_CONTROL 0xf4100030
+#define F0900_P1_FORCE_ENASAMP 0xf4100008
+#define F0900_P1_MANUAL_ROLLOFF 0xf4100004
+#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
+
+/*P1_DMDMODCOD*/
+#define R0900_P1_DMDMODCOD 0xf411
+#define F0900_P1_MANUAL_MODCOD 0xf4110080
+#define F0900_P1_DEMOD_MODCOD 0xf411007c
+#define F0900_P1_DEMOD_TYPE 0xf4110003
+
+/*P1_DSTATUS*/
+#define R0900_P1_DSTATUS 0xf412
+#define F0900_P1_CAR_LOCK 0xf4120080
+#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
+#define F0900_P1_SDVBS1_ENABLE 0xf4120010
+#define F0900_P1_LOCK_DEFINITIF 0xf4120008
+#define F0900_P1_TIMING_IS_LOCKED 0xf4120004
+#define F0900_P1_COARSE_TMGLOCK 0xf4120002
+#define F0900_P1_COARSE_CARLOCK 0xf4120001
+
+/*P1_DSTATUS2*/
+#define R0900_P1_DSTATUS2 0xf413
+#define F0900_P1_DEMOD_DELOCK 0xf4130080
+#define F0900_P1_DEMOD_TIMEOUT 0xf4130040
+#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020
+#define F0900_P1_POLYPH_SATEVENT 0xf4130010
+#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
+#define F0900_P1_AGC2_OVERFLOW 0xf4130004
+#define F0900_P1_CFR_OVERFLOW 0xf4130002
+#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
+
+/*P1_DMDCFGMD*/
+#define R0900_P1_DMDCFGMD 0xf414
+#define F0900_P1_DVBS2_ENABLE 0xf4140080
+#define F0900_P1_DVBS1_ENABLE 0xf4140040
+#define F0900_P1_CFR_AUTOSCAN 0xf4140020
+#define F0900_P1_SCAN_ENABLE 0xf4140010
+#define F0900_P1_TUN_AUTOSCAN 0xf4140008
+#define F0900_P1_NOFORCE_RELOCK 0xf4140004
+#define F0900_P1_TUN_RNG 0xf4140003
+
+/*P1_DMDCFG2*/
+#define R0900_P1_DMDCFG2 0xf415
+#define F0900_P1_AGC1_WAITLOCK 0xf4150080
+#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
+#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020
+#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010
+#define F0900_P1_DMDTOUT_BACK 0xf4150008
+#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004
+#define F0900_P1_COARSE_LK3MODE 0xf4150002
+#define F0900_P1_COARSE_LK2MODE 0xf4150001
+
+/*P1_DMDISTATE*/
+#define R0900_P1_DMDISTATE 0xf416
+#define F0900_P1_I2C_NORESETDMODE 0xf4160080
+#define F0900_P1_FORCE_ETAPED 0xf4160040
+#define F0900_P1_SDMDRST_DIRCLK 0xf4160020
+#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
+
+/*P1_DMDT0M*/
+#define R0900_P1_DMDT0M 0xf417
+#define F0900_P1_DMDT0_MIN 0xf41700ff
+
+/*P1_DMDSTATE*/
+#define R0900_P1_DMDSTATE 0xf41b
+#define F0900_P1_DEMOD_LOCKED 0xf41b0080
+#define F0900_P1_HEADER_MODE 0xf41b0060
+#define F0900_P1_DEMOD_MODE 0xf41b001f
+
+/*P1_DMDFLYW*/
+#define R0900_P1_DMDFLYW 0xf41c
+#define F0900_P1_I2C_IRQVAL 0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
+
+/*P1_DSTATUS3*/
+#define R0900_P1_DSTATUS3 0xf41d
+#define F0900_P1_CFR_ZIGZAG 0xf41d0080
+#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
+#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010
+#define F0900_P1_RELOCK_MODE 0xf41d0008
+#define F0900_P1_DEMOD_FAIL 0xf41d0004
+#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003
+
+/*P1_DMDCFG3*/
+#define R0900_P1_DMDCFG3 0xf41e
+#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080
+#define F0900_P1_NO_BWCENTERING 0xf41e0040
+#define F0900_P1_INV_SEQSRCH 0xf41e0020
+#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010
+#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
+#define F0900_P1_LOCKTIME_MODE 0xf41e0007
+
+/*P1_DMDCFG4*/
+#define R0900_P1_DMDCFG4 0xf41f
+#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
+#define F0900_P1_DIS_CLKENABLE 0xf41f0004
+#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002
+#define F0900_P1_NO_TNRWBINIT 0xf41f0001
+
+/*P1_CORRELMANT*/
+#define R0900_P1_CORRELMANT 0xf420
+#define F0900_P1_CORREL_MANT 0xf42000ff
+
+/*P1_CORRELABS*/
+#define R0900_P1_CORRELABS 0xf421
+#define F0900_P1_CORREL_ABS 0xf42100ff
+
+/*P1_CORRELEXP*/
+#define R0900_P1_CORRELEXP 0xf422
+#define F0900_P1_CORREL_ABSEXP 0xf42200f0
+#define F0900_P1_CORREL_EXP 0xf422000f
+
+/*P1_PLHMODCOD*/
+#define R0900_P1_PLHMODCOD 0xf424
+#define F0900_P1_SPECINV_DEMOD 0xf4240080
+#define F0900_P1_PLH_MODCOD 0xf424007c
+#define F0900_P1_PLH_TYPE 0xf4240003
+
+/*P1_AGCK32*/
+#define R0900_P1_AGCK32 0xf42b
+#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080
+#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040
+#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020
+#define F0900_P1_RADJ_32APSK 0xf42b001f
+
+/*P1_AGC2O*/
+#define R0900_P1_AGC2O 0xf42c
+#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080
+#define F0900_P1_AGC2_COARSEFAST 0xf42c0040
+#define F0900_P1_AGC2_LKSQRT 0xf42c0020
+#define F0900_P1_AGC2_LKMODE 0xf42c0010
+#define F0900_P1_AGC2_LKEQUA 0xf42c0008
+#define F0900_P1_AGC2_COEF 0xf42c0007
+
+/*P1_AGC2REF*/
+#define R0900_P1_AGC2REF 0xf42d
+#define F0900_P1_AGC2_REF 0xf42d00ff
+
+/*P1_AGC1ADJ*/
+#define R0900_P1_AGC1ADJ 0xf42e
+#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080
+#define F0900_P1_AGC1_ADJUSTED 0xf42e017f
+
+/*P1_AGC2I1*/
+#define R0900_P1_AGC2I1 0xf436
+#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
+
+/*P1_AGC2I0*/
+#define R0900_P1_AGC2I0 0xf437
+#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
+
+/*P1_CARCFG*/
+#define R0900_P1_CARCFG 0xf438
+#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
+#define F0900_P1_CFRUPLOW_TEST 0xf4380040
+#define F0900_P1_EN_CAR2CENTER 0xf4380020
+#define F0900_P1_CARHDR_NODIV8 0xf4380010
+#define F0900_P1_I2C_ROTA 0xf4380008
+#define F0900_P1_ROTAON 0xf4380004
+#define F0900_P1_PH_DET_ALGO 0xf4380003
+
+/*P1_ACLC*/
+#define R0900_P1_ACLC 0xf439
+#define F0900_P1_STOP_S2ALPHA 0xf43900c0
+#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
+#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
+
+/*P1_BCLC*/
+#define R0900_P1_BCLC 0xf43a
+#define F0900_P1_STOP_S2BETA 0xf43a00c0
+#define F0900_P1_CAR_BETA_MANT 0xf43a0030
+#define F0900_P1_CAR_BETA_EXP 0xf43a000f
+
+/*P1_CARFREQ*/
+#define R0900_P1_CARFREQ 0xf43d
+#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
+#define F0900_P1_BETA_FREQ 0xf43d000f
+
+/*P1_CARHDR*/
+#define R0900_P1_CARHDR 0xf43e
+#define F0900_P1_K_FREQ_HDR 0xf43e00ff
+
+/*P1_LDT*/
+#define R0900_P1_LDT 0xf43f
+#define F0900_P1_CARLOCK_THRES 0xf43f01ff
+
+/*P1_LDT2*/
+#define R0900_P1_LDT2 0xf440
+#define F0900_P1_CARLOCK_THRES2 0xf44001ff
+
+/*P1_CFRICFG*/
+#define R0900_P1_CFRICFG 0xf441
+#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080
+#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040
+#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020
+#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010
+#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008
+#define F0900_P1_CFRINIT_CSTINC 0xf4410004
+#define F0900_P1_NEG_CFRSTEP 0xf4410001
+
+/*P1_CFRUP1*/
+#define R0900_P1_CFRUP1 0xf442
+#define F0900_P1_CFR_UP1 0xf44201ff
+
+/*P1_CFRUP0*/
+#define R0900_P1_CFRUP0 0xf443
+#define F0900_P1_CFR_UP0 0xf44300ff
+
+/*P1_CFRLOW1*/
+#define R0900_P1_CFRLOW1 0xf446
+#define F0900_P1_CFR_LOW1 0xf44601ff
+
+/*P1_CFRLOW0*/
+#define R0900_P1_CFRLOW0 0xf447
+#define F0900_P1_CFR_LOW0 0xf44700ff
+
+/*P1_CFRINIT1*/
+#define R0900_P1_CFRINIT1 0xf448
+#define F0900_P1_CFR_INIT1 0xf44801ff
+
+/*P1_CFRINIT0*/
+#define R0900_P1_CFRINIT0 0xf449
+#define F0900_P1_CFR_INIT0 0xf44900ff
+
+/*P1_CFRINC1*/
+#define R0900_P1_CFRINC1 0xf44a
+#define F0900_P1_MANUAL_CFRINC 0xf44a0080
+#define F0900_P1_CFR_INC1 0xf44a017f
+
+/*P1_CFRINC0*/
+#define R0900_P1_CFRINC0 0xf44b
+#define F0900_P1_CFR_INC0 0xf44b00f0
+
+/*P1_CFR2*/
+#define R0900_P1_CFR2 0xf44c
+#define F0900_P1_CAR_FREQ2 0xf44c01ff
+
+/*P1_CFR1*/
+#define R0900_P1_CFR1 0xf44d
+#define F0900_P1_CAR_FREQ1 0xf44d00ff
+
+/*P1_CFR0*/
+#define R0900_P1_CFR0 0xf44e
+#define F0900_P1_CAR_FREQ0 0xf44e00ff
+
+/*P1_LDI*/
+#define R0900_P1_LDI 0xf44f
+#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
+
+/*P1_TMGCFG*/
+#define R0900_P1_TMGCFG 0xf450
+#define F0900_P1_TMGLOCK_BETA 0xf45000c0
+#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020
+#define F0900_P1_DO_TIMING_CORR 0xf4500010
+#define F0900_P1_MANUAL_SCAN 0xf450000c
+#define F0900_P1_TMG_MINFREQ 0xf4500003
+
+/*P1_RTC*/
+#define R0900_P1_RTC 0xf451
+#define F0900_P1_TMGALPHA_EXP 0xf45100f0
+#define F0900_P1_TMGBETA_EXP 0xf451000f
+
+/*P1_RTCS2*/
+#define R0900_P1_RTCS2 0xf452
+#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
+#define F0900_P1_TMGBETAS2_EXP 0xf452000f
+
+/*P1_TMGTHRISE*/
+#define R0900_P1_TMGTHRISE 0xf453
+#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
+
+/*P1_TMGTHFALL*/
+#define R0900_P1_TMGTHFALL 0xf454
+#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
+
+/*P1_SFRUPRATIO*/
+#define R0900_P1_SFRUPRATIO 0xf455
+#define F0900_P1_SFR_UPRATIO 0xf45500ff
+
+/*P1_SFRLOWRATIO*/
+#define R0900_P1_SFRLOWRATIO 0xf456
+#define F0900_P1_SFR_LOWRATIO 0xf45600ff
+
+/*P1_KREFTMG*/
+#define R0900_P1_KREFTMG 0xf458
+#define F0900_P1_KREF_TMG 0xf45800ff
+
+/*P1_SFRSTEP*/
+#define R0900_P1_SFRSTEP 0xf459
+#define F0900_P1_SFR_SCANSTEP 0xf45900f0
+#define F0900_P1_SFR_CENTERSTEP 0xf459000f
+
+/*P1_TMGCFG2*/
+#define R0900_P1_TMGCFG2 0xf45a
+#define F0900_P1_DIS_AUTOSAMP 0xf45a0008
+#define F0900_P1_SCANINIT_QUART 0xf45a0004
+#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002
+#define F0900_P1_SFRRATIO_FINE 0xf45a0001
+
+/*P1_SFRINIT1*/
+#define R0900_P1_SFRINIT1 0xf45e
+#define F0900_P1_SFR_INIT1 0xf45e00ff
+
+/*P1_SFRINIT0*/
+#define R0900_P1_SFRINIT0 0xf45f
+#define F0900_P1_SFR_INIT0 0xf45f00ff
+
+/*P1_SFRUP1*/
+#define R0900_P1_SFRUP1 0xf460
+#define F0900_P1_AUTO_GUP 0xf4600080
+#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
+
+/*P1_SFRUP0*/
+#define R0900_P1_SFRUP0 0xf461
+#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
+
+/*P1_SFRLOW1*/
+#define R0900_P1_SFRLOW1 0xf462
+#define F0900_P1_AUTO_GLOW 0xf4620080
+#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
+
+/*P1_SFRLOW0*/
+#define R0900_P1_SFRLOW0 0xf463
+#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
+
+/*P1_SFR3*/
+#define R0900_P1_SFR3 0xf464
+#define F0900_P1_SYMB_FREQ3 0xf46400ff
+
+/*P1_SFR2*/
+#define R0900_P1_SFR2 0xf465
+#define F0900_P1_SYMB_FREQ2 0xf46500ff
+
+/*P1_SFR1*/
+#define R0900_P1_SFR1 0xf466
+#define F0900_P1_SYMB_FREQ1 0xf46600ff
+
+/*P1_SFR0*/
+#define R0900_P1_SFR0 0xf467
+#define F0900_P1_SYMB_FREQ0 0xf46700ff
+
+/*P1_TMGREG2*/
+#define R0900_P1_TMGREG2 0xf468
+#define F0900_P1_TMGREG2 0xf46800ff
+
+/*P1_TMGREG1*/
+#define R0900_P1_TMGREG1 0xf469
+#define F0900_P1_TMGREG1 0xf46900ff
+
+/*P1_TMGREG0*/
+#define R0900_P1_TMGREG0 0xf46a
+#define F0900_P1_TMGREG0 0xf46a00ff
+
+/*P1_TMGLOCK1*/
+#define R0900_P1_TMGLOCK1 0xf46b
+#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
+
+/*P1_TMGLOCK0*/
+#define R0900_P1_TMGLOCK0 0xf46c
+#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
+
+/*P1_TMGOBS*/
+#define R0900_P1_TMGOBS 0xf46d
+#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
+#define F0900_P1_SCAN_SIGN 0xf46d0030
+#define F0900_P1_TMG_SCANNING 0xf46d0008
+#define F0900_P1_CHCENTERING_MODE 0xf46d0004
+#define F0900_P1_TMG_SCANFAIL 0xf46d0002
+
+/*P1_EQUALCFG*/
+#define R0900_P1_EQUALCFG 0xf46f
+#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080
+#define F0900_P1_EQUAL_ON 0xf46f0040
+#define F0900_P1_SEL_EQUALCOR 0xf46f0038
+#define F0900_P1_MU_EQUALDFE 0xf46f0007
+
+/*P1_EQUAI1*/
+#define R0900_P1_EQUAI1 0xf470
+#define F0900_P1_EQUA_ACCI1 0xf47001ff
+
+/*P1_EQUAQ1*/
+#define R0900_P1_EQUAQ1 0xf471
+#define F0900_P1_EQUA_ACCQ1 0xf47101ff
+
+/*P1_EQUAI2*/
+#define R0900_P1_EQUAI2 0xf472
+#define F0900_P1_EQUA_ACCI2 0xf47201ff
+
+/*P1_EQUAQ2*/
+#define R0900_P1_EQUAQ2 0xf473
+#define F0900_P1_EQUA_ACCQ2 0xf47301ff
+
+/*P1_EQUAI3*/
+#define R0900_P1_EQUAI3 0xf474
+#define F0900_P1_EQUA_ACCI3 0xf47401ff
+
+/*P1_EQUAQ3*/
+#define R0900_P1_EQUAQ3 0xf475
+#define F0900_P1_EQUA_ACCQ3 0xf47501ff
+
+/*P1_EQUAI4*/
+#define R0900_P1_EQUAI4 0xf476
+#define F0900_P1_EQUA_ACCI4 0xf47601ff
+
+/*P1_EQUAQ4*/
+#define R0900_P1_EQUAQ4 0xf477
+#define F0900_P1_EQUA_ACCQ4 0xf47701ff
+
+/*P1_EQUAI5*/
+#define R0900_P1_EQUAI5 0xf478
+#define F0900_P1_EQUA_ACCI5 0xf47801ff
+
+/*P1_EQUAQ5*/
+#define R0900_P1_EQUAQ5 0xf479
+#define F0900_P1_EQUA_ACCQ5 0xf47901ff
+
+/*P1_EQUAI6*/
+#define R0900_P1_EQUAI6 0xf47a
+#define F0900_P1_EQUA_ACCI6 0xf47a01ff
+
+/*P1_EQUAQ6*/
+#define R0900_P1_EQUAQ6 0xf47b
+#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
+
+/*P1_EQUAI7*/
+#define R0900_P1_EQUAI7 0xf47c
+#define F0900_P1_EQUA_ACCI7 0xf47c01ff
+
+/*P1_EQUAQ7*/
+#define R0900_P1_EQUAQ7 0xf47d
+#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
+
+/*P1_EQUAI8*/
+#define R0900_P1_EQUAI8 0xf47e
+#define F0900_P1_EQUA_ACCI8 0xf47e01ff
+
+/*P1_EQUAQ8*/
+#define R0900_P1_EQUAQ8 0xf47f
+#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
+
+/*P1_NNOSDATAT1*/
+#define R0900_P1_NNOSDATAT1 0xf480
+#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
+
+/*P1_NNOSDATAT0*/
+#define R0900_P1_NNOSDATAT0 0xf481
+#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
+
+/*P1_NNOSDATA1*/
+#define R0900_P1_NNOSDATA1 0xf482
+#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
+
+/*P1_NNOSDATA0*/
+#define R0900_P1_NNOSDATA0 0xf483
+#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
+
+/*P1_NNOSPLHT1*/
+#define R0900_P1_NNOSPLHT1 0xf484
+#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
+
+/*P1_NNOSPLHT0*/
+#define R0900_P1_NNOSPLHT0 0xf485
+#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
+
+/*P1_NNOSPLH1*/
+#define R0900_P1_NNOSPLH1 0xf486
+#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
+
+/*P1_NNOSPLH0*/
+#define R0900_P1_NNOSPLH0 0xf487
+#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
+
+/*P1_NOSDATAT1*/
+#define R0900_P1_NOSDATAT1 0xf488
+#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
+
+/*P1_NOSDATAT0*/
+#define R0900_P1_NOSDATAT0 0xf489
+#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
+
+/*P1_NOSDATA1*/
+#define R0900_P1_NOSDATA1 0xf48a
+#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
+
+/*P1_NOSDATA0*/
+#define R0900_P1_NOSDATA0 0xf48b
+#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
+
+/*P1_NOSPLHT1*/
+#define R0900_P1_NOSPLHT1 0xf48c
+#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
+
+/*P1_NOSPLHT0*/
+#define R0900_P1_NOSPLHT0 0xf48d
+#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
+
+/*P1_NOSPLH1*/
+#define R0900_P1_NOSPLH1 0xf48e
+#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
+
+/*P1_NOSPLH0*/
+#define R0900_P1_NOSPLH0 0xf48f
+#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
+
+/*P1_CAR2CFG*/
+#define R0900_P1_CAR2CFG 0xf490
+#define F0900_P1_DESCRAMB_OFF 0xf4900080
+#define F0900_P1_PN4_SELECT 0xf4900040
+#define F0900_P1_CFR2_STOPDVBS1 0xf4900020
+#define F0900_P1_STOP_CFR2UPDATE 0xf4900010
+#define F0900_P1_STOP_NCO2UPDATE 0xf4900008
+#define F0900_P1_ROTA2ON 0xf4900004
+#define F0900_P1_PH_DET_ALGO2 0xf4900003
+
+/*P1_ACLC2*/
+#define R0900_P1_ACLC2 0xf491
+#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040
+#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030
+#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f
+
+/*P1_BCLC2*/
+#define R0900_P1_BCLC2 0xf492
+#define F0900_P1_DVBS2_NIP 0xf4920080
+#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040
+#define F0900_P1_CAR2_BETA_MANT 0xf4920030
+#define F0900_P1_CAR2_BETA_EXP 0xf492000f
+
+/*P1_CFR22*/
+#define R0900_P1_CFR22 0xf493
+#define F0900_P1_CAR2_FREQ2 0xf49301ff
+
+/*P1_CFR21*/
+#define R0900_P1_CFR21 0xf494
+#define F0900_P1_CAR2_FREQ1 0xf49400ff
+
+/*P1_CFR20*/
+#define R0900_P1_CFR20 0xf495
+#define F0900_P1_CAR2_FREQ0 0xf49500ff
+
+/*P1_ACLC2S2Q*/
+#define R0900_P1_ACLC2S2Q 0xf497
+#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
+#define F0900_P1_CAR2S2_QADERAT 0xf4970040
+#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
+
+/*P1_ACLC2S28*/
+#define R0900_P1_ACLC2S28 0xf498
+#define F0900_P1_OLDI3Q_MODE 0xf4980080
+#define F0900_P1_CAR2S2_8ADERAT 0xf4980040
+#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
+
+/*P1_ACLC2S216A*/
+#define R0900_P1_ACLC2S216A 0xf499
+#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
+#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
+
+/*P1_ACLC2S232A*/
+#define R0900_P1_ACLC2S232A 0xf49a
+#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
+#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
+
+/*P1_BCLC2S2Q*/
+#define R0900_P1_BCLC2S2Q 0xf49c
+#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080
+#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040
+#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
+
+/*P1_BCLC2S28*/
+#define R0900_P1_BCLC2S28 0xf49d
+#define F0900_P1_DVBS2S28_NIP 0xf49d0080
+#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040
+#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
+
+/*P1_BCLC2S216A*/
+#define R0900_P1_BCLC2S216A 0xf49e
+#define F0900_P1_DVBS2S216A_NIP 0xf49e0080
+#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040
+#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030
+#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f
+
+/*P1_BCLC2S232A*/
+#define R0900_P1_BCLC2S232A 0xf49f
+#define F0900_P1_DVBS2S232A_NIP 0xf49f0080
+#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040
+#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030
+#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f
+
+/*P1_PLROOT2*/
+#define R0900_P1_PLROOT2 0xf4ac
+#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080
+#define F0900_P1_LONGFR_DISABLE 0xf4ac0040
+#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020
+#define F0900_P1_SHORTFR_AVOID 0xf4ac0010
+#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
+#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
+
+/*P1_PLROOT1*/
+#define R0900_P1_PLROOT1 0xf4ad
+#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
+
+/*P1_PLROOT0*/
+#define R0900_P1_PLROOT0 0xf4ae
+#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
+
+/*P1_MODCODLST0*/
+#define R0900_P1_MODCODLST0 0xf4b0
+#define F0900_P1_EN_TOKEN31 0xf4b00080
+#define F0900_P1_SYNCTAG_SELECT 0xf4b00040
+#define F0900_P1_MODCODRQ_MODE 0xf4b00030
+
+/*P1_MODCODLST1*/
+#define R0900_P1_MODCODLST1 0xf4b1
+#define F0900_P1_DIS_MODCOD29 0xf4b100f0
+#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
+
+/*P1_MODCODLST2*/
+#define R0900_P1_MODCODLST2 0xf4b2
+#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
+#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
+
+/*P1_MODCODLST3*/
+#define R0900_P1_MODCODLST3 0xf4b3
+#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
+#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
+
+/*P1_MODCODLST4*/
+#define R0900_P1_MODCODLST4 0xf4b4
+#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
+#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
+
+/*P1_MODCODLST5*/
+#define R0900_P1_MODCODLST5 0xf4b5
+#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
+#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
+
+/*P1_MODCODLST6*/
+#define R0900_P1_MODCODLST6 0xf4b6
+#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
+#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
+
+/*P1_MODCODLST7*/
+#define R0900_P1_MODCODLST7 0xf4b7
+#define F0900_P1_DIS_8P_9_10 0xf4b700f0
+#define F0900_P1_DIS_8P_8_9 0xf4b7000f
+
+/*P1_MODCODLST8*/
+#define R0900_P1_MODCODLST8 0xf4b8
+#define F0900_P1_DIS_8P_5_6 0xf4b800f0
+#define F0900_P1_DIS_8P_3_4 0xf4b8000f
+
+/*P1_MODCODLST9*/
+#define R0900_P1_MODCODLST9 0xf4b9
+#define F0900_P1_DIS_8P_2_3 0xf4b900f0
+#define F0900_P1_DIS_8P_3_5 0xf4b9000f
+
+/*P1_MODCODLSTA*/
+#define R0900_P1_MODCODLSTA 0xf4ba
+#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
+#define F0900_P1_DIS_QP_8_9 0xf4ba000f
+
+/*P1_MODCODLSTB*/
+#define R0900_P1_MODCODLSTB 0xf4bb
+#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
+#define F0900_P1_DIS_QP_4_5 0xf4bb000f
+
+/*P1_MODCODLSTC*/
+#define R0900_P1_MODCODLSTC 0xf4bc
+#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
+#define F0900_P1_DIS_QP_2_3 0xf4bc000f
+
+/*P1_MODCODLSTD*/
+#define R0900_P1_MODCODLSTD 0xf4bd
+#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
+#define F0900_P1_DIS_QP_1_2 0xf4bd000f
+
+/*P1_MODCODLSTE*/
+#define R0900_P1_MODCODLSTE 0xf4be
+#define F0900_P1_DIS_QP_2_5 0xf4be00f0
+#define F0900_P1_DIS_QP_1_3 0xf4be000f
+
+/*P1_MODCODLSTF*/
+#define R0900_P1_MODCODLSTF 0xf4bf
+#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
+#define F0900_P1_DDEMOD_SET 0xf4bf0002
+#define F0900_P1_DDEMOD_MASK 0xf4bf0001
+
+/*P1_DMDRESCFG*/
+#define R0900_P1_DMDRESCFG 0xf4c6
+#define F0900_P1_DMDRES_RESET 0xf4c60080
+#define F0900_P1_DMDRES_NOISESQR 0xf4c60010
+#define F0900_P1_DMDRES_STRALL 0xf4c60008
+#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
+#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
+#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001
+
+/*P1_DMDRESADR*/
+#define R0900_P1_DMDRESADR 0xf4c7
+#define F0900_P1_SUSP_PREDCANAL 0xf4c70080
+#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
+#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
+#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
+
+/*P1_DMDRESDATA7*/
+#define R0900_P1_DMDRESDATA7 0xf4c8
+#define F0900_P1_DMDRES_DATA7 0xf4c800ff
+
+/*P1_DMDRESDATA6*/
+#define R0900_P1_DMDRESDATA6 0xf4c9
+#define F0900_P1_DMDRES_DATA6 0xf4c900ff
+
+/*P1_DMDRESDATA5*/
+#define R0900_P1_DMDRESDATA5 0xf4ca
+#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
+
+/*P1_DMDRESDATA4*/
+#define R0900_P1_DMDRESDATA4 0xf4cb
+#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
+
+/*P1_DMDRESDATA3*/
+#define R0900_P1_DMDRESDATA3 0xf4cc
+#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
+
+/*P1_DMDRESDATA2*/
+#define R0900_P1_DMDRESDATA2 0xf4cd
+#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
+
+/*P1_DMDRESDATA1*/
+#define R0900_P1_DMDRESDATA1 0xf4ce
+#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
+
+/*P1_DMDRESDATA0*/
+#define R0900_P1_DMDRESDATA0 0xf4cf
+#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
+
+/*P1_FFEI1*/
+#define R0900_P1_FFEI1 0xf4d0
+#define F0900_P1_FFE_ACCI1 0xf4d001ff
+
+/*P1_FFEQ1*/
+#define R0900_P1_FFEQ1 0xf4d1
+#define F0900_P1_FFE_ACCQ1 0xf4d101ff
+
+/*P1_FFEI2*/
+#define R0900_P1_FFEI2 0xf4d2
+#define F0900_P1_FFE_ACCI2 0xf4d201ff
+
+/*P1_FFEQ2*/
+#define R0900_P1_FFEQ2 0xf4d3
+#define F0900_P1_FFE_ACCQ2 0xf4d301ff
+
+/*P1_FFEI3*/
+#define R0900_P1_FFEI3 0xf4d4
+#define F0900_P1_FFE_ACCI3 0xf4d401ff
+
+/*P1_FFEQ3*/
+#define R0900_P1_FFEQ3 0xf4d5
+#define F0900_P1_FFE_ACCQ3 0xf4d501ff
+
+/*P1_FFEI4*/
+#define R0900_P1_FFEI4 0xf4d6
+#define F0900_P1_FFE_ACCI4 0xf4d601ff
+
+/*P1_FFEQ4*/
+#define R0900_P1_FFEQ4 0xf4d7
+#define F0900_P1_FFE_ACCQ4 0xf4d701ff
+
+/*P1_FFECFG*/
+#define R0900_P1_FFECFG 0xf4d8
+#define F0900_P1_EQUALFFE_ON 0xf4d80040
+#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030
+#define F0900_P1_MU_EQUALFFE 0xf4d80007
+
+/*P1_TNRCFG*/
+#define R0900_P1_TNRCFG 0xf4e0
+#define F0900_P1_TUN_ACKFAIL 0xf4e00080
+#define F0900_P1_TUN_TYPE 0xf4e00070
+#define F0900_P1_TUN_SECSTOP 0xf4e00008
+#define F0900_P1_TUN_VCOSRCH 0xf4e00004
+#define F0900_P1_TUN_MADDRESS 0xf4e00003
+
+/*P1_TNRCFG2*/
+#define R0900_P1_TNRCFG2 0xf4e1
+#define F0900_P1_TUN_IQSWAP 0xf4e10080
+#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040
+#define F0900_P1_STB6120_DBLI2C 0xf4e10020
+#define F0900_P1_DIS_FCCK 0xf4e10010
+#define F0900_P1_DIS_LPEN 0xf4e10008
+#define F0900_P1_DIS_BWCALC 0xf4e10004
+#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
+#define F0900_P1_DIS_2BWAGC1 0xf4e10001
+
+/*P1_TNRXTAL*/
+#define R0900_P1_TNRXTAL 0xf4e4
+#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0
+#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
+
+/*P1_TNRSTEPS*/
+#define R0900_P1_TNRSTEPS 0xf4e7
+#define F0900_P1_TUNER_BW1P6 0xf4e70080
+#define F0900_P1_BWINC_OFFSET 0xf4e70070
+#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
+#define F0900_P1_TUN_BWOFFSET 0xf4e70107
+
+/*P1_TNRGAIN*/
+#define R0900_P1_TNRGAIN 0xf4e8
+#define F0900_P1_TUN_KDIVEN 0xf4e800c0
+#define F0900_P1_STB6X00_OCK 0xf4e80030
+#define F0900_P1_TUN_GAIN 0xf4e8000f
+
+/*P1_TNRRF1*/
+#define R0900_P1_TNRRF1 0xf4e9
+#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
+
+/*P1_TNRRF0*/
+#define R0900_P1_TNRRF0 0xf4ea
+#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
+
+/*P1_TNRBW*/
+#define R0900_P1_TNRBW 0xf4eb
+#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define F0900_P1_TUN_BW 0xf4eb003f
+
+/*P1_TNRADJ*/
+#define R0900_P1_TNRADJ 0xf4ec
+#define F0900_P1_STB61X0_RCLK 0xf4ec0080
+#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
+#define F0900_P1_STB6X00_DLB 0xf4ec0038
+#define F0900_P1_STB6000_FCL 0xf4ec0007
+
+/*P1_TNRCTL2*/
+#define R0900_P1_TNRCTL2 0xf4ed
+#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080
+#define F0900_P1_STB61X0_LCP0 0xf4ed0040
+#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020
+#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010
+#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008
+#define F0900_P1_STB6110_LPT 0xf4ed0004
+#define F0900_P1_STB6110_RX 0xf4ed0002
+#define F0900_P1_STB6110_SYN 0xf4ed0001
+
+/*P1_TNRCFG3*/
+#define R0900_P1_TNRCFG3 0xf4ee
+#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080
+#define F0900_P1_STB6120_INVORDER 0xf4ee0040
+#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020
+#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
+#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
+
+/*P1_TNRLAUNCH*/
+#define R0900_P1_TNRLAUNCH 0xf4f0
+
+/*P1_TNRLD*/
+#define R0900_P1_TNRLD 0xf4f0
+#define F0900_P1_TUNLD_VCOING 0xf4f00080
+#define F0900_P1_TUN_REG1FAIL 0xf4f00040
+#define F0900_P1_TUN_REG2FAIL 0xf4f00020
+#define F0900_P1_TUN_REG3FAIL 0xf4f00010
+#define F0900_P1_TUN_REG4FAIL 0xf4f00008
+#define F0900_P1_TUN_REG5FAIL 0xf4f00004
+#define F0900_P1_TUN_BWING 0xf4f00002
+#define F0900_P1_TUN_LOCKED 0xf4f00001
+
+/*P1_TNROBSL*/
+#define R0900_P1_TNROBSL 0xf4f6
+#define F0900_P1_TUN_I2CABORTED 0xf4f60080
+#define F0900_P1_TUN_LPEN 0xf4f60040
+#define F0900_P1_TUN_FCCK 0xf4f60020
+#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
+#define F0900_P1_TUN_PROGDONE 0xf4f6000c
+#define F0900_P1_TUN_RFRESTE1 0xf4f60003
+
+/*P1_TNRRESTE*/
+#define R0900_P1_TNRRESTE 0xf4f7
+#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
+
+/*P1_SMAPCOEF7*/
+#define R0900_P1_SMAPCOEF7 0xf500
+#define F0900_P1_DIS_QSCALE 0xf5000080
+#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
+
+/*P1_SMAPCOEF6*/
+#define R0900_P1_SMAPCOEF6 0xf501
+#define F0900_P1_DIS_NEWSCALE 0xf5010008
+#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
+#define F0900_P1_OLD_8PSKLLR1 0xf5010002
+#define F0900_P1_DIS_AB8PSK 0xf5010001
+
+/*P1_SMAPCOEF5*/
+#define R0900_P1_SMAPCOEF5 0xf502
+#define F0900_P1_DIS_8SCALE 0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
+
+/*P1_DMDPLHSTAT*/
+#define R0900_P1_DMDPLHSTAT 0xf520
+#define F0900_P1_PLH_STATISTIC 0xf52000ff
+
+/*P1_LOCKTIME3*/
+#define R0900_P1_LOCKTIME3 0xf522
+#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
+
+/*P1_LOCKTIME2*/
+#define R0900_P1_LOCKTIME2 0xf523
+#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
+
+/*P1_LOCKTIME1*/
+#define R0900_P1_LOCKTIME1 0xf524
+#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
+
+/*P1_LOCKTIME0*/
+#define R0900_P1_LOCKTIME0 0xf525
+#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
+
+/*P1_VITSCALE*/
+#define R0900_P1_VITSCALE 0xf532
+#define F0900_P1_NVTH_NOSRANGE 0xf5320080
+#define F0900_P1_VERROR_MAXMODE 0xf5320040
+#define F0900_P1_KDIV_MODE 0xf5320030
+#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
+#define F0900_P1_DELOCK_PRFLOSS 0xf5320004
+#define F0900_P1_DIS_RSFLOCK 0xf5320002
+
+/*P1_FECM*/
+#define R0900_P1_FECM 0xf533
+#define F0900_P1_DSS_DVB 0xf5330080
+#define F0900_P1_DEMOD_BYPASS 0xf5330040
+#define F0900_P1_CMP_SLOWMODE 0xf5330020
+#define F0900_P1_DSS_SRCH 0xf5330010
+#define F0900_P1_DIFF_MODEVIT 0xf5330004
+#define F0900_P1_SYNCVIT 0xf5330002
+#define F0900_P1_IQINV 0xf5330001
+
+/*P1_VTH12*/
+#define R0900_P1_VTH12 0xf534
+#define F0900_P1_VTH12 0xf53400ff
+
+/*P1_VTH23*/
+#define R0900_P1_VTH23 0xf535
+#define F0900_P1_VTH23 0xf53500ff
+
+/*P1_VTH34*/
+#define R0900_P1_VTH34 0xf536
+#define F0900_P1_VTH34 0xf53600ff
+
+/*P1_VTH56*/
+#define R0900_P1_VTH56 0xf537
+#define F0900_P1_VTH56 0xf53700ff
+
+/*P1_VTH67*/
+#define R0900_P1_VTH67 0xf538
+#define F0900_P1_VTH67 0xf53800ff
+
+/*P1_VTH78*/
+#define R0900_P1_VTH78 0xf539
+#define F0900_P1_VTH78 0xf53900ff
+
+/*P1_VITCURPUN*/
+#define R0900_P1_VITCURPUN 0xf53a
+#define F0900_P1_VIT_MAPPING 0xf53a00e0
+#define F0900_P1_VIT_CURPUN 0xf53a001f
+
+/*P1_VERROR*/
+#define R0900_P1_VERROR 0xf53b
+#define F0900_P1_REGERR_VIT 0xf53b00ff
+
+/*P1_PRVIT*/
+#define R0900_P1_PRVIT 0xf53c
+#define F0900_P1_DIS_VTHLOCK 0xf53c0040
+#define F0900_P1_E7_8VIT 0xf53c0020
+#define F0900_P1_E6_7VIT 0xf53c0010
+#define F0900_P1_E5_6VIT 0xf53c0008
+#define F0900_P1_E3_4VIT 0xf53c0004
+#define F0900_P1_E2_3VIT 0xf53c0002
+#define F0900_P1_E1_2VIT 0xf53c0001
+
+/*P1_VAVSRVIT*/
+#define R0900_P1_VAVSRVIT 0xf53d
+#define F0900_P1_AMVIT 0xf53d0080
+#define F0900_P1_FROZENVIT 0xf53d0040
+#define F0900_P1_SNVIT 0xf53d0030
+#define F0900_P1_TOVVIT 0xf53d000c
+#define F0900_P1_HYPVIT 0xf53d0003
+
+/*P1_VSTATUSVIT*/
+#define R0900_P1_VSTATUSVIT 0xf53e
+#define F0900_P1_VITERBI_ON 0xf53e0080
+#define F0900_P1_END_LOOPVIT 0xf53e0040
+#define F0900_P1_VITERBI_DEPRF 0xf53e0020
+#define F0900_P1_PRFVIT 0xf53e0010
+#define F0900_P1_LOCKEDVIT 0xf53e0008
+#define F0900_P1_VITERBI_DELOCK 0xf53e0004
+#define F0900_P1_VIT_DEMODSEL 0xf53e0002
+#define F0900_P1_VITERBI_COMPOUT 0xf53e0001
+
+/*P1_VTHINUSE*/
+#define R0900_P1_VTHINUSE 0xf53f
+#define F0900_P1_VIT_INUSE 0xf53f00ff
+
+/*P1_KDIV12*/
+#define R0900_P1_KDIV12 0xf540
+#define F0900_P1_KDIV12_MANUAL 0xf5400080
+#define F0900_P1_K_DIVIDER_12 0xf540007f
+
+/*P1_KDIV23*/
+#define R0900_P1_KDIV23 0xf541
+#define F0900_P1_KDIV23_MANUAL 0xf5410080
+#define F0900_P1_K_DIVIDER_23 0xf541007f
+
+/*P1_KDIV34*/
+#define R0900_P1_KDIV34 0xf542
+#define F0900_P1_KDIV34_MANUAL 0xf5420080
+#define F0900_P1_K_DIVIDER_34 0xf542007f
+
+/*P1_KDIV56*/
+#define R0900_P1_KDIV56 0xf543
+#define F0900_P1_KDIV56_MANUAL 0xf5430080
+#define F0900_P1_K_DIVIDER_56 0xf543007f
+
+/*P1_KDIV67*/
+#define R0900_P1_KDIV67 0xf544
+#define F0900_P1_KDIV67_MANUAL 0xf5440080
+#define F0900_P1_K_DIVIDER_67 0xf544007f
+
+/*P1_KDIV78*/
+#define R0900_P1_KDIV78 0xf545
+#define F0900_P1_KDIV78_MANUAL 0xf5450080
+#define F0900_P1_K_DIVIDER_78 0xf545007f
+
+/*P1_PDELCTRL1*/
+#define R0900_P1_PDELCTRL1 0xf550
+#define F0900_P1_INV_MISMASK 0xf5500080
+#define F0900_P1_FORCE_ACCEPTED 0xf5500040
+#define F0900_P1_FILTER_EN 0xf5500020
+#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010
+#define F0900_P1_HYSTEN 0xf5500008
+#define F0900_P1_HYSTSWRST 0xf5500004
+#define F0900_P1_EN_MIS00 0xf5500002
+#define F0900_P1_ALGOSWRST 0xf5500001
+
+/*P1_PDELCTRL2*/
+#define R0900_P1_PDELCTRL2 0xf551
+#define F0900_P1_FORCE_CONTINUOUS 0xf5510080
+#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
+#define F0900_P1_USER_PKTDELIN_NB 0xf5510020
+#define F0900_P1_FORCE_LOCKED 0xf5510010
+#define F0900_P1_DATA_UNBBSCRAM 0xf5510008
+#define F0900_P1_FORCE_LONGPKT 0xf5510004
+#define F0900_P1_FRAME_MODE 0xf5510002
+
+/*P1_HYSTTHRESH*/
+#define R0900_P1_HYSTTHRESH 0xf554
+#define F0900_P1_UNLCK_THRESH 0xf55400f0
+#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
+
+/*P1_ISIENTRY*/
+#define R0900_P1_ISIENTRY 0xf55e
+#define F0900_P1_ISI_ENTRY 0xf55e00ff
+
+/*P1_ISIBITENA*/
+#define R0900_P1_ISIBITENA 0xf55f
+#define F0900_P1_ISI_BIT_EN 0xf55f00ff
+
+/*P1_MATSTR1*/
+#define R0900_P1_MATSTR1 0xf560
+#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
+
+/*P1_MATSTR0*/
+#define R0900_P1_MATSTR0 0xf561
+#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
+
+/*P1_UPLSTR1*/
+#define R0900_P1_UPLSTR1 0xf562
+#define F0900_P1_UPL_CURRENT1 0xf56200ff
+
+/*P1_UPLSTR0*/
+#define R0900_P1_UPLSTR0 0xf563
+#define F0900_P1_UPL_CURRENT0 0xf56300ff
+
+/*P1_DFLSTR1*/
+#define R0900_P1_DFLSTR1 0xf564
+#define F0900_P1_DFL_CURRENT1 0xf56400ff
+
+/*P1_DFLSTR0*/
+#define R0900_P1_DFLSTR0 0xf565
+#define F0900_P1_DFL_CURRENT0 0xf56500ff
+
+/*P1_SYNCSTR*/
+#define R0900_P1_SYNCSTR 0xf566
+#define F0900_P1_SYNC_CURRENT 0xf56600ff
+
+/*P1_SYNCDSTR1*/
+#define R0900_P1_SYNCDSTR1 0xf567
+#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
+
+/*P1_SYNCDSTR0*/
+#define R0900_P1_SYNCDSTR0 0xf568
+#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
+
+/*P1_PDELSTATUS1*/
+#define R0900_P1_PDELSTATUS1 0xf569
+#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
+#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
+#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
+#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
+#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
+#define F0900_P1_BBHCRCKO 0xf5690004
+#define F0900_P1_PKTDELIN_LOCK 0xf5690002
+#define F0900_P1_FIRST_LOCK 0xf5690001
+
+/*P1_PDELSTATUS2*/
+#define R0900_P1_PDELSTATUS2 0xf56a
+#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080
+#define F0900_P1_FRAME_MODCOD 0xf56a007c
+#define F0900_P1_FRAME_TYPE 0xf56a0003
+
+/*P1_BBFCRCKO1*/
+#define R0900_P1_BBFCRCKO1 0xf56b
+#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
+
+/*P1_BBFCRCKO0*/
+#define R0900_P1_BBFCRCKO0 0xf56c
+#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
+
+/*P1_UPCRCKO1*/
+#define R0900_P1_UPCRCKO1 0xf56d
+#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
+
+/*P1_UPCRCKO0*/
+#define R0900_P1_UPCRCKO0 0xf56e
+#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
+
+/*P1_TSSTATEM*/
+#define R0900_P1_TSSTATEM 0xf570
+#define F0900_P1_TSDIL_ON 0xf5700080
+#define F0900_P1_TSSKIPRS_ON 0xf5700040
+#define F0900_P1_TSRS_ON 0xf5700020
+#define F0900_P1_TSDESCRAMB_ON 0xf5700010
+#define F0900_P1_TSFRAME_MODE 0xf5700008
+#define F0900_P1_TS_DISABLE 0xf5700004
+#define F0900_P1_TSACM_MODE 0xf5700002
+#define F0900_P1_TSOUT_NOSYNC 0xf5700001
+
+/*P1_TSCFGH*/
+#define R0900_P1_TSCFGH 0xf572
+#define F0900_P1_TSFIFO_DVBCI 0xf5720080
+#define F0900_P1_TSFIFO_SERIAL 0xf5720040
+#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
+#define F0900_P1_TSFIFO_DUTY50 0xf5720010
+#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
+#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
+#define F0900_P1_RST_HWARE 0xf5720001
+
+/*P1_TSCFGM*/
+#define R0900_P1_TSCFGM 0xf573
+#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
+#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
+#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010
+#define F0900_P1_TSFIFO_BITSPEED 0xf5730008
+#define F0900_P1_NPD_SPECDVBS2 0xf5730004
+#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002
+#define F0900_P1_TSFIFO_INVDATA 0xf5730001
+
+/*P1_TSCFGL*/
+#define R0900_P1_TSCFGL 0xf574
+#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
+#define F0900_P1_BCHERROR_MODE 0xf5740030
+#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
+#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
+#define F0900_P1_TSFIFO_DPUNACT 0xf5740002
+#define F0900_P1_TSFIFO_NPDOFF 0xf5740001
+
+/*P1_TSINSDELH*/
+#define R0900_P1_TSINSDELH 0xf576
+#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
+#define F0900_P1_TSDEL_XXHEADER 0xf5760040
+#define F0900_P1_TSDEL_BBHEADER 0xf5760020
+#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
+#define F0900_P1_TSINSDEL_ISCR 0xf5760008
+#define F0900_P1_TSINSDEL_NPD 0xf5760004
+#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
+#define F0900_P1_TSINSDEL_CRC8 0xf5760001
+
+/*P1_TSSPEED*/
+#define R0900_P1_TSSPEED 0xf580
+#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
+
+/*P1_TSSTATUS*/
+#define R0900_P1_TSSTATUS 0xf581
+#define F0900_P1_TSFIFO_LINEOK 0xf5810080
+#define F0900_P1_TSFIFO_ERROR 0xf5810040
+#define F0900_P1_TSFIFO_DATA7 0xf5810020
+#define F0900_P1_TSFIFO_NOSYNC 0xf5810010
+#define F0900_P1_ISCR_INITIALIZED 0xf5810008
+#define F0900_P1_ISCR_UPDATED 0xf5810004
+#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002
+#define F0900_P1_DIL_READY 0xf5810001
+
+/*P1_TSSTATUS2*/
+#define R0900_P1_TSSTATUS2 0xf582
+#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
+#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
+#define F0900_P1_DILXX_RESET 0xf5820020
+#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
+#define F0900_P1_TSFIFO_LINENOK 0xf5820008
+#define F0900_P1_BITSPEED_EVENT 0xf5820004
+#define F0900_P1_SCRAMBDETECT 0xf5820002
+#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001
+
+/*P1_TSBITRATE1*/
+#define R0900_P1_TSBITRATE1 0xf583
+#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
+
+/*P1_TSBITRATE0*/
+#define R0900_P1_TSBITRATE0 0xf584
+#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
+
+/*P1_ERRCTRL1*/
+#define R0900_P1_ERRCTRL1 0xf598
+#define F0900_P1_ERR_SOURCE1 0xf59800f0
+#define F0900_P1_NUM_EVENT1 0xf5980007
+
+/*P1_ERRCNT12*/
+#define R0900_P1_ERRCNT12 0xf599
+#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define F0900_P1_ERR_CNT12 0xf599007f
+
+/*P1_ERRCNT11*/
+#define R0900_P1_ERRCNT11 0xf59a
+#define F0900_P1_ERR_CNT11 0xf59a00ff
+
+/*P1_ERRCNT10*/
+#define R0900_P1_ERRCNT10 0xf59b
+#define F0900_P1_ERR_CNT10 0xf59b00ff
+
+/*P1_ERRCTRL2*/
+#define R0900_P1_ERRCTRL2 0xf59c
+#define F0900_P1_ERR_SOURCE2 0xf59c00f0
+#define F0900_P1_NUM_EVENT2 0xf59c0007
+
+/*P1_ERRCNT22*/
+#define R0900_P1_ERRCNT22 0xf59d
+#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define F0900_P1_ERR_CNT22 0xf59d007f
+
+/*P1_ERRCNT21*/
+#define R0900_P1_ERRCNT21 0xf59e
+#define F0900_P1_ERR_CNT21 0xf59e00ff
+
+/*P1_ERRCNT20*/
+#define R0900_P1_ERRCNT20 0xf59f
+#define F0900_P1_ERR_CNT20 0xf59f00ff
+
+/*P1_FECSPY*/
+#define R0900_P1_FECSPY 0xf5a0
+#define F0900_P1_SPY_ENABLE 0xf5a00080
+#define F0900_P1_NO_SYNCBYTE 0xf5a00040
+#define F0900_P1_SERIAL_MODE 0xf5a00020
+#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
+#define F0900_P1_BER_PACKMODE 0xf5a00008
+#define F0900_P1_BERMETER_LMODE 0xf5a00002
+#define F0900_P1_BERMETER_RESET 0xf5a00001
+
+/*P1_FSPYCFG*/
+#define R0900_P1_FSPYCFG 0xf5a1
+#define F0900_P1_FECSPY_INPUT 0xf5a100c0
+#define F0900_P1_RST_ON_ERROR 0xf5a10020
+#define F0900_P1_ONE_SHOT 0xf5a10010
+#define F0900_P1_I2C_MODE 0xf5a1000c
+#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
+
+/*P1_FSPYDATA*/
+#define R0900_P1_FSPYDATA 0xf5a2
+#define F0900_P1_SPY_STUFFING 0xf5a20080
+#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040
+#define F0900_P1_SPY_CNULLPKT 0xf5a20020
+#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
+
+/*P1_FSPYOUT*/
+#define R0900_P1_FSPYOUT 0xf5a3
+#define F0900_P1_FSPY_DIRECT 0xf5a30080
+#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038
+#define F0900_P1_STUFF_MODE 0xf5a30007
+
+/*P1_FSTATUS*/
+#define R0900_P1_FSTATUS 0xf5a4
+#define F0900_P1_SPY_ENDSIM 0xf5a40080
+#define F0900_P1_VALID_SIM 0xf5a40040
+#define F0900_P1_FOUND_SIGNAL 0xf5a40020
+#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
+#define F0900_P1_RESULT_STATE 0xf5a4000f
+
+/*P1_FBERCPT4*/
+#define R0900_P1_FBERCPT4 0xf5a8
+#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
+
+/*P1_FBERCPT3*/
+#define R0900_P1_FBERCPT3 0xf5a9
+#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
+
+/*P1_FBERCPT2*/
+#define R0900_P1_FBERCPT2 0xf5aa
+#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
+
+/*P1_FBERCPT1*/
+#define R0900_P1_FBERCPT1 0xf5ab
+#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
+
+/*P1_FBERCPT0*/
+#define R0900_P1_FBERCPT0 0xf5ac
+#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
+
+/*P1_FBERERR2*/
+#define R0900_P1_FBERERR2 0xf5ad
+#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
+
+/*P1_FBERERR1*/
+#define R0900_P1_FBERERR1 0xf5ae
+#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
+
+/*P1_FBERERR0*/
+#define R0900_P1_FBERERR0 0xf5af
+#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
+
+/*P1_FSPYBER*/
+#define R0900_P1_FSPYBER 0xf5b2
+#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040
+#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020
+#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
+#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
+#define F0900_P1_FSPYBER_CTIME 0xf5b20007
+
+/*RCCFGH*/
+#define R0900_RCCFGH 0xf600
+#define F0900_TSRCFIFO_DVBCI 0xf6000080
+#define F0900_TSRCFIFO_SERIAL 0xf6000040
+#define F0900_TSRCFIFO_DISABLE 0xf6000020
+#define F0900_TSFIFO_2TORC 0xf6000010
+#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008
+#define F0900_TSRCFIFO_ERRMODE 0xf6000006
+
+/*TSGENERAL*/
+#define R0900_TSGENERAL 0xf630
+#define F0900_TSFIFO_BCLK1ALL 0xf6300020
+#define F0900_MUXSTREAM_OUTMODE 0xf6300008
+#define F0900_TSFIFO_PERMPARAL 0xf6300006
+#define F0900_RST_REEDSOLO 0xf6300001
+
+/*TSGENERAL1X*/
+#define R0900_TSGENERAL1X 0xf670
+#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020
+#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008
+#define F0900_TSFIFO1X_PERMPARAL 0xf6700006
+#define F0900_RST1X_REEDSOLO 0xf6700001
+
+/*NBITER_NF4*/
+#define R0900_NBITER_NF4 0xfa03
+#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
+
+/*NBITER_NF5*/
+#define R0900_NBITER_NF5 0xfa04
+#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
+
+/*NBITER_NF6*/
+#define R0900_NBITER_NF6 0xfa05
+#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
+
+/*NBITER_NF7*/
+#define R0900_NBITER_NF7 0xfa06
+#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
+
+/*NBITER_NF8*/
+#define R0900_NBITER_NF8 0xfa07
+#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
+
+/*NBITER_NF9*/
+#define R0900_NBITER_NF9 0xfa08
+#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
+
+/*NBITER_NF10*/
+#define R0900_NBITER_NF10 0xfa09
+#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
+
+/*NBITER_NF11*/
+#define R0900_NBITER_NF11 0xfa0a
+#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
+
+/*NBITER_NF12*/
+#define R0900_NBITER_NF12 0xfa0b
+#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
+
+/*NBITER_NF13*/
+#define R0900_NBITER_NF13 0xfa0c
+#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
+
+/*NBITER_NF14*/
+#define R0900_NBITER_NF14 0xfa0d
+#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
+
+/*NBITER_NF15*/
+#define R0900_NBITER_NF15 0xfa0e
+#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
+
+/*NBITER_NF16*/
+#define R0900_NBITER_NF16 0xfa0f
+#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
+
+/*NBITER_NF17*/
+#define R0900_NBITER_NF17 0xfa10
+#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
+
+/*NBITERNOERR*/
+#define R0900_NBITERNOERR 0xfa3f
+#define F0900_NBITER_STOP_CRIT 0xfa3f000f
+
+/*GAINLLR_NF4*/
+#define R0900_GAINLLR_NF4 0xfa43
+#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
+
+/*GAINLLR_NF5*/
+#define R0900_GAINLLR_NF5 0xfa44
+#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
+
+/*GAINLLR_NF6*/
+#define R0900_GAINLLR_NF6 0xfa45
+#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
+
+/*GAINLLR_NF7*/
+#define R0900_GAINLLR_NF7 0xfa46
+#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
+
+/*GAINLLR_NF8*/
+#define R0900_GAINLLR_NF8 0xfa47
+#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
+
+/*GAINLLR_NF9*/
+#define R0900_GAINLLR_NF9 0xfa48
+#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
+
+/*GAINLLR_NF10*/
+#define R0900_GAINLLR_NF10 0xfa49
+#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
+
+/*GAINLLR_NF11*/
+#define R0900_GAINLLR_NF11 0xfa4a
+#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
+
+/*GAINLLR_NF12*/
+#define R0900_GAINLLR_NF12 0xfa4b
+#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
+
+/*GAINLLR_NF13*/
+#define R0900_GAINLLR_NF13 0xfa4c
+#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
+
+/*GAINLLR_NF14*/
+#define R0900_GAINLLR_NF14 0xfa4d
+#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
+
+/*GAINLLR_NF15*/
+#define R0900_GAINLLR_NF15 0xfa4e
+#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
+
+/*GAINLLR_NF16*/
+#define R0900_GAINLLR_NF16 0xfa4f
+#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
+
+/*GAINLLR_NF17*/
+#define R0900_GAINLLR_NF17 0xfa50
+#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
+
+/*CFGEXT*/
+#define R0900_CFGEXT 0xfa80
+#define F0900_STAGMODE 0xfa800080
+#define F0900_BYPBCH 0xfa800040
+#define F0900_BYPLDPC 0xfa800020
+#define F0900_LDPCMODE 0xfa800010
+#define F0900_INVLLRSIGN 0xfa800008
+#define F0900_SHORTMULT 0xfa800004
+#define F0900_EXTERNTX 0xfa800001
+
+/*GENCFG*/
+#define R0900_GENCFG 0xfa86
+#define F0900_BROADCAST 0xfa860010
+#define F0900_NOSHFRD2 0xfa860008
+#define F0900_BCHERRFLAG 0xfa860004
+#define F0900_PRIORITY 0xfa860002
+#define F0900_DDEMOD 0xfa860001
+
+/*LDPCERR1*/
+#define R0900_LDPCERR1 0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
+
+/*LDPCERR0*/
+#define R0900_LDPCERR0 0xfa97
+#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
+
+/*BCHERR*/
+#define R0900_BCHERR 0xfa98
+#define F0900_ERRORFLAG 0xfa980010
+#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
+
+/*TSTRES0*/
+#define R0900_TSTRES0 0xff11
+#define F0900_FRESFEC 0xff110080
+#define F0900_FRESTS 0xff110040
+#define F0900_FRESVIT1 0xff110020
+#define F0900_FRESVIT2 0xff110010
+#define F0900_FRESSYM1 0xff110008
+#define F0900_FRESSYM2 0xff110004
+#define F0900_FRESMAS 0xff110002
+#define F0900_FRESINT 0xff110001
+
+/*P2_TSTDISRX*/
+#define R0900_P2_TSTDISRX 0xff65
+#define F0900_P2_EN_DISRX 0xff650080
+#define F0900_P2_TST_CURRSRC 0xff650040
+#define F0900_P2_IN_DIGSIGNAL 0xff650020
+#define F0900_P2_HIZ_CURRENTSRC 0xff650010
+#define F0900_TST_P2_PIN_SELECT 0xff650008
+#define F0900_P2_TST_DISRX 0xff650007
+
+/*P1_TSTDISRX*/
+#define R0900_P1_TSTDISRX 0xff67
+#define F0900_P1_EN_DISRX 0xff670080
+#define F0900_P1_TST_CURRSRC 0xff670040
+#define F0900_P1_IN_DIGSIGNAL 0xff670020
+#define F0900_P1_HIZ_CURRENTSRC 0xff670010
+#define F0900_TST_P1_PIN_SELECT 0xff670008
+#define F0900_P1_TST_DISRX 0xff670007
+
+#define STV0900_NBREGS 684
+#define STV0900_NBFIELDS 1702
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
new file mode 100644
index 00000000000..a5a31536cbc
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -0,0 +1,2847 @@
+/*
+ * stv0900_sw.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+
+int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 carr_offset,
+ agc2_integr,
+ max_carrier;
+
+ int no_signal;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P1_CFR1);
+ carr_offset = ge2comp(carr_offset, 16);
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P1_AGC2I0);
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ break;
+ case STV0900_DEMOD_2:
+ carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P2_CFR1);
+ carr_offset = ge2comp(carr_offset, 16);
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P2_AGC2I0);
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ break;
+ }
+
+ max_carrier += (max_carrier / 10);
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ if ((agc2_integr > 0x2000)
+ || (carr_offset > + 2*max_carrier)
+ || (carr_offset < -2*max_carrier))
+ no_signal = TRUE;
+ else
+ no_signal = FALSE;
+
+ return no_signal;
+}
+
+static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
+ s32 *frequency_inc, s32 *sw_timeout,
+ s32 *steps,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 timeout, freq_inc, max_steps, srate, max_carrier;
+
+ enum fe_stv0900_search_standard standard;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ srate = i_params->dmd1_symbol_rate;
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ max_carrier += max_carrier / 10;
+ standard = i_params->dmd1_srch_standard;
+ break;
+ case STV0900_DEMOD_2:
+ srate = i_params->dmd2_symbol_rate;
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ max_carrier += max_carrier / 10;
+ standard = i_params->dmd2_srch_stndrd;
+ break;
+ }
+
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ freq_inc = srate;
+ freq_inc /= i_params->mclk >> 10;
+ freq_inc = freq_inc << 6;
+
+ switch (standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ freq_inc *= 3;
+ timeout = 20;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ freq_inc *= 4;
+ timeout = 25;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ freq_inc *= 3;
+ timeout = 25;
+ break;
+ }
+
+ freq_inc /= 100;
+
+ if ((freq_inc > max_carrier) || (freq_inc < 0))
+ freq_inc = max_carrier / 2;
+
+ timeout *= 27500;
+
+ if (srate > 0)
+ timeout /= srate / 1000;
+
+ if ((timeout > 100) || (timeout < 0))
+ timeout = 100;
+
+ max_steps = (max_carrier / freq_inc) + 1;
+
+ if ((max_steps > 100) || (max_steps < 0)) {
+ max_steps = 100;
+ freq_inc = max_carrier / max_steps;
+ }
+
+ *frequency_inc = freq_inc;
+ *sw_timeout = timeout;
+ *steps = max_steps;
+
+}
+
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
+ s32 FreqIncr, s32 Timeout, int zigzag,
+ s32 MaxStep, enum fe_stv0900_demod_num demod)
+{
+ int no_signal,
+ lock = FALSE;
+ s32 stepCpt,
+ freqOffset,
+ max_carrier;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ max_carrier += (max_carrier / 10);
+ break;
+ case STV0900_DEMOD_2:
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ max_carrier += (max_carrier / 10);
+ break;
+ }
+
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ if (zigzag == TRUE)
+ freqOffset = 0;
+ else
+ freqOffset = -max_carrier + FreqIncr;
+
+ stepCpt = 0;
+
+ do {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1,
+ (freqOffset / 256) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0,
+ freqOffset & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params,
+ F0900_P1_RST_HWARE, 1);
+ stv0900_write_bits(i_params,
+ F0900_P1_RST_HWARE, 0);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1,
+ (freqOffset / 256) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0,
+ freqOffset & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params,
+ F0900_P2_RST_HWARE, 1);
+ stv0900_write_bits(i_params,
+ F0900_P2_RST_HWARE, 0);
+ }
+ break;
+ }
+
+ if (zigzag == TRUE) {
+ if (freqOffset >= 0)
+ freqOffset = -freqOffset - 2 * FreqIncr;
+ else
+ freqOffset = -freqOffset;
+ } else
+ freqOffset += + 2 * FreqIncr;
+
+ stepCpt++;
+ lock = stv0900_get_demod_lock(i_params, demod, Timeout);
+ no_signal = stv0900_check_signal_presence(i_params, demod);
+
+ } while ((lock == FALSE)
+ && (no_signal == FALSE)
+ && ((freqOffset - FreqIncr) < max_carrier)
+ && ((freqOffset + FreqIncr) > -max_carrier)
+ && (stepCpt < MaxStep));
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+ break;
+ }
+
+ return lock;
+}
+
+int stv0900_sw_algo(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ int lock = FALSE;
+
+ int no_signal,
+ zigzag;
+ s32 dvbs2_fly_wheel;
+
+ s32 freqIncrement, softStepTimeout, trialCounter, max_steps;
+
+ stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout,
+ &max_steps, demod);
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_srch_standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0x3B);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0xef);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49);
+ zigzag = FALSE;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x68);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+ 0x89);
+
+ zigzag = TRUE;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0x3B);
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x79);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0xef);
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x68);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+ 0xc9);
+ zigzag = FALSE;
+ break;
+ }
+
+ trialCounter = 0;
+ do {
+ lock = stv0900_search_carr_sw_loop(i_params,
+ freqIncrement,
+ softStepTimeout,
+ zigzag,
+ max_steps,
+ demod);
+ no_signal = stv0900_check_signal_presence(i_params,
+ demod);
+ trialCounter++;
+ if ((lock == TRUE)
+ || (no_signal == TRUE)
+ || (trialCounter == 2)) {
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params,
+ R0900_P1_CARFREQ,
+ 0x49);
+ stv0900_write_reg(i_params,
+ R0900_P1_CORRELABS,
+ 0x9e);
+ } else {
+ stv0900_write_reg(i_params,
+ R0900_P1_CARFREQ,
+ 0xed);
+ stv0900_write_reg(i_params,
+ R0900_P1_CORRELABS,
+ 0x88);
+ }
+
+ if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
+
+ if (dvbs2_fly_wheel < 0xd) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
+ }
+
+ if (dvbs2_fly_wheel < 0xd) {
+ lock = FALSE;
+
+ if (trialCounter < 2) {
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89);
+ }
+ }
+ }
+ }
+
+ } while ((lock == FALSE)
+ && (trialCounter < 2)
+ && (no_signal == FALSE));
+
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_srch_stndrd) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0x3b);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0xef);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD,
+ 0x49);
+ zigzag = FALSE;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x68);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+ zigzag = TRUE;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0x3b);
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x79);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0xef);
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x68);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9);
+
+ zigzag = FALSE;
+ break;
+ }
+
+ trialCounter = 0;
+
+ do {
+ lock = stv0900_search_carr_sw_loop(i_params,
+ freqIncrement,
+ softStepTimeout,
+ zigzag,
+ max_steps,
+ demod);
+ no_signal = stv0900_check_signal_presence(i_params,
+ demod);
+ trialCounter++;
+ if ((lock == TRUE)
+ || (no_signal == TRUE)
+ || (trialCounter == 2)) {
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params,
+ R0900_P2_CARFREQ,
+ 0x49);
+ stv0900_write_reg(i_params,
+ R0900_P2_CORRELABS,
+ 0x9e);
+ } else {
+ stv0900_write_reg(i_params,
+ R0900_P2_CARFREQ,
+ 0xed);
+ stv0900_write_reg(i_params,
+ R0900_P2_CORRELABS,
+ 0x88);
+ }
+
+ if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
+ if (dvbs2_fly_wheel < 0xd) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
+ }
+
+ if (dvbs2_fly_wheel < 0xd) {
+ lock = FALSE;
+ if (trialCounter < 2) {
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+ }
+ }
+ }
+ }
+
+ } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE));
+
+ break;
+ }
+
+ return lock;
+}
+
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0,
+ rem1, rem2, intval1, intval2, srate;
+
+ dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3);
+ dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2);
+ dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1);
+ dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0);
+
+ srate = (stv0900_get_bits(i_params, sfr_field3) << 24) +
+ (stv0900_get_bits(i_params, sfr_field2) << 16) +
+ (stv0900_get_bits(i_params, sfr_field1) << 8) +
+ (stv0900_get_bits(i_params, sfr_field0));
+ dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
+ srate, stv0900_get_bits(i_params, sfr_field0),
+ stv0900_get_bits(i_params, sfr_field1),
+ stv0900_get_bits(i_params, sfr_field2),
+ stv0900_get_bits(i_params, sfr_field3));
+
+ intval1 = (mclk) >> 16;
+ intval2 = (srate) >> 16;
+
+ rem1 = (mclk) % 0x10000;
+ rem2 = (srate) % 0x10000;
+ srate = (intval1 * intval2) +
+ ((intval1 * rem2) >> 16) +
+ ((intval2 * rem1) >> 16);
+
+ return srate;
+}
+
+static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_init_reg;
+ u32 symb;
+
+ dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
+ srate, demod);
+
+ dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
+
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF));
+}
+
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_max_reg;
+ u32 symb;
+
+ dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1);
+
+ srate = 105 * (srate / 100);
+
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ if (symb < 0x7fff) {
+ stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF));
+ } else {
+ stv0900_write_reg(i_params, sfr_max_reg, 0x7F);
+ stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF);
+ }
+}
+
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_min_reg;
+ u32 symb;
+
+ dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1);
+
+ srate = 95 * (srate / 100);
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF));
+}
+
+static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
+ u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 tmgreg,
+ timingoffset;
+
+ dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2);
+
+ timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) +
+ (stv0900_read_reg(i_params, tmgreg + 1) << 8) +
+ (stv0900_read_reg(i_params, tmgreg + 2));
+
+ timingoffset = ge2comp(timingoffset, 24);
+
+
+ if (timingoffset == 0)
+ timingoffset = 1;
+
+ timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
+ timingoffset /= 320;
+
+ return timingoffset;
+}
+
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld;
+
+ dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF);
+ dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1);
+ dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL,
+ F0900_P2_ROLLOFF_CONTROL);
+
+ if (i_params->chip_id == 0x10) {
+ stv0900_write_bits(i_params, man_fld, 1);
+ rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03;
+ stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff);
+ } else
+ stv0900_write_bits(i_params, man_fld, 0);
+}
+
+static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
+{
+ u32 rolloff;
+
+ switch (ro) {
+ case STV0900_20:
+ rolloff = 20;
+ break;
+ case STV0900_25:
+ rolloff = 25;
+ break;
+ case STV0900_35:
+ default:
+ rolloff = 35;
+ break;
+ }
+
+ return srate + (srate * rolloff) / 100;
+}
+
+static int stv0900_check_timing_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ int timingLock = FALSE;
+ s32 i,
+ timingcpt = 0;
+ u8 carFreq,
+ tmgTHhigh,
+ tmgTHLow;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ);
+ tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE);
+ tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x80);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40);
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ msleep(7);
+
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ msleep(1);
+ }
+
+ if (timingcpt >= 3)
+ timingLock = TRUE;
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow);
+ break;
+ case STV0900_DEMOD_2:
+ carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ);
+ tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE);
+ tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x80);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40);
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ msleep(5);
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ msleep(1);
+ }
+
+ if (timingcpt >= 3)
+ timingLock = TRUE;
+
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow);
+ break;
+ }
+
+ return timingLock;
+}
+
+static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
+ s32 demod_timeout)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ int lock = FALSE;
+ s32 srate, search_range, locktimeout,
+ currier_step, nb_steps, current_step,
+ direction, tuner_freq, timeout;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ srate = i_params->dmd1_symbol_rate;
+ search_range = i_params->dmd1_srch_range;
+ break;
+
+ case STV0900_DEMOD_2:
+ srate = i_params->dmd2_symbol_rate;
+ search_range = i_params->dmd2_srch_range;
+ break;
+ }
+
+ if (srate >= 10000000)
+ locktimeout = demod_timeout / 3;
+ else
+ locktimeout = demod_timeout / 2;
+
+ lock = stv0900_get_demod_lock(i_params, demod, locktimeout);
+
+ if (lock == FALSE) {
+ if (srate >= 10000000) {
+ if (stv0900_check_timing_lock(i_params, demod) == TRUE) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ break;
+ }
+
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+ } else
+ lock = FALSE;
+ } else {
+ if (srate <= 4000000)
+ currier_step = 1000;
+ else if (srate <= 7000000)
+ currier_step = 2000;
+ else if (srate <= 10000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+ nb_steps = ((search_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * (nb_steps + 1));
+ if (nb_steps < 0)
+ nb_steps = 2;
+ else if (nb_steps > 12)
+ nb_steps = 12;
+
+ current_step = 1;
+ direction = 1;
+ timeout = (demod_timeout / 3);
+ if (timeout > 1000)
+ timeout = 1000;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (lock == FALSE) {
+ tuner_freq = i_params->tuner1_freq;
+ i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate;
+
+ while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ lock = stv0900_get_demod_lock(i_params, demod, timeout);
+ direction *= -1;
+ current_step++;
+ }
+ }
+ break;
+ case STV0900_DEMOD_2:
+ if (lock == FALSE) {
+ tuner_freq = i_params->tuner2_freq;
+ i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate;
+
+ while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ lock = stv0900_get_demod_lock(i_params, demod, timeout);
+ direction *= -1;
+ current_step++;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return lock;
+}
+
+static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
+ s32 srate,
+ enum fe_stv0900_search_algo algo)
+{
+ switch (algo) {
+ case STV0900_BLIND_SEARCH:
+ if (srate <= 1500000) {
+ (*demod_timeout) = 1500;
+ (*fec_timeout) = 400;
+ } else if (srate <= 5000000) {
+ (*demod_timeout) = 1000;
+ (*fec_timeout) = 300;
+ } else {
+ (*demod_timeout) = 700;
+ (*fec_timeout) = 100;
+ }
+
+ break;
+ case STV0900_COLD_START:
+ case STV0900_WARM_START:
+ default:
+ if (srate <= 1000000) {
+ (*demod_timeout) = 3000;
+ (*fec_timeout) = 1700;
+ } else if (srate <= 2000000) {
+ (*demod_timeout) = 2500;
+ (*fec_timeout) = 1100;
+ } else if (srate <= 5000000) {
+ (*demod_timeout) = 1000;
+ (*fec_timeout) = 550;
+ } else if (srate <= 10000000) {
+ (*demod_timeout) = 700;
+ (*fec_timeout) = 250;
+ } else if (srate <= 20000000) {
+ (*demod_timeout) = 400;
+ (*fec_timeout) = 130;
+ }
+
+ else {
+ (*demod_timeout) = 300;
+ (*fec_timeout) = 100;
+ }
+
+ break;
+
+ }
+
+ if (algo == STV0900_WARM_START)
+ (*demod_timeout) /= 2;
+}
+
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ s32 vth_reg;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+ stv0900_write_reg(i_params, vth_reg++, 0xd0);
+ stv0900_write_reg(i_params, vth_reg++, 0x7d);
+ stv0900_write_reg(i_params, vth_reg++, 0x53);
+ stv0900_write_reg(i_params, vth_reg++, 0x2F);
+ stv0900_write_reg(i_params, vth_reg++, 0x24);
+ stv0900_write_reg(i_params, vth_reg++, 0x1F);
+}
+
+static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
+ enum fe_stv0900_search_standard Standard,
+ enum fe_stv0900_fec PunctureRate,
+ enum fe_stv0900_demod_num demod)
+{
+
+ s32 fecmReg,
+ prvitReg;
+
+ dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ fecmReg = R0900_P1_FECM;
+ prvitReg = R0900_P1_PRVIT;
+ break;
+ case STV0900_DEMOD_2:
+ fecmReg = R0900_P2_FECM;
+ prvitReg = R0900_P2_PRVIT;
+ break;
+ }
+
+ switch (Standard) {
+ case STV0900_AUTO_SEARCH:
+ dprintk("Auto\n");
+ stv0900_write_reg(i_params, fecmReg, 0x10);
+ stv0900_write_reg(i_params, prvitReg, 0x3F);
+ break;
+ case STV0900_SEARCH_DVBS1:
+ dprintk("DVBS1\n");
+ stv0900_write_reg(i_params, fecmReg, 0x00);
+ switch (PunctureRate) {
+ case STV0900_FEC_UNKNOWN:
+ default:
+ stv0900_write_reg(i_params, prvitReg, 0x2F);
+ break;
+ case STV0900_FEC_1_2:
+ stv0900_write_reg(i_params, prvitReg, 0x01);
+ break;
+ case STV0900_FEC_2_3:
+ stv0900_write_reg(i_params, prvitReg, 0x02);
+ break;
+ case STV0900_FEC_3_4:
+ stv0900_write_reg(i_params, prvitReg, 0x04);
+ break;
+ case STV0900_FEC_5_6:
+ stv0900_write_reg(i_params, prvitReg, 0x08);
+ break;
+ case STV0900_FEC_7_8:
+ stv0900_write_reg(i_params, prvitReg, 0x20);
+ break;
+ }
+
+ break;
+ case STV0900_SEARCH_DSS:
+ dprintk("DSS\n");
+ stv0900_write_reg(i_params, fecmReg, 0x80);
+ switch (PunctureRate) {
+ case STV0900_FEC_UNKNOWN:
+ default:
+ stv0900_write_reg(i_params, prvitReg, 0x13);
+ break;
+ case STV0900_FEC_1_2:
+ stv0900_write_reg(i_params, prvitReg, 0x01);
+ break;
+ case STV0900_FEC_2_3:
+ stv0900_write_reg(i_params, prvitReg, 0x02);
+ break;
+ case STV0900_FEC_6_7:
+ stv0900_write_reg(i_params, prvitReg, 0x10);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void stv0900_track_optimization(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 srate, pilots, aclc, freq1, freq0,
+ i = 0, timed, timef, blindTunSw = 0;
+
+ enum fe_stv0900_rolloff rolloff;
+ enum fe_stv0900_modcode foundModcod;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_rslts.standard) {
+ case STV0900_DVBS1_STANDARD:
+ if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DSS_STANDARD:
+ if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DVBS2_STANDARD:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0);
+ if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) {
+ foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
+ pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
+ aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
+ if (foundModcod <= STV0900_QPSK_910)
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+ else if (foundModcod <= STV0900_8PSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
+ }
+
+ if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
+ if (foundModcod <= STV0900_16APSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
+ } else if (foundModcod <= STV0900_32APSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
+ }
+ }
+
+ } else {
+ aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id);
+ if (i_params->dmd1_rslts.modulation == STV0900_QPSK)
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+
+ else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
+ } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
+ } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
+ }
+
+ }
+
+ if (i_params->chip_id <= 0x11) {
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
+ break;
+ case STV0900_UNKNOWN_STANDARD:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ break;
+ }
+
+ freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
+ rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
+ blindTunSw = 1;
+ }
+
+ if (i_params->chip_id >= 0x20) {
+ if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a);
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0);
+ }
+ }
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A);
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) {
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
+ if (i_params->dmd1_srch_algo != STV0900_WARM_START)
+ stv0900_set_bandwidth(fe, i_params->tuner1_bw);
+ }
+
+ if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000))
+ msleep(50);
+ else
+ msleep(5);
+
+ stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
+
+ if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ i = 0;
+ while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ i++;
+ }
+ }
+
+ }
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+
+ if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD))
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_rslts.standard) {
+ case STV0900_DVBS1_STANDARD:
+
+ if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DSS_STANDARD:
+ if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DVBS2_STANDARD:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0);
+ if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) {
+ foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
+ pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
+ aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
+ if (foundModcod <= STV0900_QPSK_910)
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
+ else if (foundModcod <= STV0900_8PSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
+ }
+
+ if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
+ if (foundModcod <= STV0900_16APSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
+ } else if (foundModcod <= STV0900_32APSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
+ }
+
+ }
+
+ } else {
+ aclc = stv0900_get_optim_short_carr_loop(srate,
+ i_params->dmd2_rslts.modulation,
+ i_params->chip_id);
+
+ if (i_params->dmd2_rslts.modulation == STV0900_QPSK)
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
+
+ else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
+ } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
+ } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+
+ break;
+ case STV0900_UNKNOWN_STANDARD:
+ default:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ break;
+ }
+
+ freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
+ rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
+ blindTunSw = 1;
+ }
+
+ if (i_params->chip_id >= 0x20) {
+ if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a);
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0);
+ }
+ }
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a);
+
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) {
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
+ if (i_params->dmd2_srch_algo != STV0900_WARM_START)
+ stv0900_set_bandwidth(fe, i_params->tuner2_bw);
+ }
+
+ if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000))
+ msleep(50);
+ else
+ msleep(5);
+
+ stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
+ if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ i = 0;
+ while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ i++;
+ }
+ }
+ }
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+
+ if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD))
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+ }
+}
+
+static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out)
+{
+ s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field;
+
+ enum fe_stv0900_search_state dmd_state;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
+ dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+
+ dmd_state = stv0900_get_bits(i_params, header_field);
+
+ while ((timer < time_out) && (lock == 0)) {
+ switch (dmd_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ lock = 0;
+ break;
+ case STV0900_DVBS2_FOUND:
+ lock = stv0900_get_bits(i_params, pktdelin_field);
+ break;
+ case STV0900_DVBS_FOUND:
+ lock = stv0900_get_bits(i_params, lock_vit_field);
+ break;
+ }
+
+ if (lock == 0) {
+ msleep(10);
+ timer += 10;
+ }
+ }
+
+ if (lock)
+ dprintk("DEMOD FEC LOCK OK\n");
+ else
+ dprintk("DEMOD FEC LOCK FAIL\n");
+
+ return lock;
+}
+
+static int stv0900_wait_for_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod,
+ s32 dmd_timeout, s32 fec_timeout)
+{
+
+ s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
+ dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+
+ lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout);
+
+ if (lock)
+ lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout);
+
+ if (lock) {
+ lock = 0;
+
+ dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout);
+
+ while ((timer < fec_timeout) && (lock == 0)) {
+ lock = stv0900_get_bits(i_params, str_merg_lock_fld);
+ msleep(1);
+ timer++;
+ }
+ }
+
+ if (lock)
+ dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__);
+ else
+ dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__);
+
+ if (lock)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+ enum fe_stv0900_demod_num demod)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_tracking_standard fnd_standard;
+ s32 state_field,
+ dss_dvb_field;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB);
+
+ if (stv0900_get_bits(i_params, state_field) == 2)
+ fnd_standard = STV0900_DVBS2_STANDARD;
+
+ else if (stv0900_get_bits(i_params, state_field) == 3) {
+ if (stv0900_get_bits(i_params, dss_dvb_field) == 1)
+ fnd_standard = STV0900_DSS_STANDARD;
+ else
+ fnd_standard = STV0900_DVBS1_STANDARD;
+ } else
+ fnd_standard = STV0900_UNKNOWN_STANDARD;
+
+ return fnd_standard;
+}
+
+static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 cfr_field2, cfr_field1, cfr_field0,
+ derot, rem1, rem2, intval1, intval2;
+
+ dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2);
+ dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1);
+ dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0);
+
+ derot = (stv0900_get_bits(i_params, cfr_field2) << 16) +
+ (stv0900_get_bits(i_params, cfr_field1) << 8) +
+ (stv0900_get_bits(i_params, cfr_field0));
+
+ derot = ge2comp(derot, 24);
+ intval1 = mclk >> 12;
+ intval2 = derot >> 12;
+ rem1 = mclk % 0x1000;
+ rem2 = derot % 0x1000;
+ derot = (intval1 * intval2) +
+ ((intval1 * rem2) >> 12) +
+ ((intval2 * rem1) >> 12);
+
+ return derot;
+}
+
+static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ u32 frequency = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->get_frequency) {
+ if ((tuner_ops->get_frequency(fe, &frequency)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+ }
+
+ return frequency;
+}
+
+static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 rate_fld, vit_curpun_fld;
+ enum fe_stv0900_fec prate;
+
+ dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN);
+ rate_fld = stv0900_get_bits(i_params, vit_curpun_fld);
+
+ switch (rate_fld) {
+ case 13:
+ prate = STV0900_FEC_1_2;
+ break;
+ case 18:
+ prate = STV0900_FEC_2_3;
+ break;
+ case 21:
+ prate = STV0900_FEC_3_4;
+ break;
+ case 24:
+ prate = STV0900_FEC_5_6;
+ break;
+ case 25:
+ prate = STV0900_FEC_6_7;
+ break;
+ case 26:
+ prate = STV0900_FEC_7_8;
+ break;
+ default:
+ prate = STV0900_FEC_UNKNOWN;
+ break;
+ }
+
+ return prate;
+}
+
+static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
+ s32 offsetFreq,
+ srate_offset,
+ i = 0;
+
+ u8 timing;
+
+ msleep(5);
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
+ i = 0;
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c);
+
+ while ((i <= 50) && (timing != 0) && (timing != 0xFF)) {
+ timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+
+ i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod);
+ i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe);
+ offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
+ i_params->dmd1_rslts.frequency += offsetFreq;
+ i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod);
+ i_params->dmd1_rslts.symbol_rate += srate_offset;
+ i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod);
+ i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
+ i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
+ i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1;
+ i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
+ switch (i_params->dmd1_rslts.standard) {
+ case STV0900_DVBS2_STANDARD:
+ i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD);
+ if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_QPSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_8PSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_16APSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_32APSK;
+ else
+ i_params->dmd1_rslts.modulation = STV0900_UNKNOWN;
+ break;
+ case STV0900_DVBS1_STANDARD:
+ case STV0900_DSS_STANDARD:
+ i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV);
+ i_params->dmd1_rslts.modulation = STV0900_QPSK;
+ break;
+ default:
+ break;
+ }
+
+ if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) {
+ offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq;
+ i_params->tuner1_freq = stv0900_get_tuner_freq(fe);
+ if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+
+ } else {
+ if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
+ i = 0;
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c);
+
+ while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
+ timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+
+ i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod);
+ i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe);
+ offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
+ i_params->dmd2_rslts.frequency += offsetFreq;
+ i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod);
+ i_params->dmd2_rslts.symbol_rate += srate_offset;
+ i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod);
+ i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
+ i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
+ i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1;
+ i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
+ switch (i_params->dmd2_rslts.standard) {
+ case STV0900_DVBS2_STANDARD:
+ i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD);
+ if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_QPSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_8PSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_16APSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_32APSK;
+ else
+ i_params->dmd2_rslts.modulation = STV0900_UNKNOWN;
+ break;
+ case STV0900_DVBS1_STANDARD:
+ case STV0900_DSS_STANDARD:
+ i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV);
+ i_params->dmd2_rslts.modulation = STV0900_QPSK;
+ break;
+ default:
+ break;
+ }
+
+ if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) {
+ offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq;
+ i_params->tuner2_freq = stv0900_get_tuner_freq(fe);
+
+ if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ } else {
+ if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ }
+
+ break;
+ }
+
+ return range;
+}
+
+static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 srate, demod_timeout,
+ fec_timeout, freq1, freq0;
+ enum fe_stv0900_signal_type signal_type = STV0900_NODATA;;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = FALSE;
+ if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) {
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH)
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
+ freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd1_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ } else {
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd1_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ }
+
+ }
+
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = FALSE;
+ if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) {
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH)
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
+ freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd2_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ } else {
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd2_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ }
+
+ }
+
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ }
+
+ return signal_type;
+}
+
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 minagc2level = 0xffff,
+ agc2level,
+ init_freq, freq_step;
+
+ s32 i, j, nb_steps, direction;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ nb_steps = -1 + (i_params->dmd1_srch_range / 1000000);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ direction = 1;
+
+ freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+
+ init_freq = 0;
+
+ for (i = 0; i < nb_steps; i++) {
+ if (direction > 0)
+ init_freq = init_freq + (freq_step * i);
+ else
+ init_freq = init_freq - (freq_step * i);
+
+ direction *= -1;
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58);
+ msleep(10);
+ agc2level = 0;
+
+ for (j = 0; j < 10; j++)
+ agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ agc2level /= 10;
+
+ if (agc2level < minagc2level)
+ minagc2level = agc2level;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ nb_steps = -1 + (i_params->dmd2_srch_range / 1000000);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ direction = 1;
+ freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+ init_freq = 0;
+ for (i = 0; i < nb_steps; i++) {
+ if (direction > 0)
+ init_freq = init_freq + (freq_step * i);
+ else
+ init_freq = init_freq - (freq_step * i);
+
+ direction *= -1;
+
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58);
+
+ msleep(10);
+ agc2level = 0;
+ for (j = 0; j < 10; j++)
+ agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+
+ agc2level /= 10;
+
+ if (agc2level < minagc2level)
+ minagc2level = agc2level;
+ }
+ break;
+ }
+
+ return (u16)minagc2level;
+}
+
+static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ int timingLock = FALSE;
+ s32 i, timingcpt = 0,
+ direction = 1,
+ nb_steps,
+ current_step = 0,
+ tuner_freq;
+
+ u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a);
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73);
+ }
+
+ if (i_params->dmd1_symbol_rate <= 2000000)
+ currier_step = 1000;
+ else if (i_params->dmd1_symbol_rate <= 5000000)
+ currier_step = 2000;
+ else if (i_params->dmd1_symbol_rate <= 12000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+ nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ else if (nb_steps > 10) {
+ nb_steps = 11;
+ currier_step = (i_params->dmd1_srch_range / 1000) / 10;
+ }
+
+ current_step = 0;
+
+ direction = 1;
+ tuner_freq = i_params->tuner1_freq;
+
+ while ((timingLock == FALSE) && (current_step < nb_steps)) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F);
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0);
+
+ msleep(50);
+
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ }
+
+ agc2_integr /= 10;
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ current_step++;
+ direction *= -1;
+
+ dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt);
+
+ if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) {
+ timingLock = TRUE;
+ }
+
+ else if (current_step < nb_steps) {
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+ }
+ }
+
+ if (timingLock == FALSE)
+ coarse_srate = 0;
+ else
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a);
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73);
+ }
+
+ if (i_params->dmd2_symbol_rate <= 2000000)
+ currier_step = 1000;
+ else if (i_params->dmd2_symbol_rate <= 5000000)
+ currier_step = 2000;
+ else if (i_params->dmd2_symbol_rate <= 12000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+
+ nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+ else if (nb_steps > 10) {
+ nb_steps = 11;
+ currier_step = (i_params->dmd2_srch_range / 1000) / 10;
+ }
+
+ current_step = 0;
+ direction = 1;
+ tuner_freq = i_params->tuner2_freq;
+
+ while ((timingLock == FALSE) && (current_step < nb_steps)) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F);
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0);
+
+ msleep(50);
+ timingcpt = 0;
+
+ for (i = 0; i < 20; i++) {
+ if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+ agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+ }
+
+ agc2_integr /= 20;
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000))
+ timingLock = TRUE;
+ else {
+ current_step++;
+ direction *= -1;
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
+ }
+ }
+
+ if (timingLock == FALSE)
+ coarse_srate = 0;
+ else
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ break;
+ }
+
+ return coarse_srate;
+}
+
+static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ u32 coarse_srate,
+ coarse_freq,
+ symb;
+
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_CFR1);
+ symb = 13 * (coarse_srate / 10);
+
+ if (symb < i_params->dmd1_symbol_rate)
+ coarse_srate = 0;
+ else {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+
+ if (coarse_srate > 3000000) {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 13);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
+ } else {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 14);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_CFR1);
+
+ symb = 13 * (coarse_srate / 10);
+
+ if (symb < i_params->dmd2_symbol_rate)
+ coarse_srate = 0;
+ else {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+
+ if (coarse_srate > 3000000) {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 13);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
+ } else {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 14);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ }
+
+ break;
+ }
+
+ return coarse_srate;
+}
+
+static int stv0900_blind_search_algo(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min;
+ u32 coarse_srate;
+ int lock = FALSE, coarse_fail = FALSE;
+ s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow;
+ u16 agc2_integr;
+ u8 dstatus2;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id < 0x20) {
+ k_ref_tmg_max = 233;
+ k_ref_tmg_min = 143;
+ } else {
+ k_ref_tmg_max = 120;
+ k_ref_tmg_min = 30;
+ }
+
+ agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod);
+
+ if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) {
+ lock = FALSE;
+
+ } else {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
+ }
+
+ kref_tmg_reg = R0900_P1_KREFTMG;
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
+ }
+
+ kref_tmg_reg = R0900_P2_KREFTMG;
+ break;
+ }
+
+ k_ref_tmg = k_ref_tmg_max;
+
+ do {
+ stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg);
+ if (stv0900_search_srate_coarse(fe) != 0) {
+ coarse_srate = stv0900_search_srate_fine(fe);
+
+ if (coarse_srate != 0) {
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH);
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+ } else
+ lock = FALSE;
+ } else {
+ fail_cpt = 0;
+ agc2_overflow = 0;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ for (i = 0; i < 10; i++) {
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ if (agc2_integr >= 0xff00)
+ agc2_overflow++;
+
+ dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2);
+
+ if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+ fail_cpt++;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ for (i = 0; i < 10; i++) {
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+
+ if (agc2_integr >= 0xff00)
+ agc2_overflow++;
+
+ dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2);
+
+ if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+ fail_cpt++;
+ }
+ break;
+ }
+
+ if ((fail_cpt > 7) || (agc2_overflow > 7))
+ coarse_fail = TRUE;
+
+ lock = FALSE;
+ }
+ k_ref_tmg -= 30;
+ } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE));
+ }
+
+ return lock;
+}
+
+static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 vth_reg;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+ stv0900_write_reg(i_params, vth_reg++, 0x96);
+ stv0900_write_reg(i_params, vth_reg++, 0x64);
+ stv0900_write_reg(i_params, vth_reg++, 0x36);
+ stv0900_write_reg(i_params, vth_reg++, 0x23);
+ stv0900_write_reg(i_params, vth_reg++, 0x1E);
+ stv0900_write_reg(i_params, vth_reg++, 0x19);
+}
+
+static void stv0900_set_search_standard(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ int sstndrd;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ sstndrd = i_params->dmd1_srch_standard;
+ if (demod == 1)
+ sstndrd = i_params->dmd2_srch_stndrd;
+
+ switch (sstndrd) {
+ case STV0900_SEARCH_DVBS1:
+ dprintk("Search Standard = DVBS1\n");
+ break;
+ case STV0900_SEARCH_DSS:
+ dprintk("Search Standard = DSS\n");
+ case STV0900_SEARCH_DVBS2:
+ break;
+ dprintk("Search Standard = DVBS2\n");
+ case STV0900_AUTO_SEARCH:
+ default:
+ dprintk("Search Standard = AUTO\n");
+ break;
+ }
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_srch_standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22);
+
+ stv0900_set_viterbi_acq(i_params, demod);
+ stv0900_set_viterbi_standard(i_params,
+ i_params->dmd1_srch_standard,
+ i_params->dmd1_fec, demod);
+
+ break;
+ case STV0900_SEARCH_DVBS2:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE) {
+ if (i_params->chip_id <= 0x11)
+ stv0900_stop_all_s2_modcod(i_params, demod);
+ else
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ } else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE) {
+ if (i_params->chip_id <= 0x11)
+ stv0900_stop_all_s2_modcod(i_params, demod);
+ else
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ } else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ if (i_params->dmd1_symbol_rate >= 2000000)
+ stv0900_set_viterbi_acq(i_params, demod);
+ else
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod);
+
+ break;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_srch_stndrd) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22);
+ stv0900_set_viterbi_acq(i_params, demod);
+ stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+ break;
+ case STV0900_SEARCH_DVBS2:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+ else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ stv0900_set_viterbi_tracq(i_params, demod);
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+ else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ if (i_params->dmd2_symbol_rate >= 2000000)
+ stv0900_set_viterbi_acq(i_params, demod);
+ else
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+
+ break;
+ }
+
+ break;
+ }
+}
+
+enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field;
+
+ int lock = FALSE, low_sr = FALSE;
+
+ enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
+ enum fe_stv0900_search_algo algo;
+ int no_signal = FALSE;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ algo = i_params->dmd1_srch_algo;
+
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
+ stream_merger_field = F0900_P1_RST_HWARE;
+
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo);
+
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ i_params->tuner1_bw = 2 * 36000000;
+
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
+
+ if (i_params->dmd1_symbol_rate < 2000000)
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a);
+
+ if (i_params->dmd1_srch_algo == STV0900_COLD_START)
+ i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
+ else if (i_params->dmd1_srch_algo == STV0900_WARM_START)
+ i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000;
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1);
+ i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ if (i_params->dmd1_symbol_rate >= 10000000)
+ low_sr = FALSE;
+ else
+ low_sr = TRUE;
+
+ }
+
+ stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw);
+
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+
+ stv0900_set_search_standard(i_params, demod);
+
+ if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH)
+ stv0900_start_search(i_params, demod);
+ break;
+ case STV0900_DEMOD_2:
+ algo = i_params->dmd2_srch_algo;
+
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+
+ stream_merger_field = F0900_P2_RST_HWARE;
+
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo);
+
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ i_params->tuner2_bw = 2 * 36000000;
+
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+
+ if (i_params->dmd2_symbol_rate < 2000000)
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+ if (i_params->dmd2_symbol_rate >= 10000000)
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ else
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a);
+
+ if (i_params->dmd2_srch_algo == STV0900_COLD_START)
+ i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000)) / 10;
+ else if (i_params->dmd2_srch_algo == STV0900_WARM_START)
+ i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000;
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1);
+ i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000)) / 10;
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ if (i_params->dmd2_symbol_rate >= 10000000)
+ low_sr = FALSE;
+ else
+ low_sr = TRUE;
+
+ }
+
+ stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw);
+
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+
+ stv0900_set_search_standard(i_params, demod);
+
+ if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH)
+ stv0900_start_search(i_params, demod);
+ break;
+ }
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+
+ if (algo == STV0900_BLIND_SEARCH)
+ lock = stv0900_blind_search_algo(fe);
+ else if (algo == STV0900_COLD_START)
+ lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
+ else if (algo == STV0900_WARM_START)
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+
+ if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
+ if (low_sr == FALSE) {
+ if (stv0900_check_timing_lock(i_params, demod) == TRUE)
+ lock = stv0900_sw_algo(i_params, demod);
+ }
+ }
+
+ if (lock == TRUE)
+ signal_type = stv0900_get_signal_params(fe);
+
+ if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
+ stv0900_track_optimization(fe);
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) {
+ msleep(20);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ } else {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+ } else if (i_params->chip_id == 0x20) {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+
+ if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) {
+ lock = TRUE;
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = TRUE;
+ if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) {
+ stv0900_set_dvbs2_rolloff(i_params, demod);
+ stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40);
+ stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1);
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = TRUE;
+
+ if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) {
+ stv0900_set_dvbs2_rolloff(i_params, demod);
+ stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60);
+ stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0);
+
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1);
+ break;
+ }
+ } else {
+ lock = FALSE;
+ signal_type = STV0900_NODATA;
+ no_signal = stv0900_check_signal_presence(i_params, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = FALSE;
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) &&
+ (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
+ signal_type = stv0900_dvbs1_acq_workaround(fe);
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) &&
+ (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
+ signal_type = stv0900_dvbs1_acq_workaround(fe);
+ } else
+ i_params->dmd2_rslts.locked = FALSE;
+ break;
+ }
+ }
+
+ return signal_type;
+}
+
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
new file mode 100644
index 00000000000..70efac869d2
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -0,0 +1,456 @@
+/*
+ * stv6110.c
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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 <linux/types.h>
+
+#include "stv6110.h"
+
+static int debug;
+
+struct stv6110_priv {
+ int i2c_address;
+ struct i2c_adapter *i2c;
+
+ u32 mclk;
+ u8 regs[8];
+};
+
+#define dprintk(args...) \
+ do { \
+ if (debug) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+static s32 abssub(s32 a, s32 b)
+{
+ if (a > b)
+ return a - b;
+ else
+ return b - a;
+};
+
+static int stv6110_release(struct dvb_frontend *fe)
+{
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
+ int start, int len)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ int rc;
+ u8 cmdbuf[len + 1];
+ struct i2c_msg msg = {
+ .addr = priv->i2c_address,
+ .flags = 0,
+ .buf = cmdbuf,
+ .len = len + 1
+ };
+
+ dprintk("%s\n", __func__);
+
+ if (start + len > 8)
+ return -EINVAL;
+
+ memcpy(&cmdbuf[1], buf, len);
+ cmdbuf[0] = start;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+}
+
+static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
+ int start, int len)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ int rc;
+ u8 reg[] = { start };
+ struct i2c_msg msg_wr = {
+ .addr = priv->i2c_address,
+ .flags = 0,
+ .buf = reg,
+ .len = 1,
+ };
+
+ struct i2c_msg msg_rd = {
+ .addr = priv->i2c_address,
+ .flags = I2C_M_RD,
+ .buf = regs,
+ .len = len,
+ };
+ /* write subaddr */
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg_wr, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ /* read registers */
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg_rd, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ memcpy(&priv->regs[start], regs, len);
+
+ return 0;
+}
+
+static int stv6110_read_reg(struct dvb_frontend *fe, int start)
+{
+ u8 buf[] = { 0 };
+ stv6110_read_regs(fe, buf, start, 1);
+
+ return buf[0];
+}
+
+static int stv6110_sleep(struct dvb_frontend *fe)
+{
+ u8 reg[] = { 0 };
+ stv6110_write_regs(fe, reg, 0, 1);
+
+ return 0;
+}
+
+static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
+{
+ u32 rlf;
+
+ switch (rolloff) {
+ case ROLLOFF_20:
+ rlf = 20;
+ break;
+ case ROLLOFF_25:
+ rlf = 25;
+ break;
+ default:
+ rlf = 35;
+ break;
+ }
+
+ return symbol_rate + ((symbol_rate * rlf) / 100);
+}
+
+static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 r8, ret = 0x04;
+ int i;
+
+ if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
+ r8 = 31;
+ else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
+ r8 = 0;
+ else /*if 5 < BW/2 < 36*/
+ r8 = (bandwidth / 2) / 1000000 - 5;
+
+ /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
+ /* ctrl3, CF = r8 Set the LPF value */
+ priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
+ priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+ /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
+ priv->regs[RSTV6110_STAT1] |= 0x02;
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
+
+ i = 0;
+ /* Wait for CALRCSTRT == 0 */
+ while ((i < 10) && (ret != 0)) {
+ ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
+ mdelay(1); /* wait for LPF auto calibration */
+ i++;
+ }
+
+ /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
+ priv->regs[RSTV6110_CTRL3] |= (1 << 6);
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+ return 0;
+}
+
+static int stv6110_init(struct dvb_frontend *fe)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+ memcpy(priv->regs, buf0, 8);
+ /* K = (Reference / 1000000) - 16 */
+ priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+ priv->regs[RSTV6110_CTRL1] |=
+ ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
+ msleep(1);
+ stv6110_set_bandwidth(fe, 72000000);
+
+ return 0;
+}
+
+static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u32 nbsteps, divider, psd2, freq;
+ u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ stv6110_read_regs(fe, regs, 0, 8);
+ /*N*/
+ divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
+ divider += priv->regs[RSTV6110_TUNING1];
+
+ /*R*/
+ nbsteps = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
+ /*p*/
+ psd2 = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
+
+ freq = divider * (priv->mclk / 1000);
+ freq /= (1 << (nbsteps + psd2));
+ freq /= 4;
+
+ *frequency = freq;
+
+ return 0;
+}
+
+static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u8 ret = 0x04;
+ u32 divider, ref, p, presc, i, result_freq, vco_freq;
+ s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
+ s32 srate; u8 gain;
+
+ dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
+ frequency, priv->mclk);
+
+ /* K = (Reference / 1000000) - 16 */
+ priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+ priv->regs[RSTV6110_CTRL1] |=
+ ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+ /* BB_GAIN = db/2 */
+ if (fe->ops.set_property && fe->ops.get_property) {
+ srate = c->symbol_rate;
+ dprintk("%s: Get Frontend parameters: srate=%d\n",
+ __func__, srate);
+ } else
+ srate = 15000000;
+
+ if (srate >= 15000000)
+ gain = 3; /* +6 dB */
+ else if (srate >= 5000000)
+ gain = 3; /* +6 dB */
+ else
+ gain = 3; /* +6 dB */
+
+ priv->regs[RSTV6110_CTRL2] &= ~0x0f;
+ priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f);
+
+ if (frequency <= 1023000) {
+ p = 1;
+ presc = 0;
+ } else if (frequency <= 1300000) {
+ p = 1;
+ presc = 1;
+ } else if (frequency <= 2046000) {
+ p = 0;
+ presc = 0;
+ } else {
+ p = 0;
+ presc = 1;
+ }
+ /* DIV4SEL = p*/
+ priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
+ priv->regs[RSTV6110_TUNING2] |= (p << 4);
+
+ /* PRESC32ON = presc */
+ priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
+ priv->regs[RSTV6110_TUNING2] |= (presc << 5);
+
+ p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
+ for (r_div = 0; r_div <= 3; r_div++) {
+ p_calc = (priv->mclk / 100000);
+ p_calc /= (1 << (r_div + 1));
+ if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
+ r_div_opt = r_div;
+
+ p_calc_opt = (priv->mclk / 100000);
+ p_calc_opt /= (1 << (r_div_opt + 1));
+ }
+
+ ref = priv->mclk / ((1 << (r_div_opt + 1)) * (1 << (p + 1)));
+ divider = (((frequency * 1000) + (ref >> 1)) / ref);
+
+ /* RDIV = r_div_opt */
+ priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
+ priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
+
+ /* NDIV_MSB = MSB(divider) */
+ priv->regs[RSTV6110_TUNING2] &= ~0x0f;
+ priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
+
+ /* NDIV_LSB, LSB(divider) */
+ priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
+
+ /* CALVCOSTRT = 1 VCO Auto Calibration */
+ priv->regs[RSTV6110_STAT1] |= 0x04;
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
+ RSTV6110_CTRL1, 8);
+
+ i = 0;
+ /* Wait for CALVCOSTRT == 0 */
+ while ((i < 10) && (ret != 0)) {
+ ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
+ msleep(1); /* wait for VCO auto calibration */
+ i++;
+ }
+
+ ret = stv6110_read_reg(fe, RSTV6110_STAT1);
+ stv6110_get_frequency(fe, &result_freq);
+
+ vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
+ dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
+ ret, result_freq, vco_freq);
+
+ return 0;
+}
+
+static int stv6110_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
+
+ stv6110_set_frequency(fe, c->frequency);
+ stv6110_set_bandwidth(fe, bandwidth);
+
+ return 0;
+}
+
+static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 r8 = 0;
+ u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ stv6110_read_regs(fe, regs, 0, 8);
+
+ /* CF */
+ r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
+ *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
+
+ return 0;
+}
+
+static struct dvb_tuner_ops stv6110_tuner_ops = {
+ .info = {
+ .name = "ST STV6110",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 1000,
+ },
+ .init = stv6110_init,
+ .release = stv6110_release,
+ .sleep = stv6110_sleep,
+ .set_params = stv6110_set_params,
+ .get_frequency = stv6110_get_frequency,
+ .set_frequency = stv6110_set_frequency,
+ .get_bandwidth = stv6110_get_bandwidth,
+ .set_bandwidth = stv6110_set_bandwidth,
+
+};
+
+struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct stv6110_priv *priv = NULL;
+ u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = config->i2c_address,
+ .flags = 0,
+ .buf = reg0,
+ .len = 9
+ }
+ };
+ int ret;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = i2c_transfer(i2c, msg, 1);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (ret != 1)
+ return NULL;
+
+ priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->i2c_address = config->i2c_address;
+ priv->i2c = i2c;
+ priv->mclk = config->mclk;
+
+ memcpy(&priv->regs, &reg0[1], 8);
+
+ memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ fe->tuner_priv = priv;
+ printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
+
+ return fe;
+}
+EXPORT_SYMBOL(stv6110_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV6110 driver");
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
new file mode 100644
index 00000000000..1c0314d6aa5
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -0,0 +1,62 @@
+/*
+ * stv6110.h
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * 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_STV6110_H__
+#define __DVB_STV6110_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* registers */
+#define RSTV6110_CTRL1 0
+#define RSTV6110_CTRL2 1
+#define RSTV6110_TUNING1 2
+#define RSTV6110_TUNING2 3
+#define RSTV6110_CTRL3 4
+#define RSTV6110_STAT1 5
+#define RSTV6110_STAT2 6
+#define RSTV6110_STAT3 7
+
+struct stv6110_config {
+ u8 i2c_address;
+ u32 mclk;
+ int iq_wiring;
+};
+
+#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_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/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 1465ff77b0c..4981cef8b44 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
if (ret != 2) {
dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
ret);
- return -1;
+ return -EINVAL;
}
dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
@@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
static int tda10046_fwupload(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- int ret;
+ int ret, confc4;
const struct firmware *fw;
/* reset + wake up chip */
if (state->config->xtal_freq == TDA10046_XTAL_4M) {
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+ confc4 = 0;
} else {
dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+ confc4 = 0x80;
}
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
/* set GPIO 1 and 3 */
if (state->config->gpio_config != TDA10046_GPTRI) {
@@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /*
+ For i2c normal work, we need to slow down the bus speed.
+ However, the slow down breaks the eeprom firmware load.
+ So, use normal speed for eeprom booting and then restore the
+ i2c speed after that. Tested with MSI TV @nyware A/D board,
+ that comes with firmware version 29 inside their eeprom.
+
+ It should also be noticed that no other I2C transfer should
+ be in course while booting from eeprom, otherwise, tda10046
+ goes into an instable state. So, proper locking are needed
+ at the i2c bus master.
+ */
printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
- tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
msleep(300);
- /* don't re-upload unless necessary */
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+ /* Checks if eeprom firmware went without troubles */
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /* eeprom firmware didn't work. Load one manually. */
+
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");
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
new file mode 100644
index 00000000000..e22a0b381dc
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -0,0 +1,519 @@
+/**
+ * Driver for Zarlink zl10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ **
+ * The data sheet for this tuner can be found at:
+ * http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
+ *
+ * This one is working: (at my Avermedia DVB-S Pro)
+ * - zl10036 (40pin, FTA)
+ *
+ * A driver for zl10038 should be very similar.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "zl10036.h"
+
+static int zl10036_debug;
+#define dprintk(level, args...) \
+ do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
+ } while (0)
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_i2c(args...) dprintk(0x02, args)
+
+struct zl10036_state {
+ struct i2c_adapter *i2c;
+ const struct zl10036_config *config;
+ u32 frequency;
+ u8 br, bf;
+};
+
+
+/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
+#define _XTAL 10111
+
+/* Some of the possible dividers:
+ * 64, (write 0x05 to reg), freq step size 158kHz
+ * 10, (write 0x0a to reg), freq step size 1.011kHz (used here)
+ * 5, (write 0x09 to reg), freq step size 2.022kHz
+ */
+
+#define _RDIV 10
+#define _RDIV_REG 0x0a
+#define _FR (_XTAL/_RDIV)
+
+#define STATUS_POR 0x80 /* Power on Reset */
+#define STATUS_FL 0x40 /* Frequency & Phase Lock */
+
+/* read/write for zl10036 and zl10038 */
+
+static int zl10036_read_status_reg(struct zl10036_state *state)
+{
+ u8 status;
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = I2C_M_RD,
+ .buf = &status, .len = sizeof(status) },
+ };
+
+ if (i2c_transfer(state->i2c, msg, 1) != 1) {
+ printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
+ __func__, state->config->tuner_address);
+ return -EIO;
+ }
+
+ deb_i2c("R(status): %02x [FL=%d]\n", status,
+ (status & STATUS_FL) ? 1 : 0);
+ if (status & STATUS_POR)
+ deb_info("%s: Power-On-Reset bit enabled - "
+ "need to initialize the tuner\n", __func__);
+
+ return status;
+}
+
+static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
+{
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = 0,
+ .buf = buf, .len = count },
+ };
+ u8 reg = 0;
+ int ret;
+
+ if (zl10036_debug & 0x02) {
+ /* every 8bit-value satisifes this!
+ * so only check for debug log */
+ if ((buf[0] & 0x80) == 0x00)
+ reg = 2;
+ else if ((buf[0] & 0xc0) == 0x80)
+ reg = 4;
+ else if ((buf[0] & 0xf0) == 0xc0)
+ reg = 6;
+ else if ((buf[0] & 0xf0) == 0xd0)
+ reg = 8;
+ else if ((buf[0] & 0xf0) == 0xe0)
+ reg = 10;
+ else if ((buf[0] & 0xf0) == 0xf0)
+ reg = 12;
+
+ deb_i2c("W(%d):", reg);
+ {
+ int i;
+ for (i = 0; i < count; i++)
+ printk(KERN_CONT " %02x", buf[i]);
+ printk(KERN_CONT "\n");
+ }
+ }
+
+ ret = i2c_transfer(state->i2c, msg, 1);
+ if (ret != 1) {
+ printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int zl10036_release(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(state);
+
+ return 0;
+}
+
+static int zl10036_sleep(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
+ int ret;
+
+ deb_info("%s\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_write(state, buf, sizeof(buf));
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+/**
+ * register map of the ZL10036/ZL10038
+ *
+ * reg[default] content
+ * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8
+ * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0
+ * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
+ * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0
+ * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0
+ * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0
+ * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1
+ * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0
+ * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0
+ * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
+ * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0
+ * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL
+ */
+
+static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
+{
+ u8 buf[2];
+ u32 div, foffset;
+
+ div = (frequency + _FR/2) / _FR;
+ state->frequency = div * _FR;
+
+ foffset = frequency - state->frequency;
+
+ buf[0] = (div >> 8) & 0x7f;
+ buf[1] = (div >> 0) & 0xff;
+
+ deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
+ frequency, state->frequency, foffset, div);
+
+ return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
+{
+ /* fbw is measured in kHz */
+ u8 br, bf;
+ int ret;
+ u8 buf_bf[] = {
+ 0xc0, 0x00, /* 6/7: rsd=0 bf=0 */
+ };
+ u8 buf_br[] = {
+ 0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
+ };
+ u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
+
+ /* ensure correct values */
+ if (fbw > 35000)
+ fbw = 35000;
+ if (fbw < 8000)
+ fbw = 8000;
+
+#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
+
+ /* <= 28,82 MHz */
+ if (fbw <= 28820) {
+ br = _BR_MAXIMUM;
+ } else {
+ /**
+ * f(bw)=34,6MHz f(xtal)=10.111MHz
+ * br = (10111/34600) * 63 * 1/K = 14;
+ */
+ br = ((_XTAL * 21 * 1000) / (fbw * 419));
+ }
+
+ /* ensure correct values */
+ if (br < 4)
+ br = 4;
+ if (br > _BR_MAXIMUM)
+ br = _BR_MAXIMUM;
+
+ /*
+ * k = 1.257
+ * bf = fbw/_XTAL * br * k - 1 */
+
+ bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
+
+ /* ensure correct values */
+ if (bf > 62)
+ bf = 62;
+
+ buf_bf[1] = (bf << 1) & 0x7e;
+ buf_br[1] = (br << 2) & 0x7c;
+ deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
+
+ if (br != state->br) {
+ ret = zl10036_write(state, buf_br, sizeof(buf_br));
+ if (ret < 0)
+ return ret;
+ }
+
+ if (bf != state->bf) {
+ ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
+ if (ret < 0)
+ return ret;
+
+ /* time = br/(32* fxtal) */
+ /* minimal sleep time to be calculated
+ * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
+ msleep(1);
+
+ ret = zl10036_write(state, zl10036_rsd_off,
+ sizeof(zl10036_rsd_off));
+ if (ret < 0)
+ return ret;
+ }
+
+ state->br = br;
+ state->bf = bf;
+
+ return 0;
+}
+
+static int zl10036_set_gain_params(struct zl10036_state *state,
+ int c)
+{
+ u8 buf[2];
+ u8 rfg, ba, bg;
+
+ /* default values */
+ rfg = 0; /* enable when using an lna */
+ ba = 1;
+ bg = 1;
+
+ /* reg 4 */
+ buf[0] = 0x80 | ((rfg << 5) & 0x20)
+ | ((ba << 3) & 0x18) | ((bg << 1) & 0x06);
+
+ if (!state->config->rf_loop_enable)
+ buf[0] |= 0x01;
+
+ /* P0=0 */
+ buf[1] = _RDIV_REG | ((c << 5) & 0x60);
+
+ deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
+ return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ int ret = 0;
+ u32 frequency = params->frequency;
+ u32 fbw;
+ int i;
+ u8 c;
+
+ /* ensure correct values
+ * maybe redundant as core already checks this */
+ if ((frequency < fe->ops.info.frequency_min)
+ || (frequency > fe->ops.info.frequency_max))
+ return -EINVAL;
+
+ /**
+ * alpha = 1.35 for dvb-s
+ * fBW = (alpha*symbolrate)/(2*0.8)
+ * 1.35 / (2*0.8) = 27 / 32
+ */
+ fbw = (27 * params->u.qpsk.symbol_rate) / 32;
+
+ /* scale to kHz */
+ fbw /= 1000;
+
+ /* Add safe margin of 3MHz */
+ fbw += 3000;
+
+ /* setting the charge pump - guessed values */
+ if (frequency < 950000)
+ return -EINVAL;
+ else if (frequency < 1250000)
+ c = 0;
+ else if (frequency < 1750000)
+ c = 1;
+ else if (frequency < 2175000)
+ c = 2;
+ else
+ return -EINVAL;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_set_gain_params(state, c);
+ if (ret < 0)
+ goto error;
+
+ ret = zl10036_set_frequency(state, params->frequency);
+ if (ret < 0)
+ goto error;
+
+ ret = zl10036_set_bandwidth(state, fbw);
+ if (ret < 0)
+ goto error;
+
+ /* wait for tuner lock - no idea if this is really needed */
+ for (i = 0; i < 20; i++) {
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0)
+ goto error;
+
+ /* check Frequency & Phase Lock Bit */
+ if (ret & STATUS_FL)
+ break;
+
+ msleep(10);
+ }
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+
+ *frequency = state->frequency;
+
+ return 0;
+}
+
+static int zl10036_init_regs(struct zl10036_state *state)
+{
+ int ret;
+ int i;
+
+ /* could also be one block from reg 2 to 13 and additional 10/11 */
+ u8 zl10036_init_tab[][2] = {
+ { 0x04, 0x00 }, /* 2/3: div=0x400 - arbitrary value */
+ { 0x8b, _RDIV_REG }, /* 4/5: rfg=0 ba=1 bg=1 len=? */
+ /* p0=0 c=0 r=_RDIV_REG */
+ { 0xc0, 0x20 }, /* 6/7: rsd=0 bf=0x10 */
+ { 0xd3, 0x40 }, /* 8/9: from datasheet */
+ { 0xe3, 0x5b }, /* 10/11: lock window level */
+ { 0xf0, 0x28 }, /* 12/13: br=0xa clr=0 tl=0*/
+ { 0xe3, 0xf9 }, /* 10/11: unlock window level */
+ };
+
+ /* invalid values to trigger writing */
+ state->br = 0xff;
+ state->bf = 0xff;
+
+ if (!state->config->rf_loop_enable)
+ zl10036_init_tab[1][2] |= 0x01;
+
+ deb_info("%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
+ ret = zl10036_write(state, zl10036_init_tab[i], 2);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int zl10036_init(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ int ret = 0;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0)
+ return ret;
+
+ /* Only init if Power-on-Reset bit is set? */
+ ret = zl10036_init_regs(state);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+static struct dvb_tuner_ops zl10036_tuner_ops = {
+ .info = {
+ .name = "Zarlink ZL10036",
+ .frequency_min = 950000,
+ .frequency_max = 2175000
+ },
+ .init = zl10036_init,
+ .release = zl10036_release,
+ .sleep = zl10036_sleep,
+ .set_params = zl10036_set_params,
+ .get_frequency = zl10036_get_frequency,
+};
+
+struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct zl10036_state *state = NULL;
+ int ret;
+
+ if (NULL == config) {
+ printk(KERN_ERR "%s: no config specified", __func__);
+ goto error;
+ }
+
+ state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
+ if (NULL == state)
+ return NULL;
+
+ state->config = config;
+ state->i2c = i2c;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: No zl10036 found\n", __func__);
+ goto error;
+ }
+
+ ret = zl10036_init_regs(state);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: tuner initialization failed\n",
+ __func__);
+ goto error;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ fe->tuner_priv = state;
+
+ memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
+ __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+ return fe;
+
+error:
+ zl10036_release(fe);
+ return NULL;
+}
+EXPORT_SYMBOL(zl10036_attach);
+
+module_param_named(debug, zl10036_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB ZL10036 driver");
+MODULE_AUTHOR("Tino Reichardt");
+MODULE_AUTHOR("Matthias Schwarzott");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb/frontends/zl10036.h
new file mode 100644
index 00000000000..d84b8f8215e
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.h
@@ -0,0 +1,53 @@
+/**
+ * Driver for Zarlink ZL10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef DVB_ZL10036_H
+#define DVB_ZL10036_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a zl10036 tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config zl10036_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct zl10036_config {
+ u8 tuner_address;
+ int rf_loop_enable;
+};
+
+#if defined(CONFIG_DVB_ZL10036) || \
+ (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
+extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* DVB_ZL10036_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index b150ed30669..148b6f7f6cb 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -572,6 +572,10 @@ static int zl10353_init(struct dvb_frontend *fe)
zl10353_dump_regs(fe);
if (state->config.parallel_ts)
zl10353_reset_attach[2] &= ~0x20;
+ if (state->config.clock_ctl_1)
+ zl10353_reset_attach[3] = state->config.clock_ctl_1;
+ if (state->config.pll_0)
+ zl10353_reset_attach[4] = state->config.pll_0;
/* Do a "hard" reset if not already done */
if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
@@ -614,6 +618,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
struct i2c_adapter *i2c)
{
struct zl10353_state *state = NULL;
+ int id;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
@@ -625,7 +630,8 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
memcpy(&state->config, config, sizeof(struct zl10353_config));
/* check if the demod is there */
- if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
+ id = zl10353_read_register(state, CHIP_ID);
+ if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
goto error;
/* create dvb_frontend */
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 2287bac4624..6e3ca9eed04 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -41,6 +41,10 @@ struct zl10353_config
/* set if i2c_gate_ctrl disable is required */
u8 disable_i2c_gate_ctrl:1;
+
+ /* clock control registers (0x51-0x54) */
+ u8 clock_ctl_1; /* default: 0x46 */
+ u8 pll_0; /* default: 0x15 */
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
index 055ff1f7e34..e0dd1d3e09d 100644
--- a/drivers/media/dvb/frontends/zl10353_priv.h
+++ b/drivers/media/dvb/frontends/zl10353_priv.h
@@ -22,7 +22,9 @@
#ifndef _ZL10353_PRIV_
#define _ZL10353_PRIV_
-#define ID_ZL10353 0x14
+#define ID_ZL10353 0x14 /* Zarlink ZL10353 */
+#define ID_CE6230 0x18 /* Intel CE6230 */
+#define ID_CE6231 0x19 /* Intel CE6231 */
#define msb(x) (((x) >> 8) & 0xff)
#define lsb(x) ((x) & 0xff)
@@ -50,6 +52,10 @@ enum zl10353_reg_addr {
TPS_RECEIVED_0 = 0x1E,
TPS_CURRENT_1 = 0x1F,
TPS_CURRENT_0 = 0x20,
+ CLOCK_CTL_0 = 0x51,
+ CLOCK_CTL_1 = 0x52,
+ PLL_0 = 0x53,
+ PLL_1 = 0x54,
RESET = 0x55,
AGC_TARGET = 0x56,
MCLK_RATIO = 0x5C,
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index d101b304e9b..ee89623be85 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -116,6 +116,7 @@ struct pluto {
/* irq */
unsigned int overflow;
+ unsigned int dead;
/* dma */
dma_addr_t dma_addr;
@@ -336,8 +337,10 @@ static irqreturn_t pluto_irq(int irq, void *dev_id)
return IRQ_NONE;
if (tscr == 0xffffffff) {
- // FIXME: maybe recover somehow
- dev_err(&pluto->pdev->dev, "card hung up :(\n");
+ if (pluto->dead == 0)
+ dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
+ /* It's dead Jim */
+ pluto->dead = 1;
return IRQ_HANDLED;
}
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
index ee0737af98c..bcf93f4828b 100644
--- a/drivers/media/dvb/siano/Makefile
+++ b/drivers/media/dvb/siano/Makefile
@@ -1,6 +1,8 @@
-sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o
+sms1xxx-objs := smscoreapi.o sms-cards.o
obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 4307e4e8aa3..63e4d0ec658 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -19,50 +19,9 @@
#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 int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = {
@@ -115,6 +74,7 @@ static struct sms_board sms_boards[] = {
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.lna_ctrl = 29,
+ .rf_switch = 17,
},
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
.name = "Hauppauge WinTV MiniCard",
@@ -130,6 +90,7 @@ struct sms_board *sms_get_board(int id)
return &sms_boards[id];
}
+EXPORT_SYMBOL_GPL(sms_get_board);
static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
{
@@ -182,6 +143,7 @@ int sms_board_setup(struct smscore_device_t *coredev)
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_setup);
int sms_board_power(struct smscore_device_t *coredev, int onoff)
{
@@ -197,12 +159,13 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff)
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
/* LNA */
- sms_set_gpio(coredev,
- board->lna_ctrl, onoff ? 1 : 0);
+ if (!onoff)
+ sms_set_gpio(coredev, board->lna_ctrl, 0);
break;
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_power);
int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
{
@@ -225,3 +188,40 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_led_feedback);
+
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
+{
+ int board_id = smscore_get_board_id(coredev);
+ struct sms_board *board = sms_get_board(board_id);
+
+ sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+
+ switch (board_id) {
+ case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+ case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+ sms_set_gpio(coredev,
+ board->rf_switch, onoff ? 1 : 0);
+ return sms_set_gpio(coredev,
+ board->lna_ctrl, onoff ? 1 : 0);
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(sms_board_lna_control);
+
+int sms_board_load_modules(int id)
+{
+ switch (id) {
+ case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
+ case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
+ case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
+ case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+ request_module("smsdvb");
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 8e0fe9fd261..64d74c59c33 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -40,7 +40,7 @@ struct sms_board {
char *name, *fw[DEVICE_MODE_MAX];
/* gpios */
- int led_power, led_hi, led_lo, lna_ctrl;
+ int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
};
struct sms_board *sms_get_board(int id);
@@ -52,7 +52,8 @@ int sms_board_setup(struct smscore_device_t *coredev);
#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);
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
-extern struct usb_device_id smsusb_id_table[];
+extern int sms_board_load_modules(int id);
#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index cf613f22fb8..7bd4d1dee2b 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -3,7 +3,7 @@
*
* This file contains implementation for the interface to sms core component
*
- * author: Anatoly Greenblat
+ * author: Uri Shkolnik
*
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
*
@@ -34,8 +34,8 @@
#include "smscoreapi.h"
#include "sms-cards.h"
-int sms_debug;
-module_param_named(debug, sms_debug, int, 0644);
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
struct smscore_device_notifyee_t {
@@ -105,11 +105,13 @@ int smscore_led_state(struct smscore_device_t *core, int led)
core->led_state = led;
return core->led_state;
}
+EXPORT_SYMBOL_GPL(smscore_set_board_id);
int smscore_get_board_id(struct smscore_device_t *core)
{
return core->board_id;
}
+EXPORT_SYMBOL_GPL(smscore_get_board_id);
struct smscore_registry_entry_t {
struct list_head entry;
@@ -170,6 +172,7 @@ int smscore_registry_getmode(char *devpath)
return default_mode;
}
+EXPORT_SYMBOL_GPL(smscore_registry_getmode);
static enum sms_device_type_st smscore_registry_gettype(char *devpath)
{
@@ -261,6 +264,7 @@ int smscore_register_hotplug(hotplug_t hotplug)
return rc;
}
+EXPORT_SYMBOL_GPL(smscore_register_hotplug);
/**
* unregister a client callback that called when device plugged in/unplugged
@@ -289,6 +293,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug)
kmutex_unlock(&g_smscore_deviceslock);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
static void smscore_notify_clients(struct smscore_device_t *coredev)
{
@@ -432,6 +437,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
return 0;
}
+EXPORT_SYMBOL_GPL(smscore_register_device);
/**
* sets initial device mode and notifies client hotplugs that device is ready
@@ -460,6 +466,7 @@ int smscore_start_device(struct smscore_device_t *coredev)
return rc;
}
+EXPORT_SYMBOL_GPL(smscore_start_device);
static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
void *buffer, size_t size,
@@ -688,6 +695,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
sms_info("device %p destroyed", coredev);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_device);
static int smscore_detect_mode(struct smscore_device_t *coredev)
{
@@ -732,7 +740,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
/*DVBH*/
{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
/*TDMB*/
- {"none", "tdmb_nova_12mhz.inp", "none", "none"},
+ {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
/*DABIP*/
{"none", "none", "none", "none"},
/*BDA*/
@@ -879,6 +887,7 @@ int smscore_get_device_mode(struct smscore_device_t *coredev)
{
return coredev->mode;
}
+EXPORT_SYMBOL_GPL(smscore_get_device_mode);
/**
* find client by response id & type within the clients list.
@@ -1006,6 +1015,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
smscore_putbuffer(coredev, cb);
}
}
+EXPORT_SYMBOL_GPL(smscore_onresponse);
/**
* return pointer to next free buffer descriptor from core pool
@@ -1031,6 +1041,7 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
return cb;
}
+EXPORT_SYMBOL_GPL(smscore_getbuffer);
/**
* return buffer descriptor to a pool
@@ -1045,6 +1056,7 @@ void smscore_putbuffer(struct smscore_device_t *coredev,
{
list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
}
+EXPORT_SYMBOL_GPL(smscore_putbuffer);
static int smscore_validate_client(struct smscore_device_t *coredev,
struct smscore_client_t *client,
@@ -1124,6 +1136,7 @@ int smscore_register_client(struct smscore_device_t *coredev,
return 0;
}
+EXPORT_SYMBOL_GPL(smscore_register_client);
/**
* frees smsclient object and all subclients associated with it
@@ -1154,6 +1167,7 @@ void smscore_unregister_client(struct smscore_client_t *client)
spin_unlock_irqrestore(&coredev->clientslock, flags);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_client);
/**
* verifies that source id is not taken by another client,
@@ -1193,6 +1207,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
return coredev->sendrequest_handler(coredev->context, buffer, size);
}
+EXPORT_SYMBOL_GPL(smsclient_sendrequest);
int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
@@ -1276,12 +1291,12 @@ static int __init smscore_module_init(void)
INIT_LIST_HEAD(&g_smscore_registry);
kmutex_init(&g_smscore_registrylock);
- /* USB Register */
- rc = smsusb_register();
- /* DVB Register */
- rc = smsdvb_register();
+
+
+
+ return rc;
sms_debug("rc %d", rc);
return rc;
@@ -1290,6 +1305,10 @@ static int __init smscore_module_init(void)
static void __exit smscore_module_exit(void)
{
+
+
+
+
kmutex_lock(&g_smscore_deviceslock);
while (!list_empty(&g_smscore_notifyees)) {
struct smscore_device_notifyee_t *notifyee =
@@ -1312,18 +1331,12 @@ static void __exit smscore_module_exit(void)
}
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_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index 760e233fcbc..548de9056e8 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -29,13 +29,13 @@
#include <linux/scatterlist.h>
#include <linux/types.h>
#include <asm/page.h>
+#include <linux/mutex.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_)
@@ -369,27 +369,6 @@ struct smscore_gpio_config {
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);
@@ -418,6 +397,13 @@ extern int smsclient_sendrequest(struct smscore_client_t *client,
extern void smscore_onresponse(struct smscore_device_t *coredev,
struct smscore_buffer_t *cb);
+extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
+extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
+ struct vm_area_struct *vma);
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
+ int mode, char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev,
+ u8 *ufwbuf, int size);
extern
struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
@@ -433,18 +419,9 @@ 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
@@ -452,7 +429,7 @@ extern int sms_debug;
printk(kern "%s: " fmt "\n", __func__, ##arg)
#define dprintk(kern, lvl, fmt, arg...) do {\
- if (sms_debug & lvl) \
+ if (sms_dbg & lvl) \
sms_printk(kern, fmt, ##arg); } while (0)
#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 2da953a4f4f..ba080b95bef 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -1,7 +1,7 @@
/*
* Driver for the Siano SMS1xxx USB dongle
*
- * author: Anatoly Greenblat
+ * Author: Uri Shkolni
*
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
*
@@ -27,9 +27,33 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+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;
+};
+
static struct list_head g_smsdvb_clients;
static struct mutex g_smsdvb_clientslock;
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -262,6 +286,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
struct SmsMsgHdr_ST Msg;
u32 Data[3];
} Msg;
+ int ret;
Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
Msg.Msg.msgDstId = HIF_TASK;
@@ -282,6 +307,24 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
default: return -EINVAL;
}
+ /* Disable LNA, if any. An error is returned if no LNA is present */
+ ret = sms_board_lna_control(client->coredev, 0);
+ if (ret == 0) {
+ fe_status_t status;
+
+ /* tune with LNA off at first */
+ ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+ &client->tune_done);
+
+ smsdvb_read_status(fe, &status);
+
+ if (status & FE_HAS_LOCK)
+ return ret;
+
+ /* previous tune didnt lock - enable LNA and tune again */
+ sms_board_lna_control(client->coredev, 1);
+ }
+
return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
&client->tune_done);
}
@@ -329,7 +372,7 @@ static void smsdvb_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops smsdvb_fe_ops = {
.info = {
- .name = "Siano Mobile Digital SMS1xxx",
+ .name = "Siano Mobile Digital MDTV Receiver",
.type = FE_OFDM,
.frequency_min = 44250000,
.frequency_max = 867250000,
@@ -371,7 +414,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
if (!arrival)
return 0;
- if (smscore_get_device_mode(coredev) != 4) {
+ if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) {
sms_err("SMS Device mode is not set for "
"DVB operation.");
return 0;
@@ -473,7 +516,7 @@ adapter_error:
return rc;
}
-int smsdvb_register(void)
+int smsdvb_module_init(void)
{
int rc;
@@ -487,7 +530,7 @@ int smsdvb_register(void)
return rc;
}
-void smsdvb_unregister(void)
+void smsdvb_module_exit(void)
{
smscore_unregister_hotplug(smsdvb_hotplug);
@@ -499,3 +542,10 @@ void smsdvb_unregister(void)
kmutex_unlock(&g_smsdvb_clientslock);
}
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 5d7ca341771..71c65f544c0 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -27,6 +27,10 @@
#include "smscoreapi.h"
#include "sms-cards.h"
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
#define USB1_BUFFER_SIZE 0x1000
#define USB2_BUFFER_SIZE 0x4000
@@ -424,6 +428,7 @@ static int smsusb_probe(struct usb_interface *intf,
rc = smsusb_init_device(intf, id->driver_info);
sms_info("rc %d", rc);
+ sms_board_load_modules(id->driver_info);
return rc;
}
@@ -436,7 +441,7 @@ 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);
+ printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
smsusb_stop_streaming(dev);
return 0;
}
@@ -448,7 +453,7 @@ static int smsusb_resume(struct usb_interface *intf)
(struct smsusb_device_t *)usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
- printk(KERN_INFO "%s Entering.\n", __func__);
+ printk(KERN_INFO "%s: Entering.\n", __func__);
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
@@ -463,9 +468,8 @@ static int smsusb_resume(struct usb_interface *intf)
intf->cur_altsetting->desc.
bInterfaceNumber, 0);
if (rc < 0) {
- printk(KERN_INFO
- "%s usb_set_interface failed, rc %d\n",
- __func__, rc);
+ printk(KERN_INFO "%s usb_set_interface failed, "
+ "rc %d\n", __func__, rc);
return rc;
}
}
@@ -474,8 +478,55 @@ static int smsusb_resume(struct usb_interface *intf)
return 0;
}
+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, 0x2011),
+ .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 usb_driver smsusb_driver = {
- .name = "sms1xxx",
+ .name = "smsusb",
.probe = smsusb_probe,
.disconnect = smsusb_disconnect,
.id_table = smsusb_id_table,
@@ -484,7 +535,7 @@ static struct usb_driver smsusb_driver = {
.resume = smsusb_resume,
};
-int smsusb_register(void)
+int smsusb_module_init(void)
{
int rc = usb_register(&smsusb_driver);
if (rc)
@@ -495,10 +546,16 @@ int smsusb_register(void)
return rc;
}
-void smsusb_unregister(void)
+void smsusb_module_exit(void)
{
sms_debug("");
/* Regular USB Cleanup */
usb_deregister(&smsusb_driver);
}
+module_init(smsusb_module_init);
+module_exit(smsusb_module_exit);
+
+MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index ab0bcd208c7..772990415f9 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -108,7 +108,7 @@ config DVB_BUDGET_CI
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 MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
select VIDEO_IR
help
Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index aa1ff524256..4624cee93e7 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -725,7 +725,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file,
}
-static struct file_operations dvb_osd_fops = {
+static const struct file_operations dvb_osd_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index bdc62acf209..e4d0900d512 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file)
* driver registration
******************************************************************************/
-static struct file_operations dvb_video_fops = {
+static const struct file_operations dvb_video_fops = {
.owner = THIS_MODULE,
.write = dvb_video_write,
.ioctl = dvb_generic_ioctl,
@@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video = {
.kernel_ioctl = dvb_video_ioctl,
};
-static struct file_operations dvb_audio_fops = {
+static const struct file_operations dvb_audio_fops = {
.owner = THIS_MODULE,
.write = dvb_audio_write,
.ioctl = dvb_generic_ioctl,
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 261135ded48..c7a65b1544a 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf,
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
}
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_read,
.write = dvb_ca_write,
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index c5b9c70563d..2210cff738e 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -316,253 +316,261 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
return 0;
}
-static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
{
- struct saa7146_dev *dev = fh->dev;
- struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
- dprintk(4, "saa7146_dev: %p\n", dev);
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 stereo_det;
+ s8 stereo;
- 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);
- dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
+ if (!av7110->analog_tuner_flags || t->index != 0)
+ return -EINVAL;
- 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;
- 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;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 fm_matrix, src;
- dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 fm_matrix, src;
+ dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ 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;
+ 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;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ 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;
+}
- dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
- 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;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = av7110->current_freq;
+ return 0;
+}
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+ dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- /* 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;
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- 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;
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
- dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+ /* 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;
- if (av7110->analog_tuner_flags) {
- if (i->index < 0 || i->index >= 4)
- return -EINVAL;
- } else {
- if (i->index != 0)
- return -EINVAL;
- }
+ 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;
+}
- memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- return 0;
+ 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;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = av7110->current_input;
- dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+
+ memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ *input = av7110->current_input;
+ dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+
+ if (!av7110->analog_tuner_flags)
return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+ if (input < 0 || input >= 4)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags)
- return 0;
+ av7110->current_input = input;
+ return av7110_dvb_c_switch(fh);
+}
- if (input < 0 || input >= 4)
- return -EINVAL;
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+ if (a->index != 0)
+ return -EINVAL;
+ memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
+ return 0;
+}
- av7110->current_input = input;
- return av7110_dvb_c_switch(fh);
- }
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
+ return 0;
+}
- 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;
+static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_sliced_vbi_cap *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+ return -EINVAL;
+ if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+ cap->service_set = V4L2_SLICED_WSS_625;
+ cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
}
- 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;
+ return 0;
+}
+
+static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_FMT:\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ 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);
}
- default:
- printk("no such ioctl\n");
- return -ENOIOCTLCMD;
+ return 0;
+}
+
+static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_FMT\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ 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;
}
return 0;
}
@@ -609,22 +617,6 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size
* 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,
@@ -788,20 +780,34 @@ int av7110_init_analog_module(struct av7110 *av7110)
int av7110_init_v4l(struct av7110 *av7110)
{
struct saa7146_dev* dev = av7110->dev;
+ struct saa7146_ext_vv *vv_data;
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);
+ vv_data = &av7110_vv_data_c;
else
- ret = saa7146_vv_init(dev, &av7110_vv_data_st);
+ vv_data = &av7110_vv_data_st;
+ ret = saa7146_vv_init(dev, vv_data);
if (ret) {
ERR(("cannot init capture device. skipping.\n"));
return -ENODEV;
}
+ vv_data->ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data->ops.vidioc_g_input = vidioc_g_input;
+ vv_data->ops.vidioc_s_input = vidioc_s_input;
+ vv_data->ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data->ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data->ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data->ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data->ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data->ops.vidioc_s_audio = vidioc_s_audio;
+ vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
+ vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
+ vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture device. skipping.\n"));
@@ -900,9 +906,6 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
.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,
@@ -918,9 +921,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
.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
index 4182121d7e5..855fe74b640 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1404,6 +1404,41 @@ static int budget_av_detach(struct saa7146_dev *dev)
return err;
}
+#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 int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ 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;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ *i = budget_av->cur_input;
+
+ dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
+ return saa7113_setinput(budget_av, input);
+}
+
static struct saa7146_ext_vv vv_data;
static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
@@ -1442,6 +1477,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
ERR(("cannot init vv subsystem.\n"));
return err;
}
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
/* fixme: proper cleanup here */
@@ -1480,54 +1518,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
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,
@@ -1546,8 +1536,6 @@ static struct saa7146_ext_vv vv_data = {
.flags = 0,
.stds = &standard[0],
.num_stds = ARRAY_SIZE(standard),
- .ioctls = &ioctls[0],
- .ioctl = av_ioctl,
};
static struct saa7146_extension budget_extension;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index bcbc5d41a0f..371a7161681 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -1076,6 +1076,10 @@ static struct tda10023_config tda10023_config = {
.deltaf = 0xa511,
};
+static struct tda827x_config tda827x_config = {
+ .config = 0,
+};
+
/* TT S2-3200 DVB-S (STB0899) Inittab */
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
@@ -1414,7 +1418,7 @@ static void frontend_init(struct budget_ci *budget_ci)
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) {
+ if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
printk(KERN_ERR "%s: No tda827x found!\n", __func__);
dvb_frontend_detach(budget_ci->budget.dvb_frontend);
budget_ci->budget.dvb_frontend = NULL;