aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/dvb/b2c2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/b2c2')
-rw-r--r--drivers/media/dvb/b2c2/Kconfig15
-rw-r--r--drivers/media/dvb/b2c2/Makefile2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c165
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c26
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c12
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c23
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c122
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h551
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c2
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c34
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h1
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_be.h458
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_le.h458
-rw-r--r--drivers/media/dvb/b2c2/skystar2.c2644
15 files changed, 1209 insertions, 3310 deletions
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index 99bd675df95..d7417eac2ab 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -6,6 +6,7 @@ config DVB_B2C2_FLEXCOP
select DVB_MT312
select DVB_NXT2002
select DVB_STV0297
+ select DVB_BCM3510
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
Technisats PCI cards and USB boxes.
@@ -34,17 +35,3 @@ config DVB_B2C2_FLEXCOP_DEBUG
help
Say Y if you want to enable the module option to control debug messages
of all B2C2 FlexCop drivers.
-
-config DVB_B2C2_SKYSTAR
- tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI"
- depends on DVB_CORE && PCI
- select DVB_STV0299
- select DVB_MT352
- select DVB_MT312
- select DVB_NXT2002
- help
- Support for the Skystar2 PCI DVB card by Technisat, which
- is equipped with the FlexCopII chipset by B2C2, and
- for the B2C2/BBTI Air2PC-ATSC card.
-
- Say Y if you own such a device and want to use it.
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index 7703812af34..1a1c3bca55f 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -9,6 +9,4 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o
b2c2-flexcop-usb-objs = flexcop-usb.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o
-obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o
-
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 773d158032d..a94912ac187 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -108,6 +108,8 @@ void flexcop_device_kfree(struct flexcop_device*);
int flexcop_device_initialize(struct flexcop_device*);
void flexcop_device_exit(struct flexcop_device *fc);
+void flexcop_reset_block_300(struct flexcop_device *fc);
+
/* from flexcop-dma.c */
int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
void flexcop_dma_free(struct flexcop_dma *dma);
@@ -115,7 +117,8 @@ 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_control_packet_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,flexcop_dma_addr_index_t index);
+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_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets);
@@ -151,6 +154,7 @@ int flexcop_sram_init(struct flexcop_device *fc);
/* from flexcop-misc.c */
void flexcop_determine_revision(struct flexcop_device *fc);
void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
/* from flexcop-hw-filter.c */
int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index 8d270607536..cf4ed1df608 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -37,22 +37,90 @@ void flexcop_dma_free(struct flexcop_dma *dma)
}
EXPORT_SYMBOL(flexcop_dma_free);
-int flexcop_dma_control_timer_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)
{
- flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
+ flexcop_ibi_value v0x0,v0x4,v0xc;
+ v0x0.raw = v0x4.raw = v0xc.raw = 0;
- if (no & FC_DMA_1)
- v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
+ 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 (no & FC_DMA_2)
- v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
+ if ((dma_idx & FC_DMA_1) == dma_idx) {
+ fc->write_ibi_reg(fc,dma1_000,v0x0);
+ fc->write_ibi_reg(fc,dma1_004,v0x4);
+ fc->write_ibi_reg(fc,dma1_00c,v0xc);
+ } else if ((dma_idx & FC_DMA_2) == dma_idx) {
+ fc->write_ibi_reg(fc,dma2_010,v0x0);
+ fc->write_ibi_reg(fc,dma2_014,v0x4);
+ fc->write_ibi_reg(fc,dma2_01c,v0xc);
+ } else {
+ err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+ return -EINVAL;
+ }
- fc->write_ibi_reg(fc,ctrl_208,v);
return 0;
}
-EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
+EXPORT_SYMBOL(flexcop_dma_config);
+
+/* start the DMA transfers, but not the DMA IRQs */
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ flexcop_dma_addr_index_t index,
+ int onoff)
+{
+ flexcop_ibi_value v0x0,v0xc;
+ flexcop_ibi_register r0x0,r0xc;
+
+ if ((dma_idx & FC_DMA_1) == dma_idx) {
+ r0x0 = dma1_000;
+ r0xc = dma1_00c;
+ } else if ((dma_idx & FC_DMA_2) == dma_idx) {
+ r0x0 = dma2_010;
+ r0xc = dma2_01c;
+ } else {
+ err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+ return -EINVAL;
+ }
+
+ v0x0 = fc->read_ibi_reg(fc,r0x0);
+ v0xc = fc->read_ibi_reg(fc,r0xc);
+
+ deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+ deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+
+ if (index & FC_DMA_SUBADDR_0)
+ v0x0.dma_0x0.dma_0start = onoff;
+
+ if (index & FC_DMA_SUBADDR_1)
+ v0xc.dma_0xc.dma_1start = onoff;
+
+ fc->write_ibi_reg(fc,r0x0,v0x0);
+ fc->write_ibi_reg(fc,r0xc,v0xc);
+
+ deb_rdump("reg: %03x: %x\n",r0x0,v0x0.raw);
+ deb_rdump("reg: %03x: %x\n",r0xc,v0xc.raw);
+ return 0;
+}
+EXPORT_SYMBOL(flexcop_dma_xfer_control);
+
+static int flexcop_dma_remap(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ int onoff)
+{
+ flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+ deb_info("%s\n",__FUNCTION__);
+ v.dma_0xc.remap_enable = onoff;
+ fc->write_ibi_reg(fc,r,v);
+ return 0;
+}
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no,
+ int onoff)
{
flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
@@ -67,75 +135,64 @@ int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t
}
EXPORT_SYMBOL(flexcop_dma_control_size_irq);
-int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff)
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no,
+ int onoff)
{
flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
if (no & FC_DMA_1)
- v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+ v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
if (no & FC_DMA_2)
- v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+ v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
fc->write_ibi_reg(fc,ctrl_208,v);
return 0;
}
-EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
+EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index)
+/* 1 cycles = 1.97 msec */
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ u8 cycles)
{
+ flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
- flexcop_ibi_value v0x0,v0x4,v0xc;
- v0x0.raw = v0x4.raw = v0xc.raw = 0;
-
- v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
- v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
- v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
-
- if (index & FC_DMA_SUBADDR_0)
- v0x0.dma_0x0.dma_0start = 1;
-
- if (index & FC_DMA_SUBADDR_1)
- v0xc.dma_0xc.dma_1start = 1;
-
- if (dma_idx & FC_DMA_1) {
- fc->write_ibi_reg(fc,dma1_000,v0x0);
- fc->write_ibi_reg(fc,dma1_004,v0x4);
- fc->write_ibi_reg(fc,dma1_00c,v0xc);
- } else { /* (dma_idx & FC_DMA_2) */
- fc->write_ibi_reg(fc,dma2_010,v0x0);
- fc->write_ibi_reg(fc,dma2_014,v0x4);
- fc->write_ibi_reg(fc,dma2_01c,v0xc);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(flexcop_dma_config);
+ flexcop_dma_remap(fc,dma_idx,0);
-static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff)
-{
- flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
- v.dma_0xc.remap_enable = onoff;
+ deb_info("%s\n",__FUNCTION__);
+ v.dma_0x4_write.dmatimer = cycles;
fc->write_ibi_reg(fc,r,v);
return 0;
}
+EXPORT_SYMBOL(flexcop_dma_config_timer);
-/* 1 cycles = 1.97 msec */
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles)
+/* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */
+int flexcop_dma_control_packet_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no,
+ int onoff)
{
- flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208);
- flexcop_dma_remap(fc,dma_idx,0);
+ deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
+ if (no & FC_DMA_1)
+ v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff;
+
+ if (no & FC_DMA_2)
+ v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff;
+
+ fc->write_ibi_reg(fc,ctrl_208,v);
+ deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw);
- v.dma_0x4_write.dmatimer = cycles >> 1;
- fc->write_ibi_reg(fc,r,v);
return 0;
}
-EXPORT_SYMBOL(flexcop_dma_config_timer);
+EXPORT_SYMBOL(flexcop_dma_control_packet_irq);
-int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets)
+int flexcop_dma_config_packet_count(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx,
+ u8 packets)
{
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-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 71be400e9ae..0410cc96a48 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -10,6 +10,7 @@
#include "stv0299.h"
#include "mt352.h"
#include "nxt2002.h"
+#include "bcm3510.h"
#include "stv0297.h"
#include "mt312.h"
@@ -285,21 +286,25 @@ static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_front
}
static struct mt352_config samsung_tdtc9251dh0_config = {
-
.demod_address = 0x0f,
- .demod_init = samsung_tdtc9251dh0_demod_init,
- .pll_set = samsung_tdtc9251dh0_pll_set,
+ .demod_init = samsung_tdtc9251dh0_demod_init,
+ .pll_set = samsung_tdtc9251dh0_pll_set,
};
-static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{
struct flexcop_device *fc = fe->dvb->priv;
return request_firmware(fw, name, fc->dev);
}
static struct nxt2002_config samsung_tbmv_config = {
- .demod_address = 0x0a,
- .request_firmware = nxt2002_request_firmware,
+ .demod_address = 0x0a,
+ .request_firmware = flexcop_fe_request_firmware,
+};
+
+static struct bcm3510_config air2pc_atsc_first_gen_config = {
+ .demod_address = 0x0f,
+ .request_firmware = flexcop_fe_request_firmware,
};
static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
@@ -354,11 +359,16 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->dev_type = FC_AIR_DVB;
info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address);
} else
- /* try the air atsc (nxt2002) */
+ /* try the air atsc 2nd generation (nxt2002) */
if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) {
- fc->dev_type = FC_AIR_ATSC;
+ fc->dev_type = FC_AIR_ATSC2;
info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address);
} else
+ /* try the air atsc 1nd generation (bcm3510)/panasonic ct10s */
+ if ((fc->fe = bcm3510_attach(&air2pc_atsc_first_gen_config, &fc->i2c_adap)) != NULL) {
+ fc->dev_type = FC_AIR_ATSC1;
+ info("found the bcm3510 at i2c address: 0x%02x",air2pc_atsc_first_gen_config.demod_address);
+ } else
/* try the cable dvb (stv0297) */
if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) {
fc->dev_type = FC_CABLE;
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 2baf43d3ce8..75cf237196e 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -10,6 +10,8 @@
static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
{
flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
+
+ deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
}
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
@@ -151,7 +153,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
{
int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
- fc->feedcount += onoff ? 1 : -1;
+ fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
if (dvbdmxfeed->index >= max_pid_filter)
fc->extra_feedcount += onoff ? 1 : -1;
@@ -178,8 +180,14 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
/* if it was the first or last feed request change the stream-status */
if (fc->feedcount == onoff) {
flexcop_rcv_data_ctrl(fc,onoff);
- if (fc->stream_control)
+ if (fc->stream_control) /* device specific stream control */
fc->stream_control(fc,onoff);
+
+ /* feeding stopped -> reset the flexcop filter*/
+ if (onoff == 0) {
+ flexcop_reset_block_300(fc);
+ flexcop_hw_filter_init(fc);
+ }
}
return 0;
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 19e06da4677..3a08d38b318 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -45,11 +45,12 @@ const char *flexcop_revision_names[] = {
const char *flexcop_device_names[] = {
"Unkown device",
- "AirStar 2 DVB-T",
- "AirStar 2 ATSC",
- "SkyStar 2 DVB-S",
- "SkyStar 2 DVB-S (old version)",
- "CableStar 2 DVB-C",
+ "Air2PC/AirStar 2 DVB-T",
+ "Air2PC/AirStar 2 ATSC 1st generation",
+ "Air2PC/AirStar 2 ATSC 2nd generation",
+ "Sky2PC/SkyStar 2 DVB-S",
+ "Sky2PC/SkyStar 2 DVB-S (old version)",
+ "Cable2PC/CableStar 2 DVB-C",
};
const char *flexcop_bus_names[] = {
@@ -64,3 +65,15 @@ void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
flexcop_revision_names[fc->rev],suffix);
}
+
+void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+{
+ flexcop_ibi_value v;
+ int i;
+ for (i = 0; i < num; i++) {
+ v = fc->read_ibi_reg(fc,reg+4*i);
+ deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+ }
+ deb_rdump("\n");
+}
+EXPORT_SYMBOL(flexcop_dump_reg);
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index ed717c0073d..2f76eb3fea4 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -13,6 +13,10 @@ static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+static int irq_chk_intv;
+module_param(irq_chk_intv, int, 0644);
+MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ watchdog (currently just debugging).");
+
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
do { if ((debug & level)) printk(args); } while (0)
@@ -26,6 +30,7 @@ MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported
#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 = 0;
module_param(debug, int, 0644);
@@ -56,6 +61,10 @@ struct flexcop_pci {
spinlock_t irq_lock;
+ unsigned long last_irq;
+
+ struct work_struct irq_check_work;
+
struct flexcop_device *fc_dev;
};
@@ -88,18 +97,55 @@ static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi
return 0;
}
+static void flexcop_pci_irq_check_work(void *data)
+{
+ struct flexcop_pci *fc_pci = data;
+ struct flexcop_device *fc = fc_pci->fc_dev;
+
+ flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+
+ flexcop_dump_reg(fc_pci->fc_dev,dma1_000,4);
+
+ if (v.sram_dest_reg_714.net_ovflow_error)
+ deb_chk("sram net_ovflow_error\n");
+ if (v.sram_dest_reg_714.media_ovflow_error)
+ deb_chk("sram media_ovflow_error\n");
+ if (v.sram_dest_reg_714.cai_ovflow_error)
+ deb_chk("sram cai_ovflow_error\n");
+ if (v.sram_dest_reg_714.cai_ovflow_error)
+ deb_chk("sram cai_ovflow_error\n");
+
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
+}
+
/* When PID filtering is turned on, we use the timer IRQ, because small amounts
* of data need to be passed to the user space instantly as well. When PID
* filtering is turned off, we use the page-change-IRQ */
-static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs)
{
struct flexcop_pci *fc_pci = dev_id;
struct flexcop_device *fc = fc_pci->fc_dev;
- flexcop_ibi_value v = fc->read_ibi_reg(fc,irq_20c);
+ flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
spin_lock_irq(&fc_pci->irq_lock);
+ v = fc->read_ibi_reg(fc,irq_20c);
+
+ /* errors */
+ if (v.irq_20c.Data_receiver_error)
+ deb_chk("data receiver error\n");
+ if (v.irq_20c.Continuity_error_flag)
+ deb_chk("Contunuity error flag is set\n");
+ if (v.irq_20c.LLC_SNAP_FLAG_set)
+ deb_chk("LLC_SNAP_FLAG_set is set\n");
+ if (v.irq_20c.Transport_Error)
+ deb_chk("Transport error\n");
+
+ if ((fc_pci->count % 1000) == 0)
+ deb_chk("%d valid irq took place so far\n",fc_pci->count);
+
if (v.irq_20c.DMA1_IRQ_Status == 1) {
if (fc_pci->active_dma1_addr == 0)
flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
@@ -115,8 +161,9 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
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("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
- v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+ deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ",
+ jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos);
+ fc_pci->last_irq = jiffies;
/* buffer end was reached, restarted from the beginning
* pass the data from last_cur_pos to the buffer end to the demux
@@ -127,7 +174,6 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
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;
- fc_pci->count = 0;
}
if (cur_pos > fc_pci->last_dma1_cur_pos) {
@@ -139,16 +185,14 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs)
deb_irq("\n");
fc_pci->last_dma1_cur_pos = cur_pos;
- } else
+ fc_pci->count++;
+ } else {
+ deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
ret = IRQ_NONE;
+ }
spin_unlock_irq(&fc_pci->irq_lock);
-/* packet count would be ideal for hw filtering, but it isn't working. Either
- * the data book is wrong, or I'm unable to read it correctly */
-
-/* if (v.irq_20c.DMA1_Size_IRQ_Status == 1) { packet counter */
-
return ret;
}
@@ -156,30 +200,35 @@ 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,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
- flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1);
- flexcop_dma_config_timer(fc,FC_DMA_1,1);
+ flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
+ flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
- if (fc_pci->fc_dev->pid_filtering) {
- fc_pci->last_dma1_cur_pos = 0;
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
- } else {
- fc_pci->active_dma1_addr = 0;
- flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
- }
+ flexcop_dma_config_timer(fc,FC_DMA_1,0);
-/* flexcop_dma_config_packet_count(fc,FC_DMA_1,0xc0);
- flexcop_dma_control_packet_irq(fc,FC_DMA_1,1); */
+ flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+ deb_irq("DMA xfer enabled\n");
- deb_irq("irqs enabled\n");
+ fc_pci->last_dma1_cur_pos = 0;
+ flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+ deb_irq("IRQ enabled\n");
+
+// fc_pci->active_dma1_addr = 0;
+// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
+
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
} else {
- if (fc_pci->fc_dev->pid_filtering)
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
- else
- flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+ if (irq_chk_intv > 0)
+ cancel_delayed_work(&fc_pci->irq_check_work);
+
+ flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+ deb_irq("IRQ disabled\n");
-// flexcop_dma_control_packet_irq(fc,FC_DMA_1,0);
- deb_irq("irqs disabled\n");
+// flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
+
+ flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+ deb_irq("DMA xfer disabled\n");
}
return 0;
@@ -198,6 +247,7 @@ static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
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;
+
goto success;
dma1_free:
flexcop_dma_free(&fc_pci->dma[0]);
@@ -244,7 +294,7 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
pci_set_drvdata(fc_pci->pdev, fc_pci);
- if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_irq,
+ if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0)
goto err_pci_iounmap;
@@ -324,6 +374,8 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
goto err_fc_exit;
+ INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci);
+
goto success;
err_fc_exit:
flexcop_device_exit(fc);
@@ -350,17 +402,17 @@ 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) }, PCI FlexCopIII ? */
+/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
{ },
};
MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);
static struct pci_driver flexcop_pci_driver = {
- .name = "Technisat/B2C2 FlexCop II/IIb/III PCI",
+ .name = "b2c2_flexcop_pci",
.id_table = flexcop_pci_tbl,
- .probe = flexcop_pci_probe,
- .remove = flexcop_pci_remove,
+ .probe = flexcop_pci_probe,
+ .remove = flexcop_pci_remove,
};
static int __init flexcop_pci_module_init(void)
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 5e131be55cb..4ae1eb5bfe9 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -21,7 +21,8 @@ extern const char *flexcop_revision_names[];
typedef enum {
FC_UNK = 0,
FC_AIR_DVB,
- FC_AIR_ATSC,
+ FC_AIR_ATSC1,
+ FC_AIR_ATSC2,
FC_SKY,
FC_SKY_OLD,
FC_CABLE,
@@ -35,555 +36,21 @@ typedef enum {
extern const char *flexcop_device_names[];
/* FlexCop IBI Registers */
+#if defined(__LITTLE_ENDIAN)
+ #include "flexcop_ibi_value_le.h"
+#elif defined(__BIG_ENDIAN)
+ #include "flexcop_ibi_value_be.h"
+#else
+ #error no endian defined
+#endif
-/* flexcop_ibi_reg - a huge union representing the register structure */
-typedef union {
- u32 raw;
-
-/* DMA 0x000 to 0x01c
- * DMA1 0x000 to 0x00c
- * DMA2 0x010 to 0x01c
- */
- struct {
- u32 dma_0start : 1; /* set: data will be delivered to dma1_address0 */
- u32 dma_0No_update : 1; /* set: dma1_cur_address will be updated, unset: no update */
- u32 dma_address0 :30; /* physical/virtual host memory address0 DMA */
- } dma_0x0;
-
- struct {
- u32 DMA_maxpackets : 8; /* (remapped) PCI DMA1 Packet Count Interrupt. This variable
- is able to be read and written while bit(1) of register
- 0x00c (remap_enable) is set. This variable represents
- the number of packets that will be transmitted to the PCI
- host using PCI DMA1 before an interrupt to the PCI is
- asserted. This functionality may be enabled using bit(20)
- of register 0x208. N=0 disables the IRQ. */
- u32 dma_addr_size :24; /* size of memory buffer in DWORDs (bytesize / 4) for DMA */
- } dma_0x4_remap;
-
- struct {
- u32 dma1timer : 7; /* reading PCI DMA1 timer ... when remap_enable is 0 */
- u32 unused : 1;
- u32 dma_addr_size :24;
- } dma_0x4_read;
-
- struct {
- u32 unused : 1;
- u32 dmatimer : 7; /* writing PCI DMA1 timer ... when remap_enable is 0 */
- u32 dma_addr_size :24;
- } dma_0x4_write;
-
- struct {
- u32 unused : 2;
- u32 dma_cur_addr :30; /* current physical host memory address pointer for DMA */
- } dma_0x8;
-
- struct {
- u32 dma_1start : 1; /* set: data will be delivered to dma_address1, when dma_address0 is full */
- u32 remap_enable : 1; /* remap enable for 0x0x4(7:0) */
- u32 dma_address1 :30; /* Physical/virtual address 1 on DMA */
- } dma_0xc;
-
-/* Two-wire Serial Master and Clock 0x100-0x110 */
- struct {
-// u32 slave_transmitter : 1; /* ???*/
- u32 chipaddr : 7; /* two-line serial address of the target slave */
- u32 reserved1 : 1;
- u32 baseaddr : 8; /* address of the location of the read/write operation */
- u32 data1_reg : 8; /* first byte in two-line serial read/write operation */
- u32 working_start : 1; /* when doing a write operation this indicator is 0 when ready
- * set to 1 when doing a write operation */
- u32 twoWS_rw : 1; /* read/write indicator (1 = read, 0 write) */
- u32 total_bytes : 2; /* number of data bytes in each two-line serial transaction (0 = 1 byte, 11 = 4byte)*/
- u32 twoWS_port_reg : 2; /* port selection: 01 - Front End/Demod, 10 - EEPROM, 11 - Tuner */
- u32 no_base_addr_ack_error : 1; /* writing: write-req: frame is produced w/o baseaddr, read-req: read-cycles w/o
- * preceding address assignment write frame
- * ACK_ERROR = 1 when no ACK from slave in the last transaction */
- u32 st_done : 1; /* indicator for transaction is done */
- } tw_sm_c_100;
-
- struct {
- u32 data2_reg : 8; /* 2nd data byte */
- u32 data3_reg : 8; /* 3rd data byte */
- u32 data4_reg : 8; /* 4th data byte */
- u32 exlicit_stops : 1; /* when set, transactions are produced w/o trailing STOP flag, then send isolated STOP flags */
- u32 force_stop : 1; /* isolated stop flag */
- u32 unused : 6;
- } tw_sm_c_104;
-
-/* Clock. The register allows the FCIII to convert an incoming Master clock
- * (MCLK) signal into a lower frequency clock through the use of a LowCounter
- * (TLO) and a High- Counter (THI). The time counts for THI and TLO are
- * measured in MCLK; each count represents 4 MCLK input clock cycles.
- *
- * The default output for port #1 is set for Front End Demod communication. (0x108)
- * The default output for port #2 is set for EEPROM communication. (0x10c)
- * The default output for port #3 is set for Tuner communication. (0x110)
- */
- struct {
- u32 thi1 : 6; /* Thi for port #1 (def: 100110b; 38) */
- u32 reserved1 : 2;
- u32 tlo1 : 5; /* Tlo for port #1 (def: 11100b; 28) */
- u32 reserved2 :19;
- } tw_sm_c_108;
-
- struct {
- u32 thi1 : 6; /* Thi for port #2 (def: 111001b; 57) */
- u32 reserved1 : 2;
- u32 tlo1 : 5; /* Tlo for port #2 (def: 11100b; 28) */
- u32 reserved2 :19;
- } tw_sm_c_10c;
-
- struct {
- u32 thi1 : 6; /* Thi for port #3 (def: 111001b; 57) */
- u32 reserved1 : 2;
- u32 tlo1 : 5; /* Tlo for port #3 (def: 11100b; 28) */
- u32 reserved2 :19;
- } tw_sm_c_110;
-
-/* LNB Switch Frequency 0x200
- * Clock that creates the LNB switch tone. The default is set to have a fixed
- * low output (not oscillating) to the LNB_CTL line.
- */
- struct {
- u32 LNB_CTLHighCount_sig :15; /* It is the number of pre-scaled clock cycles that will be low. */
- u32 LNB_CTLLowCount_sig :15; /* For example, to obtain a 22KHz output given a 45 Mhz Master
- Clock signal (MCLK), set PreScalar=01 and LowCounter value to 0x1ff. */
- u32 LNB_CTLPrescaler_sig : 2; /* pre-scaler divides MCLK: 00 (no division), 01 by 2, 10 by 4, 11 by 12 */
- } lnb_switch_freq_200;
-
-/* ACPI, Peripheral Reset, LNB Polarity
- * ACPI power conservation mode, LNB polarity selection (low or high voltage),
- * and peripheral reset.
- */
- struct {
- u32 ACPI1_sig : 1; /* turn of the power of tuner and LNB, not implemented in FCIII */
- u32 ACPI3_sig : 1; /* turn of power of the complete satelite receiver board (except FCIII) */
- u32 LNB_L_H_sig : 1; /* low or high voltage for LNB. (0 = low, 1 = high) */
- u32 Per_reset_sig : 1; /* misc. init reset (default: 1), to reset set to low and back to high */
- u32 reserved :20;
- u32 Rev_N_sig_revision_hi : 4;/* 0xc in case of FCIII */
- u32 Rev_N_sig_reserved1 : 2;
- u32 Rev_N_sig_caps : 1; /* if 1, FCIII has 32 PID- and MAC-filters and is capable of IP multicast */
- u32 Rev_N_sig_reserved2 : 1;
- } misc_204;
-
-/* Control and Status 0x208 to 0x21c */
-/* Gross enable and disable control */
- struct {
- u32 Stream1_filter_sig : 1; /* Stream1 PID filtering */
- u32 Stream2_filter_sig : 1; /* Stream2 PID filtering */
- u32 PCR_filter_sig : 1; /* PCR PID filter */
- u32 PMT_filter_sig : 1; /* PMT PID filter */
-
- u32 EMM_filter_sig : 1; /* EMM PID filter */
- u32 ECM_filter_sig : 1; /* ECM PID filter */
- u32 Null_filter_sig : 1; /* Filters null packets, PID=0x1fff. */
- u32 Mask_filter_sig : 1; /* mask PID filter */
-
- u32 WAN_Enable_sig : 1; /* WAN output line through V8 memory space is activated. */
- u32 WAN_CA_Enable_sig : 1; /* not in FCIII */
- u32 CA_Enable_sig : 1; /* not in FCIII */
- u32 SMC_Enable_sig : 1; /* CI stream data (CAI) goes directly to the smart card intf (opposed IBI 0x600 or SC-cmd buf). */
-
- u32 Per_CA_Enable_sig : 1; /* not in FCIII */
- u32 Multi2_Enable_sig : 1; /* ? */
- u32 MAC_filter_Mode_sig : 1; /* (MAC_filter_enable) Globally enables MAC filters for Net PID filteres. */
- u32 Rcv_Data_sig : 1; /* PID filtering module enable. When this bit is a one, the PID filter will
- examine and process packets according to all other (individual) PID
- filtering controls. If it a zero, no packet processing of any kind will
- take place. All data from the tuner will be thrown away. */
-
- u32 DMA1_IRQ_Enable_sig : 1; /* When set, a DWORD counter is enabled on PCI DMA1 that asserts the PCI
- * interrupt after the specified count for filling the buffer. */
- u32 DMA1_Timer_Enable_sig : 1; /* When set, a timer is enabled on PCI DMA1 that asserts the PCI interrupt
- after a specified amount of time. */
- u32 DMA2_IRQ_Enable_sig : 1; /* same as DMA1_IRQ_Enable_sig but for DMA2 */
- u32 DMA2_Timer_Enable_sig : 1; /* same as DMA1_Timer_Enable_sig but for DMA2 */
-
- u32 DMA1_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA1 that asserts the PCI interrupt. */
- u32 DMA2_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA2 that asserts the PCI interrupt. */
- u32 Mailbox_from_V8_Enable_sig: 1; /* When set, writes to the mailbox register produce an interrupt to the
- PCI host to indicate that mailbox data is available. */
-
- u32 unused : 9;
- } ctrl_208;
-
-/* General status. When a PCI interrupt occurs, this register is read to
- * discover the reason for the interrupt.
- */
- struct {
- u32 DMA1_IRQ_Status : 1; /* When set(1) the DMA1 counter had generated an IRQ. Read Only. */
- u32 DMA1_Timer_Status : 1; /* When set(1) the DMA1 timer had generated an IRQ. Read Only. */
- u32 DMA2_IRQ_Status : 1; /* When set(1) the DMA2 counter had generated an IRQ. Read Only. */
- u32 DMA2_Timer_Status : 1; /* When set(1) the DMA2 timer had generated an IRQ. Read Only. */
- u32 DMA1_Size_IRQ_Status : 1; /* (Read only). This register is read after an interrupt to */
- u32 DMA2_Size_IRQ_Status : 1; /* find out why we had an IRQ. Reading this register will clear this bit. Packet count*/
- u32 Mailbox_from_V8_Status_sig: 1; /* Same as above. Reading this register will clear this bit. */
- u32 Data_receiver_error : 1; /* 1 indicate an error in the receiver Front End (Tuner module) */
- u32 Continuity_error_flag : 1; /* 1 indicates a continuity error in the TS stream. */
- u32 LLC_SNAP_FLAG_set : 1; /* 1 indicates that the LCC_SNAP_FLAG was set. */
- u32 Transport_Error : 1; /* When set indicates that an unexpected packet was received. */
- u32 reserved :21;
- } irq_20c;
-
-
-/* Software reset register */
- struct {
- u32 reset_blocks : 8; /* Enabled when Block_reset_enable = 0xB2 and 0x208 bits 15:8 = 0x00.
- Each bit location represents a 0x100 block of registers. Writing
- a one in a bit location resets that block of registers and the logic
- that it controls. */
- u32 Block_reset_enable : 8; /* This variable is set to 0xB2 when the register is written. */
- u32 Special_controls :16; /* Asserts Reset_V8 => 0xC258; Turns on pci encryption => 0xC25A;
- Turns off pci encryption => 0xC259 Note: pci_encryption default
- at power-up is ON. */
- } sw_reset_210;
-
- struct {
- u32 vuart_oe_sig : 1; /* When clear, the V8 processor has sole control of the serial UART
- (RS-232 Smart Card interface). When set, the IBI interface
- defined by register 0x600 controls the serial UART. */
- u32 v2WS_oe_sig : 1; /* When clear, the V8 processor has direct control of the Two-line
- Serial Master EEPROM target. When set, the Two-line Serial Master
- EEPROM target interface is controlled by IBI register 0x100. */
- u32 halt_V8_sig : 1; /* When set, contiguous wait states are applied to the V8-space
- bus masters. Once this signal is cleared, normal V8-space
- operations resume. */
- u32 section_pkg_enable_sig: 1; /* When set, this signal enables the front end translation circuitry
- to process section packed transport streams. */
- u32 s2p_sel_sig : 1; /* Serial to parallel conversion. When set, polarized transport data
- within the FlexCop3 front end circuitry is converted from a serial
- stream into parallel data before downstream processing otherwise
- interprets the data. */
- u32 unused1 : 3;
- u32 polarity_PS_CLK_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream CLOCK signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 polarity_PS_VALID_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream VALID signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 polarity_PS_SYNC_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream SYNC signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 polarity_PS_ERR_sig: 1; /* This signal is used to invert the input polarity of the tranport
- stream ERROR signal before any processing occurs on the transport
- stream within FlexCop3. */
- u32 unused2 :20;
- } misc_214;
-
-/* Mailbox from V8 to host */
- struct {
- u32 Mailbox_from_V8 :32; /* When this register is written by either the V8 processor or by an
- end host, an interrupt is generated to the PCI host to indicate
- that mailbox data is available. Reading register 20c will clear
- the IRQ. */
- } mbox_v8_to_host_218;
-
-/* Mailbox from host to v8 Mailbox_to_V8
- * Mailbox_to_V8 mailbox storage register
- * used to send messages from PCI to V8. Writing to this register will send an
- * IRQ to the V8. Then it can read the data from here. Reading this register
- * will clear the IRQ. If the V8 is halted and bit 31 of this register is set,
- * then this register is used instead as a direct interface to access the
- * V8space memory.
- */
- struct {
- u32 sysramaccess_data : 8; /* Data byte written or read from the specified address in V8 SysRAM. */
- u32 sysramaccess_addr :15; /* 15 bit address used to access V8 Sys-RAM. */
- u32 unused : 7;
- u32 sysramaccess_write: 1; /* Write flag used to latch data into the V8 SysRAM. */
- u32 sysramaccess_busmuster: 1; /* Setting this bit when the V8 is halted at 0x214 Bit(2) allows
- this IBI register interface to directly drive the V8-space memory. */
- } mbox_host_to_v8_21c;
-
-
-/* PIDs, Translation Bit, SMC Filter Select 0x300 to 0x31c */
- struct {
- u32 Stream1_PID :13; /* Primary use is receiving Net data, so these 13 bits normally
- hold the PID value for the desired network stream. */
- u32 Stream1_trans : 1; /* When set, Net translation will take place for Net data ferried in TS packets. */
- u32 MAC_Multicast_filter : 1; /* When clear, multicast MAC filtering is not allowed for Stream1 and PID_n filters. */
- u32 debug_flag_pid_saved : 1;
- u32 Stream2_PID :13; /* 13 bits for Stream 2 PID filter value. General use. */
- u32 Stream2_trans : 1; /* When set Tables/CAI translation will take place for the data ferried in
- Stream2_PID TS packets. */
- u32 debug_flag_write_status00 : 1;
- u32 debug_fifo_problem : 1;
- } pid_filter_300;
-
- struct {
- u32 PCR_PID :13; /* PCR stream PID filter value. Primary use is Program Clock Reference stream filtering. */
- u32 PCR_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 debug_overrun3 : 1;
- u32 debug_overrun2 : 1;
- u32 PMT_PID :13; /* stream PID filter value. Primary use is Program Management Table segment filtering. */
- u32 PMT_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 reserved : 2;
- } pid_filter_304;
-
- struct {
- u32 EMM_PID :13; /* EMM PID filter value. Primary use is Entitlement Management Messaging for
- conditional access-related data. */
- u32 EMM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 EMM_filter_4 : 1; /* When set will pass only EMM data possessing the same ID code as the
- first four bytes (32 bits) of the end-user s 6-byte Smart Card ID number Select */
- u32 EMM_filter_6 : 1; /* When set will pass only EMM data possessing the same 6-byte code as the end-users
- complete 6-byte Smart Card ID number. */
- u32 ECM_PID :13; /* ECM PID filter value. Primary use is Entitlement Control Messaging for conditional
- access-related data. */
- u32 ECM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 reserved : 2;
- } pid_filter_308;
-
- struct {
- u32 Group_PID :13; /* PID value for group filtering. */
- u32 Group_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */
- u32 unused1 : 2;
- u32 Group_mask :13; /* Mask value used in logical "and" equation that defines group filtering */
- u32 unused2 : 3;
- } pid_filter_30c_ext_ind_0_7;
-
- struct {
- u32 net_master_read :17;
- u32 unused :15;
- } pid_filter_30c_ext_ind_1;
-
- struct {
- u32 net_master_write :17;
- u32 unused :15;
- } pid_filter_30c_ext_ind_2;
-
- struct {
- u32 next_net_master_write :17;
- u32 unused :15;
- } pid_filter_30c_ext_ind_3;
-
- struct {
- u32 unused1 : 1;
- u32 state_write :10;
- u32 reserved1 : 6; /* default: 000100 */
- u32 stack_read :10;
- u32 reserved2 : 5; /* default: 00100 */
- } pid_filter_30c_ext_ind_4;
-
- struct {
- u32 stack_cnt :10;
- u32 unused :22;
- } pid_filter_30c_ext_ind_5;
-
- struct {
- u32 pid_fsm_save_reg0 : 2;
- u32 pid_fsm_save_reg1 : 2;
- u32 pid_fsm_save_reg2 : 2;
- u32 pid_fsm_save_reg3 : 2;
- u32 pid_fsm_save_reg4 : 2;
- u32 pid_fsm_save_reg300 : 2;
- u32 write_status1 : 2;
- u32 write_status4 : 2;
- u32 data_size_reg :12;
- u32 unused : 4;
- } pid_filter_30c_ext_ind_6;
-
- struct {
- u32 index_reg : 5; /* (Index pointer) Points at an internal PIDn register. A binary code
- representing one of 32 internal PIDn registers as well as its
- corresponding internal MAC_lown register. */
- u32 extra_index_reg : 3; /* This vector is used to select between sets of debug signals routed to register 0x30c. */
- u32 AB_select : 1; /* Used in conjunction with 0x31c. read/write to the MAC_highA or MAC_highB register
- 0=MAC_highB register, 1=MAC_highA */
- u32 pass_alltables : 1; /* 1=Net packets are not filtered against the Network Table ID found in register 0x400.
- All types of networks (DVB, ATSC, ISDB) are passed. */
- u32 unused :22;
- } index_reg_310;
-
- struct {
- u32 PID :13; /* PID value */
- u32 PID_trans : 1; /* translation will take place for packets filtered */
- u32 PID_enable_bit : 1; /* When set this PID filter is enabled */
- u32 reserved :17;
- } pid_n_reg_314;
-
- struct {
- u32 A4_byte : 8;
- u32 A5_byte : 8;
- u32 A6_byte : 8;
- u32 Enable_bit : 1; /* enabled (1) or disabled (1) */
- u32 HighAB_bit : 1; /* use MAC_highA (1) or MAC_highB (0) as MSB */
- u32 reserved : 6;
- } mac_low_reg_318;
-
- struct {
- u32 A1_byte : 8;
- u32 A2_byte : 8;
- u32 A3_byte : 8;
- u32 reserved : 8;
- } mac_high_reg_31c;
-
-/* Table, SMCID,MACDestination Filters 0x400 to 0x41c */
- struct {
- u32 reserved :16;
#define fc_data_Tag_ID_DVB 0x3e
#define fc_data_Tag_ID_ATSC 0x3f
#define fc_data_Tag_ID_IDSB 0x8b
- u32 data_Tag_ID :16;
- } data_tag_400;
-
- struct {
- u32 Card_IDbyte6 : 8;
- u32 Card_IDbyte5 : 8;
- u32 Card_IDbyte4 : 8;
- u32 Card_IDbyte3 : 8;
- } card_id_408;
-
- struct {
- u32 Card_IDbyte2 : 8;
- u32 Card_IDbyte1 : 8;
- } card_id_40c;
-
- /* holding the unique mac address of the receiver which houses the FlexCopIII */
- struct {
- u32 MAC1 : 8;
- u32 MAC2 : 8;
- u32 MAC3 : 8;
- u32 MAC6 : 8;
- } mac_address_418;
-
- struct {
- u32 MAC7 : 8;
- u32 MAC8 : 8;
- u32 reserved : 16;
- } mac_address_41c;
-
- struct {
- u32 transmitter_data_byte : 8;
- u32 ReceiveDataReady : 1;
- u32 ReceiveByteFrameError: 1;
- u32 txbuffempty : 1;
- u32 reserved :21;
- } ci_600;
-
- struct {
- u32 pi_d : 8;
- u32 pi_ha :20;
- u32 pi_rw : 1;
- u32 pi_component_reg : 3;
- } pi_604;
-
- struct {
- u32 serialReset : 1;
- u32 oncecycle_read : 1;
- u32 Timer_Read_req : 1;
- u32 Timer_Load_req : 1;
- u32 timer_data : 7;
- u32 unused : 1; /* ??? not mentioned in data book */
- u32 Timer_addr : 5;
- u32 reserved : 3;
- u32 pcmcia_a_mod_pwr_n : 1;
- u32 pcmcia_b_mod_pwr_n : 1;
- u32 config_Done_stat : 1;
- u32 config_Init_stat : 1;
- u32 config_Prog_n : 1;
- u32 config_wr_n : 1;
- u32 config_cs_n : 1;
- u32 config_cclk : 1;
- u32 pi_CiMax_IRQ_n : 1;
- u32 pi_timeout_status : 1;
- u32 pi_wait_n : 1;
- u32 pi_busy_n : 1;
- } pi_608;
- struct {
- u32 PID :13;
- u32 key_enable : 1;
#define fc_key_code_default 0x1
#define fc_key_code_even 0x2
#define fc_key_code_odd 0x3
- u32 key_code : 2;
- u32 key_array_col : 3;
- u32 key_array_row : 5;
- u32 dvb_en : 1; /* 0=TS bypasses the Descrambler */
- u32 rw_flag : 1;
- u32 reserved : 6;
- } dvb_reg_60c;
-
-/* SRAM and Output Destination 0x700 to 0x714 */
- struct {
- u32 sram_addr :15;
- u32 sram_rw : 1; /* 0=write, 1=read */
- u32 sram_data : 8;
- u32 sc_xfer_bit : 1;
- u32 reserved1 : 3;
- u32 oe_pin_reg : 1;
- u32 ce_pin_reg : 1;
- u32 reserved2 : 1;
- u32 start_sram_ibi : 1;
- } sram_ctrl_reg_700;
-
- struct {
- u32 net_addr_read :16;
- u32 net_addr_write :16;
- } net_buf_reg_704;
-
- struct {
- u32 cai_read :11;
- u32 reserved1 : 5;
- u32 cai_write :11;
- u32 reserved2 : 6;
- u32 cai_cnt : 4;
- } cai_buf_reg_708;
-
- struct {
- u32 cao_read :11;
- u32 reserved1 : 5;
- u32 cap_write :11;
- u32 reserved2 : 6;
- u32 cao_cnt : 4;
- } cao_buf_reg_70c;
-
- struct {
- u32 media_read :11;
- u32 reserved1 : 5;
- u32 media_write :11;
- u32 reserved2 : 6;
- u32 media_cnt : 4;
- } media_buf_reg_710;
-
- struct {
- u32 NET_Dest : 2;
- u32 CAI_Dest : 2;
- u32 CAO_Dest : 2;
- u32 MEDIA_Dest : 2;
- u32 net_ovflow_error : 1;
- u32 media_ovflow_error : 1;
- u32 cai_ovflow_error : 1;
- u32 cao_ovflow_error : 1;
- u32 ctrl_usb_wan : 1;
- u32 ctrl_sramdma : 1;
- u32 ctrl_maximumfill : 1;
- u32 reserved :17;
- } sram_dest_reg_714;
-
- struct {
- u32 net_cnt :12;
- u32 reserved1 : 4;
- u32 net_addr_read : 1;
- u32 reserved2 : 3;
- u32 net_addr_write : 1;
- u32 reserved3 :11;
- } net_buf_reg_718;
-
- struct {
- u32 wan_speed_sig : 2;
- u32 reserved1 : 6;
- u32 wan_wait_state : 8;
- u32 sram_chip : 2;
- u32 sram_memmap : 2;
- u32 reserved2 : 4;
- u32 wan_pkt_frame : 4;
- u32 reserved3 : 4;
- } wan_ctrl_reg_71c;
-} flexcop_ibi_value;
extern flexcop_ibi_value ibi_zero;
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index 0113449abd1..0a78ba3737a 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -545,7 +545,7 @@ static struct usb_device_id flexcop_usb_table [] = {
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver flexcop_usb_driver = {
.owner = THIS_MODULE,
- .name = "Technisat/B2C2 FlexCop II/IIb/III USB",
+ .name = "b2c2_flexcop_usb",
.probe = flexcop_usb_probe,
.disconnect = flexcop_usb_disconnect,
.id_table = flexcop_usb_table,
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 8b5d14dd36e..12873d43540 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -46,7 +46,7 @@
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 (|-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
/* global zero for ibi values */
@@ -173,9 +173,20 @@ static void flexcop_reset(struct flexcop_device *fc)
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
- v210.sw_reset_210.reset_blocks = 0xff;
+ v210.sw_reset_210.reset_block_000 = 1;
+ v210.sw_reset_210.reset_block_100 = 1;
+ v210.sw_reset_210.reset_block_200 = 1;
+ v210.sw_reset_210.reset_block_300 = 1;
+ v210.sw_reset_210.reset_block_400 = 1;
+ v210.sw_reset_210.reset_block_500 = 1;
+ v210.sw_reset_210.reset_block_600 = 1;
+ v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+ v210.sw_reset_210.Special_controls = 0xc259;
+
fc->write_ibi_reg(fc,sw_reset_210,v210);
+ msleep(1);
/* reset the periphical devices */
@@ -186,6 +197,25 @@ static void flexcop_reset(struct flexcop_device *fc)
fc->write_ibi_reg(fc,misc_204,v204);
}
+void flexcop_reset_block_300(struct flexcop_device *fc)
+{
+ flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
+ v210 = fc->read_ibi_reg(fc,sw_reset_210);
+
+ deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+
+ fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
+
+ v210.sw_reset_210.reset_block_300 = 1;
+ v210.sw_reset_210.Block_reset_enable = 0xb2;
+
+ fc->write_ibi_reg(fc,sw_reset_210,v210);
+ msleep(1);
+
+ fc->write_ibi_reg(fc,ctrl_208,v208_save);
+}
+EXPORT_SYMBOL(flexcop_reset_block_300);
+
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
{
void *bus;
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
index caa343a97bd..0cebe1d92e0 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -26,5 +26,6 @@ extern int b2c2_flexcop_debug;
#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
new file mode 100644
index 00000000000..ed9a6756b19
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -0,0 +1,458 @@
+/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * register descriptions
+ *
+ * see flexcop.c for copyright information.
+ */
+
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+ u32 raw;
+
+ struct {
+ u32 dma_address0 :30;
+ u32 dma_0No_update : 1;
+ u32 dma_0start : 1;
+ } dma_0x0;
+
+ struct {
+ u32 dma_addr_size :24;
+ u32 DMA_maxpackets : 8;
+ } dma_0x4_remap;
+
+ struct {
+ u32 dma_addr_size :24;
+ u32 unused : 1;
+ u32 dma1timer : 7;
+ } dma_0x4_read;
+
+ struct {
+ u32 dma_addr_size :24;
+ u32 dmatimer : 7;
+ u32 unused : 1;
+ } dma_0x4_write;
+
+ struct {
+ u32 dma_cur_addr :30;
+ u32 unused : 2;
+ } dma_0x8;
+
+ struct {
+ u32 dma_address1 :30;
+ u32 remap_enable : 1;
+ u32 dma_1start : 1;
+ } dma_0xc;
+
+ struct {
+ u32 st_done : 1;
+ u32 no_base_addr_ack_error : 1;
+ u32 twoWS_port_reg : 2;
+ u32 total_bytes : 2;
+ u32 twoWS_rw : 1;
+ u32 working_start : 1;
+ u32 data1_reg : 8;
+ u32 baseaddr : 8;
+ u32 reserved1 : 1;
+ u32 chipaddr : 7;
+ } tw_sm_c_100;
+
+ struct {
+ u32 unused : 6;
+ u32 force_stop : 1;
+ u32 exlicit_stops : 1;
+ u32 data4_reg : 8;
+ u32 data3_reg : 8;
+ u32 data2_reg : 8;
+ } tw_sm_c_104;
+
+ struct {
+ u32 reserved2 :19;
+ u32 tlo1 : 5;
+ u32 reserved1 : 2;
+ u32 thi1 : 6;
+ } tw_sm_c_108;
+
+ struct {
+ u32 reserved2 :19;
+ u32 tlo1 : 5;
+ u32 reserved1 : 2;
+ u32 thi1 : 6;
+ } tw_sm_c_10c;
+
+ struct {
+ u32 reserved2 :19;
+ u32 tlo1 : 5;
+ u32 reserved1 : 2;
+ u32 thi1 : 6;
+ } tw_sm_c_110;
+
+ struct {
+ u32 LNB_CTLPrescaler_sig : 2;
+ u32 LNB_CTLLowCount_sig :15;
+ u32 LNB_CTLHighCount_sig :15;
+ } lnb_switch_freq_200;
+
+ struct {
+ u32 Rev_N_sig_reserved2 : 1;
+ u32 Rev_N_sig_caps : 1;
+ u32 Rev_N_sig_reserved1 : 2;
+ u32 Rev_N_sig_revision_hi : 4;
+ u32 reserved :20;
+ u32 Per_reset_sig : 1;
+ u32 LNB_L_H_sig : 1;
+ u32 ACPI3_sig : 1;
+ u32 ACPI1_sig : 1;
+ } misc_204;
+
+ struct {
+ u32 unused : 9;
+ u32 Mailbox_from_V8_Enable_sig : 1;
+ u32 DMA2_Size_IRQ_Enable_sig : 1;
+ u32 DMA1_Size_IRQ_Enable_sig : 1;
+ u32 DMA2_Timer_Enable_sig : 1;
+ u32 DMA2_IRQ_Enable_sig : 1;
+ u32 DMA1_Timer_Enable_sig : 1;
+ u32 DMA1_IRQ_Enable_sig : 1;
+ u32 Rcv_Data_sig : 1;
+ u32 MAC_filter_Mode_sig : 1;
+ u32 Multi2_Enable_sig : 1;
+ u32 Per_CA_Enable_sig : 1;
+ u32 SMC_Enable_sig : 1;
+ u32 CA_Enable_sig : 1;
+ u32 WAN_CA_Enable_sig : 1;
+ u32 WAN_Enable_sig : 1;
+ u32 Mask_filter_sig : 1;
+ u32 Null_filter_sig : 1;
+ u32 ECM_filter_sig : 1;
+ u32 EMM_filter_sig : 1;
+ u32 PMT_filter_sig : 1;
+ u32 PCR_filter_sig : 1;
+ u32 Stream2_filter_sig : 1;
+ u32 Stream1_filter_sig : 1;
+ } ctrl_208;
+
+ struct {
+ u32 reserved :21;
+ u32 Transport_Error : 1;
+ u32 LLC_SNAP_FLAG_set : 1;
+ u32 Continuity_error_flag : 1;
+ u32 Data_receiver_error : 1;
+ u32 Mailbox_from_V8_Status_sig : 1;
+ u32 DMA2_Size_IRQ_Status : 1;
+ u32 DMA1_Size_IRQ_Status : 1;
+ u32 DMA2_Timer_Status : 1;
+ u32 DMA2_IRQ_Status : 1;
+ u32 DMA1_Timer_Status : 1;
+ u32 DMA1_IRQ_Status : 1;
+ } irq_20c;
+
+ struct {
+ u32 Special_controls :16;
+ u32 Block_reset_enable : 8;
+ u32 reset_block_700 : 1;
+ u32 reset_block_600 : 1;
+ u32 reset_block_500 : 1;
+ u32 reset_block_400 : 1;
+ u32 reset_block_300 : 1;
+ u32 reset_block_200 : 1;
+ u32 reset_block_100 : 1;
+ u32 reset_block_000 : 1;
+ } sw_reset_210;
+
+ struct {
+ u32 unused2 :20;
+ u32 polarity_PS_ERR_sig : 1;
+ u32 polarity_PS_SYNC_sig : 1;
+ u32 polarity_PS_VALID_sig : 1;
+ u32 polarity_PS_CLK_sig : 1;
+ u32 unused1 : 3;
+ u32 s2p_sel_sig : 1;
+ u32 section_pkg_enable_sig : 1;
+ u32 halt_V8_sig : 1;
+ u32 v2WS_oe_sig : 1;
+ u32 vuart_oe_sig : 1;
+ } misc_214;
+
+ struct {
+ u32 Mailbox_from_V8 :32;
+ } mbox_v8_to_host_218;
+
+ struct {
+ u32 sysramaccess_busmuster : 1;
+ u32 sysramaccess_write : 1;
+ u32 unused : 7;
+ u32 sysramaccess_addr :15;
+ u32 sysramaccess_data : 8;
+ } mbox_host_to_v8_21c;
+
+ struct {
+ u32 debug_fifo_problem : 1;
+ u32 debug_flag_write_status00 : 1;
+ u32 Stream2_trans : 1;
+ u32 Stream2_PID :13;
+ u32 debug_flag_pid_saved : 1;
+ u32 MAC_Multicast_filter : 1;
+ u32 Stream1_trans : 1;
+ u32 Stream1_PID :13;
+ } pid_filter_300;
+
+ struct {
+ u32 reserved : 2;
+ u32 PMT_trans : 1;
+ u32 PMT_PID :13;
+ u32 debug_overrun2 : 1;
+ u32 debug_overrun3 : 1;
+ u32 PCR_trans : 1;
+ u32 PCR_PID :13;
+ } pid_filter_304;
+
+ struct {
+ u32 reserved : 2;
+ u32 ECM_trans : 1;
+ u32 ECM_PID :13;
+ u32 EMM_filter_6 : 1;
+ u32 EMM_filter_4 : 1;
+ u32 EMM_trans : 1;
+ u32 EMM_PID :13;
+ } pid_filter_308;
+
+ struct {
+ u32 unused2 : 3;
+ u32 Group_mask :13;
+ u32 unused1 : 2;
+ u32 Group_trans : 1;
+ u32 Group_PID :13;
+ } pid_filter_30c_ext_ind_0_7;
+
+ struct {
+ u32 unused :15;
+ u32 net_master_read :17;
+ } pid_filter_30c_ext_ind_1;
+
+ struct {
+ u32 unused :15;
+ u32 net_master_write :17;
+ } pid_filter_30c_ext_ind_2;
+
+ struct {
+ u32 unused :15;
+ u32 next_net_master_write :17;
+ } pid_filter_30c_ext_ind_3;
+
+ struct {
+ u32 reserved2 : 5;
+ u32 stack_read :10;
+ u32 reserved1 : 6;
+ u32 state_write :10;
+ u32 unused1 : 1;
+ } pid_filter_30c_ext_ind_4;
+
+ struct {
+ u32 unused :22;
+ u32 stack_cnt :10;
+ } pid_filter_30c_ext_ind_5;
+
+ struct {
+ u32 unused : 4;
+ u32 data_size_reg :12;
+ u32 write_status4 : 2;
+ u32 write_status1 : 2;
+ u32 pid_fsm_save_reg300 : 2;
+ u32 pid_fsm_save_reg4 : 2;
+ u32 pid_fsm_save_reg3 : 2;
+ u32 pid_fsm_save_reg2 : 2;
+ u32 pid_fsm_save_reg1 : 2;
+ u32 pid_fsm_save_reg0 : 2;
+ } pid_filter_30c_ext_ind_6;
+
+ struct {
+ u32 unused :22;
+ u32 pass_alltables : 1;
+ u32 AB_select : 1;
+ u32 extra_index_reg : 3;
+ u32 index_reg : 5;
+ } index_reg_310;
+
+ struct {
+ u32 reserved :17;
+ u32 PID_enable_bit : 1;
+ u32 PID_trans : 1;
+ u32 PID :13;
+ } pid_n_reg_314;
+
+ struct {
+ u32 reserved : 6;
+ u32 HighAB_bit : 1;
+ u32 Enable_bit : 1;
+ u32 A6_byte : 8;
+ u32 A5_byte : 8;
+ u32 A4_byte : 8;
+ } mac_low_reg_318;
+
+ struct {
+ u32 reserved : 8;
+ u32 A3_byte : 8;
+ u32 A2_byte : 8;
+ u32 A1_byte : 8;
+ } mac_high_reg_31c;
+
+ struct {
+ u32 data_Tag_ID :16;
+ u32 reserved :16;
+ } data_tag_400;
+
+ struct {
+ u32 Card_IDbyte3 : 8;
+ u32 Card_IDbyte4 : 8;
+ u32 Card_IDbyte5 : 8;
+ u32 Card_IDbyte6 : 8;
+ } card_id_408;
+
+ struct {
+ u32 Card_IDbyte1 : 8;
+ u32 Card_IDbyte2 : 8;
+ } card_id_40c;
+
+ struct {
+ u32 MAC6 : 8;
+ u32 MAC3 : 8;
+ u32 MAC2 : 8;
+ u32 MAC1 : 8;
+ } mac_address_418;
+
+ struct {
+ u32 reserved :16;
+ u32 MAC8 : 8;
+ u32 MAC7 : 8;
+ } mac_address_41c;
+
+ struct {
+ u32 reserved :21;
+ u32 txbuffempty : 1;
+ u32 ReceiveByteFrameError : 1;
+ u32 ReceiveDataReady : 1;
+ u32 transmitter_data_byte : 8;
+ } ci_600;
+
+ struct {
+ u32 pi_component_reg : 3;
+ u32 pi_rw : 1;
+ u32 pi_ha :20;
+ u32 pi_d : 8;
+ } pi_604;
+
+ struct {
+ u32 pi_busy_n : 1;
+ u32 pi_wait_n : 1;
+ u32 pi_timeout_status : 1;
+ u32 pi_CiMax_IRQ_n : 1;
+ u32 config_cclk : 1;
+ u32 config_cs_n : 1;
+ u32 config_wr_n : 1;
+ u32 config_Prog_n : 1;
+ u32 config_Init_stat : 1;
+ u32 config_Done_stat : 1;
+ u32 pcmcia_b_mod_pwr_n : 1;
+ u32 pcmcia_a_mod_pwr_n : 1;
+ u32 reserved : 3;
+ u32 Timer_addr : 5;
+ u32 unused : 1;
+ u32 timer_data : 7;
+ u32 Timer_Load_req : 1;
+ u32 Timer_Read_req : 1;
+ u32 oncecycle_read : 1;
+ u32 serialReset : 1;
+ } pi_608;
+
+ struct {
+ u32 reserved : 6;
+ u32 rw_flag : 1;
+ u32 dvb_en : 1;
+ u32 key_array_row : 5;
+ u32 key_array_col : 3;
+ u32 key_code : 2;
+ u32 key_enable : 1;
+ u32 PID :13;
+ } dvb_reg_60c;
+
+ struct {
+ u32 start_sram_ibi : 1;
+ u32 reserved2 : 1;
+ u32 ce_pin_reg : 1;
+ u32 oe_pin_reg : 1;
+ u32 reserved1 : 3;
+ u32 sc_xfer_bit : 1;
+ u32 sram_data : 8;
+ u32 sram_rw : 1;
+ u32 sram_addr :15;
+ } sram_ctrl_reg_700;
+
+ struct {
+ u32 net_addr_write :16;
+ u32 net_addr_read :16;
+ } net_buf_reg_704;
+
+ struct {
+ u32 cai_cnt : 4;
+ u32 reserved2 : 6;
+ u32 cai_write :11;
+ u32 reserved1 : 5;
+ u32 cai_read :11;
+ } cai_buf_reg_708;
+
+ struct {
+ u32 cao_cnt : 4;
+ u32 reserved2 : 6;
+ u32 cap_write :11;
+ u32 reserved1 : 5;
+ u32 cao_read :11;
+ } cao_buf_reg_70c;
+
+ struct {
+ u32 media_cnt : 4;
+ u32 reserved2 : 6;
+ u32 media_write :11;
+ u32 reserved1 : 5;
+ u32 media_read :11;
+ } media_buf_reg_710;
+
+ struct {
+ u32 reserved :17;
+ u32 ctrl_maximumfill : 1;
+ u32 ctrl_sramdma : 1;
+ u32 ctrl_usb_wan : 1;
+ u32 cao_ovflow_error : 1;
+ u32 cai_ovflow_error : 1;
+ u32 media_ovflow_error : 1;
+ u32 net_ovflow_error : 1;
+ u32 MEDIA_Dest : 2;
+ u32 CAO_Dest : 2;
+ u32 CAI_Dest : 2;
+ u32 NET_Dest : 2;
+ } sram_dest_reg_714;
+
+ struct {
+ u32 reserved3 :11;
+ u32 net_addr_write : 1;
+ u32 reserved2 : 3;
+ u32 net_addr_read : 1;
+ u32 reserved1 : 4;
+ u32 net_cnt :12;
+ } net_buf_reg_718;
+
+ struct {
+ u32 reserved3 : 4;
+ u32 wan_pkt_frame : 4;
+ u32 reserved2 : 4;
+ u32 sram_memmap : 2;
+ u32 sram_chip : 2;
+ u32 wan_wait_state : 8;
+ u32 reserved1 : 6;
+ u32 wan_speed_sig : 2;
+ } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
new file mode 100644
index 00000000000..49f2315b6e5
--- /dev/null
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -0,0 +1,458 @@
+/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ *
+ * register descriptions
+ *
+ * see flexcop.c for copyright information.
+ */
+
+/* This file is automatically generated, do not edit things here. */
+#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
+#define __FLEXCOP_IBI_VALUE_INCLUDED__
+
+typedef union {
+ u32 raw;
+
+ struct {
+ u32 dma_0start : 1;
+ u32 dma_0No_update : 1;
+ u32 dma_address0 :30;
+ } dma_0x0;
+
+ struct {
+ u32 DMA_maxpackets : 8;
+ u32 dma_addr_size :24;
+ } dma_0x4_remap;
+
+ struct {
+ u32 dma1timer : 7;
+ u32 unused : 1;
+ u32 dma_addr_size :24;
+ } dma_0x4_read;
+
+ struct {
+ u32 unused : 1;
+ u32 dmatimer : 7;
+ u32 dma_addr_size :24;
+ } dma_0x4_write;
+
+ struct {
+ u32 unused : 2;
+ u32 dma_cur_addr :30;
+ } dma_0x8;
+
+ struct {
+ u32 dma_1start : 1;
+ u32 remap_enable : 1;
+ u32 dma_address1 :30;
+ } dma_0xc;
+
+ struct {
+ u32 chipaddr : 7;
+ u32 reserved1 : 1;
+ u32 baseaddr : 8;
+ u32 data1_reg : 8;
+ u32 working_start : 1;
+ u32 twoWS_rw : 1;
+ u32 total_bytes : 2;
+ u32 twoWS_port_reg : 2;
+ u32 no_base_addr_ack_error : 1;
+ u32 st_done : 1;
+ } tw_sm_c_100;
+
+ struct {
+ u32 data2_reg : 8;
+ u32 data3_reg : 8;
+ u32 data4_reg : 8;
+ u32 exlicit_stops : 1;
+ u32 force_stop : 1;
+ u32 unused : 6;
+ } tw_sm_c_104;
+
+ struct {
+ u32 thi1 : 6;
+ u32 reserved1 : 2;
+ u32 tlo1 : 5;
+ u32 reserved2 :19;
+ } tw_sm_c_108;
+
+ struct {
+ u32 thi1 : 6;
+ u32 reserved1 : 2;
+ u32 tlo1 : 5;
+ u32 reserved2 :19;
+ } tw_sm_c_10c;
+
+ struct {
+ u32 thi1 : 6;
+ u32 reserved1 : 2;
+ u32 tlo1 : 5;
+ u32 reserved2 :19;
+ } tw_sm_c_110;
+
+ struct {
+ u32 LNB_CTLHighCount_sig :15;
+ u32 LNB_CTLLowCount_sig :15;
+ u32 LNB_CTLPrescaler_sig : 2;
+ } lnb_switch_freq_200;
+
+ struct {
+ u32 ACPI1_sig : 1;
+ u32 ACPI3_sig : 1;
+ u32 LNB_L_H_sig : 1;
+ u32 Per_reset_sig : 1;
+ u32 reserved :20;
+ u32 Rev_N_sig_revision_hi : 4;
+ u32 Rev_N_sig_reserved1 : 2;
+ u32 Rev_N_sig_caps : 1;
+ u32 Rev_N_sig_reserved2 : 1;
+ } misc_204;
+
+ struct {
+ u32 Stream1_filter_sig : 1;
+ u32 Stream2_filter_sig : 1;
+ u32 PCR_filter_sig : 1;
+ u32 PMT_filter_sig : 1;
+ u32 EMM_filter_sig : 1;
+ u32 ECM_filter_sig : 1;
+ u32 Null_filter_sig : 1;
+ u32 Mask_filter_sig : 1;
+ u32 WAN_Enable_sig : 1;
+ u32 WAN_CA_Enable_sig : 1;
+ u32 CA_Enable_sig : 1;
+ u32 SMC_Enable_sig : 1;
+ u32 Per_CA_Enable_sig : 1;
+ u32 Multi2_Enable_sig : 1;
+ u32 MAC_filter_Mode_sig : 1;
+ u32 Rcv_Data_sig : 1;
+ u32 DMA1_IRQ_Enable_sig : 1;
+ u32 DMA1_Timer_Enable_sig : 1;
+ u32 DMA2_IRQ_Enable_sig : 1;
+ u32 DMA2_Timer_Enable_sig : 1;
+ u32 DMA1_Size_IRQ_Enable_sig : 1;
+ u32 DMA2_Size_IRQ_Enable_sig : 1;
+ u32 Mailbox_from_V8_Enable_sig : 1;
+ u32 unused : 9;
+ } ctrl_208;
+
+ struct {
+ u32 DMA1_IRQ_Status : 1;
+ u32 DMA1_Timer_Status : 1;
+ u32 DMA2_IRQ_Status : 1;
+ u32 DMA2_Timer_Status : 1;
+ u32 DMA1_Size_IRQ_Status : 1;
+ u32 DMA2_Size_IRQ_Status : 1;
+ u32 Mailbox_from_V8_Status_sig : 1;
+ u32 Data_receiver_error : 1;
+ u32 Continuity_error_flag : 1;
+ u32 LLC_SNAP_FLAG_set : 1;
+ u32 Transport_Error : 1;
+ u32 reserved :21;
+ } irq_20c;
+
+ struct {
+ u32 reset_block_000 : 1;
+ u32 reset_block_100 : 1;
+ u32 reset_block_200 : 1;
+ u32 reset_block_300 : 1;
+ u32 reset_block_400 : 1;
+ u32 reset_block_500 : 1;
+ u32 reset_block_600 : 1;
+ u32 reset_block_700 : 1;
+ u32 Block_reset_enable : 8;
+ u32 Special_controls :16;
+ } sw_reset_210;
+
+ struct {
+ u32 vuart_oe_sig : 1;
+ u32 v2WS_oe_sig : 1;
+ u32 halt_V8_sig : 1;
+ u32 section_pkg_enable_sig : 1;
+ u32 s2p_sel_sig : 1;
+ u32 unused1 : 3;
+ u32 polarity_PS_CLK_sig : 1;
+ u32 polarity_PS_VALID_sig : 1;
+ u32 polarity_PS_SYNC_sig : 1;
+ u32 polarity_PS_ERR_sig : 1;
+ u32 unused2 :20;
+ } misc_214;
+
+ struct {
+ u32 Mailbox_from_V8 :32;
+ } mbox_v8_to_host_218;
+
+ struct {
+ u32 sysramaccess_data : 8;
+ u32 sysramaccess_addr :15;
+ u32 unused : 7;
+ u32 sysramaccess_write : 1;
+ u32 sysramaccess_busmuster : 1;
+ } mbox_host_to_v8_21c;
+
+ struct {
+ u32 Stream1_PID :13;
+ u32 Stream1_trans : 1;
+ u32 MAC_Multicast_filter : 1;
+ u32 debug_flag_pid_saved : 1;
+ u32 Stream2_PID :13;
+ u32 Stream2_trans : 1;
+ u32 debug_flag_write_status00 : 1;
+ u32 debug_fifo_problem : 1;
+ } pid_filter_300;
+
+ struct {
+ u32 PCR_PID :13;
+ u32 PCR_trans : 1;
+ u32 debug_overrun3 : 1;
+ u32 debug_overrun2 : 1;
+ u32 PMT_PID :13;
+ u32 PMT_trans : 1;
+ u32 reserved : 2;
+ } pid_filter_304;
+
+ struct {
+ u32 EMM_PID :13;
+ u32 EMM_trans : 1;
+ u32 EMM_filter_4 : 1;
+ u32 EMM_filter_6 : 1;
+ u32 ECM_PID :13;
+ u32 ECM_trans : 1;
+ u32 reserved : 2;
+ } pid_filter_308;
+
+ struct {
+ u32 Group_PID :13;
+ u32 Group_trans : 1;
+ u32 unused1 : 2;
+ u32 Group_mask :13;
+ u32 unused2 : 3;
+ } pid_filter_30c_ext_ind_0_7;
+
+ struct {
+ u32 net_master_read :17;
+ u32 unused :15;
+ } pid_filter_30c_ext_ind_1;
+
+ struct {
+ u32 net_master_write :17;
+ u32 unused :15;
+ } pid_filter_30c_ext_ind_2;
+
+ struct {
+ u32 next_net_master_write :17;
+ u32 unused :15;
+ } pid_filter_30c_ext_ind_3;
+
+ struct {
+ u32 unused1 : 1;
+ u32 state_write :10;
+ u32 reserved1 : 6;
+ u32 stack_read :10;
+ u32 reserved2 : 5;
+ } pid_filter_30c_ext_ind_4;
+
+ struct {
+ u32 stack_cnt :10;
+ u32 unused :22;
+ } pid_filter_30c_ext_ind_5;
+
+ struct {
+ u32 pid_fsm_save_reg0 : 2;
+ u32 pid_fsm_save_reg1 : 2;
+ u32 pid_fsm_save_reg2 : 2;
+ u32 pid_fsm_save_reg3 : 2;
+ u32 pid_fsm_save_reg4 : 2;
+ u32 pid_fsm_save_reg300 : 2;
+ u32 write_status1 : 2;
+ u32 write_status4 : 2;
+ u32 data_size_reg :12;
+ u32 unused : 4;
+ } pid_filter_30c_ext_ind_6;
+
+ struct {
+ u32 index_reg : 5;
+ u32 extra_index_reg : 3;
+ u32 AB_select : 1;
+ u32 pass_alltables : 1;
+ u32 unused :22;
+ } index_reg_310;
+
+ struct {
+ u32 PID :13;
+ u32 PID_trans : 1;
+ u32 PID_enable_bit : 1;
+ u32 reserved :17;
+ } pid_n_reg_314;
+
+ struct {
+ u32 A4_byte : 8;
+ u32 A5_byte : 8;
+ u32 A6_byte : 8;
+ u32 Enable_bit : 1;
+ u32 HighAB_bit : 1;
+ u32 reserved : 6;
+ } mac_low_reg_318;
+
+ struct {
+ u32 A1_byte : 8;
+ u32 A2_byte : 8;
+ u32 A3_byte : 8;
+ u32 reserved : 8;
+ } mac_high_reg_31c;
+
+ struct {
+ u32 reserved :16;
+ u32 data_Tag_ID :16;
+ } data_tag_400;
+
+ struct {
+ u32 Card_IDbyte6 : 8;
+ u32 Card_IDbyte5 : 8;
+ u32 Card_IDbyte4 : 8;
+ u32 Card_IDbyte3 : 8;
+ } card_id_408;
+
+ struct {
+ u32 Card_IDbyte2 : 8;
+ u32 Card_IDbyte1 : 8;
+ } card_id_40c;
+
+ struct {
+ u32 MAC1 : 8;
+ u32 MAC2 : 8;
+ u32 MAC3 : 8;
+ u32 MAC6 : 8;
+ } mac_address_418;
+
+ struct {
+ u32 MAC7 : 8;
+ u32 MAC8 : 8;
+ u32 reserved :16;
+ } mac_address_41c;
+
+ struct {
+ u32 transmitter_data_byte : 8;
+ u32 ReceiveDataReady : 1;
+ u32 ReceiveByteFrameError : 1;
+ u32 txbuffempty : 1;
+ u32 reserved :21;
+ } ci_600;
+
+ struct {
+ u32 pi_d : 8;
+ u32 pi_ha :20;
+ u32 pi_rw : 1;
+ u32 pi_component_reg : 3;
+ } pi_604;
+
+ struct {
+ u32 serialReset : 1;
+ u32 oncecycle_read : 1;
+ u32 Timer_Read_req : 1;
+ u32 Timer_Load_req : 1;
+ u32 timer_data : 7;
+ u32 unused : 1;
+ u32 Timer_addr : 5;
+ u32 reserved : 3;
+ u32 pcmcia_a_mod_pwr_n : 1;
+ u32 pcmcia_b_mod_pwr_n : 1;
+ u32 config_Done_stat : 1;
+ u32 config_Init_stat : 1;
+ u32 config_Prog_n : 1;
+ u32 config_wr_n : 1;
+ u32 config_cs_n : 1;
+ u32 config_cclk : 1;
+ u32 pi_CiMax_IRQ_n : 1;
+ u32 pi_timeout_status : 1;
+ u32 pi_wait_n : 1;
+ u32 pi_busy_n : 1;
+ } pi_608;
+
+ struct {
+ u32 PID :13;
+ u32 key_enable : 1;
+ u32 key_code : 2;
+ u32 key_array_col : 3;
+ u32 key_array_row : 5;
+ u32 dvb_en : 1;
+ u32 rw_flag : 1;
+ u32 reserved : 6;
+ } dvb_reg_60c;
+
+ struct {
+ u32 sram_addr :15;
+ u32 sram_rw : 1;
+ u32 sram_data : 8;
+ u32 sc_xfer_bit : 1;
+ u32 reserved1 : 3;
+ u32 oe_pin_reg : 1;
+ u32 ce_pin_reg : 1;
+ u32 reserved2 : 1;
+ u32 start_sram_ibi : 1;
+ } sram_ctrl_reg_700;
+
+ struct {
+ u32 net_addr_read :16;
+ u32 net_addr_write :16;
+ } net_buf_reg_704;
+
+ struct {
+ u32 cai_read :11;
+ u32 reserved1 : 5;
+ u32 cai_write :11;
+ u32 reserved2 : 6;
+ u32 cai_cnt : 4;
+ } cai_buf_reg_708;
+
+ struct {
+ u32 cao_read :11;
+ u32 reserved1 : 5;
+ u32 cap_write :11;
+ u32 reserved2 : 6;
+ u32 cao_cnt : 4;
+ } cao_buf_reg_70c;
+
+ struct {
+ u32 media_read :11;
+ u32 reserved1 : 5;
+ u32 media_write :11;
+ u32 reserved2 : 6;
+ u32 media_cnt : 4;
+ } media_buf_reg_710;
+
+ struct {
+ u32 NET_Dest : 2;
+ u32 CAI_Dest : 2;
+ u32 CAO_Dest : 2;
+ u32 MEDIA_Dest : 2;
+ u32 net_ovflow_error : 1;
+ u32 media_ovflow_error : 1;
+ u32 cai_ovflow_error : 1;
+ u32 cao_ovflow_error : 1;
+ u32 ctrl_usb_wan : 1;
+ u32 ctrl_sramdma : 1;
+ u32 ctrl_maximumfill : 1;
+ u32 reserved :17;
+ } sram_dest_reg_714;
+
+ struct {
+ u32 net_cnt :12;
+ u32 reserved1 : 4;
+ u32 net_addr_read : 1;
+ u32 reserved2 : 3;
+ u32 net_addr_write : 1;
+ u32 reserved3 :11;
+ } net_buf_reg_718;
+
+ struct {
+ u32 wan_speed_sig : 2;
+ u32 reserved1 : 6;
+ u32 wan_wait_state : 8;
+ u32 sram_chip : 2;
+ u32 sram_memmap : 2;
+ u32 reserved2 : 4;
+ u32 wan_pkt_frame : 4;
+ u32 reserved3 : 4;
+ } wan_ctrl_reg_71c;
+} flexcop_ibi_value;
+
+#endif
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c
deleted file mode 100644
index acbc4c34f72..00000000000
--- a/drivers/media/dvb/b2c2/skystar2.c
+++ /dev/null
@@ -1,2644 +0,0 @@
-/*
- * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card
- * based on the FlexCopII by B2C2,Inc.
- *
- * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
- *
- * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl()
- * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped
- * Vincenzo Di Massa, hawk.it at tiscalinet.it
- *
- * Converted to Linux coding style
- * Misc reorganization, polishing, restyling
- * Roberto Ragusa, skystar2-c5b8 at robertoragusa dot it
- *
- * Added hardware filtering support,
- * Niklas Peinecke, peinecke at gdv.uni-hannover.de
- *
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/delay.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/version.h>
-
-#include <asm/io.h>
-
-#include "dvb_frontend.h"
-
-#include <linux/dvb/frontend.h>
-#include <linux/dvb/dmx.h>
-#include "dvb_demux.h"
-#include "dmxdev.h"
-#include "dvb_filter.h"
-#include "dvbdev.h"
-#include "demux.h"
-#include "dvb_net.h"
-#include "stv0299.h"
-#include "mt352.h"
-#include "mt312.h"
-#include "nxt2002.h"
-
-static int debug;
-static int enable_hw_filters = 2;
-
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Set debugging level (0 = default, 1 = most messages, 2 = all messages).");
-module_param(enable_hw_filters, int, 0444);
-MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters: supported values: 0 (none), 1, 2");
-
-#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
-#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0)
-
-#define SIZE_OF_BUF_DMA1 0x3ac00
-#define SIZE_OF_BUF_DMA2 0x758
-
-#define MAX_N_HW_FILTERS (6+32)
-#define N_PID_SLOTS 256
-
-struct dmaq {
- u32 bus_addr;
- u32 head;
- u32 tail;
- u32 buffer_size;
- u8 *buffer;
-};
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
-#define __iomem
-#endif
-
-struct adapter {
- struct pci_dev *pdev;
-
- u8 card_revision;
- u32 b2c2_revision;
- u32 pid_filter_max;
- u32 mac_filter_max;
- u32 irq;
- void __iomem *io_mem;
- unsigned long io_port;
- u8 mac_addr[8];
- u32 dw_sram_type;
-
- struct dvb_adapter dvb_adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dmx_frontend hw_frontend;
- struct dmx_frontend mem_frontend;
- struct i2c_adapter i2c_adap;
- struct dvb_net dvbnet;
-
- struct semaphore i2c_sem;
-
- struct dmaq dmaq1;
- struct dmaq dmaq2;
-
- u32 dma_ctrl;
- u32 dma_status;
-
- int capturing;
-
- spinlock_t lock;
-
- int useable_hw_filters;
- u16 hw_pids[MAX_N_HW_FILTERS];
- u16 pid_list[N_PID_SLOTS];
- int pid_rc[N_PID_SLOTS]; // ref counters for the pids
- int pid_count;
- int whole_bandwidth_count;
- u32 mac_filter;
-
- struct dvb_frontend* fe;
- int (*fe_sleep)(struct dvb_frontend* fe);
-};
-
-#define write_reg_dw(adapter,reg,value) writel(value, adapter->io_mem + reg)
-#define read_reg_dw(adapter,reg) readl(adapter->io_mem + reg)
-
-static void write_reg_bitfield(struct adapter *adapter, u32 reg, u32 zeromask, u32 orvalue)
-{
- u32 tmp;
-
- tmp = read_reg_dw(adapter, reg);
- tmp = (tmp & ~zeromask) | orvalue;
- write_reg_dw(adapter, reg, tmp);
-}
-
-/* i2c functions */
-static int i2c_main_write_for_flex2(struct adapter *adapter, u32 command, u8 *buf, int retries)
-{
- int i;
- u32 value;
-
- write_reg_dw(adapter, 0x100, 0);
- write_reg_dw(adapter, 0x100, command);
-
- for (i = 0; i < retries; i++) {
- value = read_reg_dw(adapter, 0x100);
-
- if ((value & 0x40000000) == 0) {
- if ((value & 0x81000000) == 0x80000000) {
- if (buf != 0)
- *buf = (value >> 0x10) & 0xff;
-
- return 1;
- }
- } else {
- write_reg_dw(adapter, 0x100, 0);
- write_reg_dw(adapter, 0x100, command);
- }
- }
-
- return 0;
-}
-
-/* device = 0x10000000 for tuner, 0x20000000 for eeprom */
-static void i2c_main_setup(u32 device, u32 chip_addr, u8 op, u8 addr, u32 value, u32 len, u32 *command)
-{
- *command = device | ((len - 1) << 26) | (value << 16) | (addr << 8) | chip_addr;
-
- if (op != 0)
- *command = *command | 0x03000000;
- else
- *command = *command | 0x01000000;
-}
-
-static int flex_i2c_read4(struct adapter *adapter, u32 device, u32 chip_addr, u16 addr, u8 *buf, u8 len)
-{
- u32 command;
- u32 value;
-
- int result, i;
-
- i2c_main_setup(device, chip_addr, 1, addr, 0, len, &command);
-
- result = i2c_main_write_for_flex2(adapter, command, buf, 100000);
-
- if ((result & 0xff) != 0) {
- if (len > 1) {
- value = read_reg_dw(adapter, 0x104);
-
- for (i = 1; i < len; i++) {
- buf[i] = value & 0xff;
- value = value >> 8;
- }
- }
- }
-
- return result;
-}
-
-static int flex_i2c_write4(struct adapter *adapter, u32 device, u32 chip_addr, u32 addr, u8 *buf, u8 len)
-{
- u32 command;
- u32 value;
- int i;
-
- if (len > 1) {
- value = 0;
-
- for (i = len; i > 1; i--) {
- value = value << 8;
- value = value | buf[i - 1];
- }
-
- write_reg_dw(adapter, 0x104, value);
- }
-
- i2c_main_setup(device, chip_addr, 0, addr, buf[0], len, &command);
-
- return i2c_main_write_for_flex2(adapter, command, NULL, 100000);
-}
-
-static void fixchipaddr(u32 device, u32 bus, u32 addr, u32 *ret)
-{
- if (device == 0x20000000)
- *ret = bus | ((addr >> 8) & 3);
- else
- *ret = bus;
-}
-
-static u32 flex_i2c_read(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
-{
- u32 chipaddr;
- u32 bytes_to_transfer;
- u8 *start;
-
- ddprintk("%s:\n", __FUNCTION__);
-
- start = buf;
-
- while (len != 0) {
- bytes_to_transfer = len;
-
- if (bytes_to_transfer > 4)
- bytes_to_transfer = 4;
-
- fixchipaddr(device, bus, addr, &chipaddr);
-
- if (flex_i2c_read4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
- return buf - start;
-
- buf = buf + bytes_to_transfer;
- addr = addr + bytes_to_transfer;
- len = len - bytes_to_transfer;
- };
-
- return buf - start;
-}
-
-static u32 flex_i2c_write(struct adapter *adapter, u32 device, u32 bus, u32 addr, u8 *buf, u32 len)
-{
- u32 chipaddr;
- u32 bytes_to_transfer;
- u8 *start;
-
- ddprintk("%s:\n", __FUNCTION__);
-
- start = buf;
-
- while (len != 0) {
- bytes_to_transfer = len;
-
- if (bytes_to_transfer > 4)
- bytes_to_transfer = 4;
-
- fixchipaddr(device, bus, addr, &chipaddr);
-
- if (flex_i2c_write4(adapter, device, chipaddr, addr, buf, bytes_to_transfer) == 0)
- return buf - start;
-
- buf = buf + bytes_to_transfer;
- addr = addr + bytes_to_transfer;
- len = len - bytes_to_transfer;
- }
-
- return buf - start;
-}
-
-static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg *msgs, int num)
-{
- struct adapter *tmp = i2c_get_adapdata(adapter);
- int i, ret = 0;
-
- if (down_interruptible(&tmp->i2c_sem))
- return -ERESTARTSYS;
-
- ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
-
- for (i = 0; i < num; i++) {
- ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
- msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
- }
-
- // read command
- if ((num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && (msgs[0].buf != NULL) && (msgs[1].buf != NULL)) {
-
- ret = flex_i2c_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len);
-
- up(&tmp->i2c_sem);
-
- if (ret != msgs[1].len) {
- dprintk("%s: read error !\n", __FUNCTION__);
-
- for (i = 0; i < 2; i++) {
- dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
- msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
- }
-
- return -EREMOTEIO;
- }
-
- return num;
- }
- // write command
- for (i = 0; i < num; i++) {
-
- if ((msgs[i].flags != 0) || (msgs[i].buf == NULL) || (msgs[i].len < 2))
- return -EINVAL;
-
- ret = flex_i2c_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1);
-
- up(&tmp->i2c_sem);
-
- if (ret != msgs[0].len - 1) {
- dprintk("%s: write error %i !\n", __FUNCTION__, ret);
-
- dprintk("message %d: flags=0x%x, addr=0x%x, buf[0]=0x%x, len=%d \n", i,
- msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
-
- return -EREMOTEIO;
- }
-
- return num;
- }
-
- printk("%s: unknown command format !\n", __FUNCTION__);
-
- return -EINVAL;
-}
-
-/* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board,
- but it seems that FlexCopII can work with more than one chip) */
-static void sram_set_net_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xfffffffc) | (dest & 3);
-
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-static void sram_set_cai_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xfffffff3) | ((dest & 3) << 2);
-
- udelay(1000);
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-static void sram_set_cao_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xffffffcf) | ((dest & 3) << 4);
-
- udelay(1000);
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-static void sram_set_media_dest(struct adapter *adapter, u8 dest)
-{
- u32 tmp;
-
- udelay(1000);
-
- tmp = (read_reg_dw(adapter, 0x714) & 0xffffff3f) | ((dest & 3) << 6);
-
- udelay(1000);
- udelay(1000);
-
- write_reg_dw(adapter, 0x714, tmp);
- write_reg_dw(adapter, 0x714, tmp);
-
- udelay(1000);
-
- /* return value is never used? */
-/* return tmp; */
-}
-
-/* SRAM memory is accessed through a buffer register in the FlexCop
- chip (0x700). This register has the following structure:
- bits 0-14 : address
- bit 15 : read/write flag
- bits 16-23 : 8-bit word to write
- bits 24-27 : = 4
- bits 28-29 : memory bank selector
- bit 31 : busy flag
-*/
-static void flex_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
- int i, retries;
- u32 command;
-
- for (i = 0; i < len; i++) {
- command = bank | addr | 0x04000000 | (*buf << 0x10);
-
- retries = 2;
-
- while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
- mdelay(1);
- retries--;
- };
-
- if (retries == 0)
- printk("%s: SRAM timeout\n", __FUNCTION__);
-
- write_reg_dw(adapter, 0x700, command);
-
- buf++;
- addr++;
- }
-}
-
-static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len)
-{
- int i, retries;
- u32 command, value;
-
- for (i = 0; i < len; i++) {
- command = bank | addr | 0x04008000;
-
- retries = 10000;
-
- while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
- mdelay(1);
- retries--;
- };
-
- if (retries == 0)
- printk("%s: SRAM timeout\n", __FUNCTION__);
-
- write_reg_dw(adapter, 0x700, command);
-
- retries = 10000;
-
- while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) {
- mdelay(1);
- retries--;
- };
-
- if (retries == 0)
- printk("%s: SRAM timeout\n", __FUNCTION__);
-
- value = read_reg_dw(adapter, 0x700) >> 0x10;
-
- *buf = (value & 0xff);
-
- addr++;
- buf++;
- }
-}
-
-static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
- u32 bank;
-
- bank = 0;
-
- if (adapter->dw_sram_type == 0x20000) {
- bank = (addr & 0x18000) << 0x0d;
- }
-
- if (adapter->dw_sram_type == 0x00000) {
- if ((addr >> 0x0f) == 0)
- bank = 0x20000000;
- else
- bank = 0x10000000;
- }
-
- flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
-{
- u32 bank;
-
- bank = 0;
-
- if (adapter->dw_sram_type == 0x20000) {
- bank = (addr & 0x18000) << 0x0d;
- }
-
- if (adapter->dw_sram_type == 0x00000) {
- if ((addr >> 0x0f) == 0)
- bank = 0x20000000;
- else
- bank = 0x10000000;
- }
-
- flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
-}
-
-static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
- u32 length;
-
- while (len != 0) {
- length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is read from
- // one chip at a time.
- if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
- length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
- }
-
- sram_read_chunk(adapter, addr, buf, length);
-
- addr = addr + length;
- buf = buf + length;
- len = len - length;
- }
-}
-
-static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
-{
- u32 length;
-
- while (len != 0) {
- length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is written to
- // one chip at a time.
- if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
- length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
- }
-
- sram_write_chunk(adapter, addr, buf, length);
-
- addr = addr + length;
- buf = buf + length;
- len = len - length;
- }
-}
-
-static void sram_set_size(struct adapter *adapter, u32 mask)
-{
- write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
-}
-
-static void sram_init(struct adapter *adapter)
-{
- u32 tmp;
-
- tmp = read_reg_dw(adapter, 0x71c);
-
- write_reg_dw(adapter, 0x71c, 1);
-
- if (read_reg_dw(adapter, 0x71c) != 0) {
- write_reg_dw(adapter, 0x71c, tmp);
-
- adapter->dw_sram_type = tmp & 0x30000;
-
- ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
-
- } else {
-
- adapter->dw_sram_type = 0x10000;
-
- ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, 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", __FUNCTION__, mask, addr);
-
- sram_set_size(adapter, mask);
- sram_init(adapter);
-
- tmp2 = 0xa5;
- tmp1 = 0x4f;
-
- sram_write(adapter, addr, &tmp2, 1);
- sram_write(adapter, addr + 4, &tmp1, 1);
-
- tmp2 = 0;
-
- mdelay(20);
-
- sram_read(adapter, addr, &tmp2, 1);
- sram_read(adapter, addr, &tmp2, 1);
-
- dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2);
-
- if (tmp2 != 0xa5)
- return 0;
-
- tmp2 = 0x5a;
- tmp1 = 0xf4;
-
- sram_write(adapter, addr, &tmp2, 1);
- sram_write(adapter, addr + 4, &tmp1, 1);
-
- tmp2 = 0;
-
- mdelay(20);
-
- sram_read(adapter, addr, &tmp2, 1);
- sram_read(adapter, addr, &tmp2, 1);
-
- dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2);
-
- if (tmp2 != 0x5a)
- return 0;
-
- return 1;
-}
-
-static u32 sram_length(struct adapter *adapter)
-{
- if (adapter->dw_sram_type == 0x10000)
- return 32768; // 32K
- if (adapter->dw_sram_type == 0x00000)
- return 65536; // 64K
- if (adapter->dw_sram_type == 0x20000)
- return 131072; // 128K
-
- return 32768; // 32K
-}
-
-/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
- - for 128K there are 4x32K chips at bank 0,1,2,3.
- - for 64K there are 2x32K chips at bank 1,2.
- - for 32K there is one 32K chip at bank 0.
-
- FlexCop works only with one bank at a time. The bank is selected
- by bits 28-29 of the 0x700 register.
-
- bank 0 covers addresses 0x00000-0x07fff
- bank 1 covers addresses 0x08000-0x0ffff
- bank 2 covers addresses 0x10000-0x17fff
- bank 3 covers addresses 0x18000-0x1ffff
-*/
-static int sram_detect_for_flex2(struct adapter *adapter)
-{
- u32 tmp, tmp2, tmp3;
-
- dprintk("%s:\n", __FUNCTION__);
-
- tmp = read_reg_dw(adapter, 0x208);
- write_reg_dw(adapter, 0x208, 0);
-
- tmp2 = read_reg_dw(adapter, 0x71c);
-
- dprintk("%s: tmp2 = %x\n", __FUNCTION__, tmp2);
-
- write_reg_dw(adapter, 0x71c, 1);
-
- tmp3 = read_reg_dw(adapter, 0x71c);
-
- dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3);
-
- write_reg_dw(adapter, 0x71c, tmp2);
-
- // check for internal SRAM ???
- tmp3--;
- if (tmp3 != 0) {
- sram_set_size(adapter, 0x10000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 32K\n", __FUNCTION__);
-
- return 32;
- }
-
- if (sram_test_location(adapter, 0x20000, 0x18000) != 0) {
- sram_set_size(adapter, 0x20000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 128K\n", __FUNCTION__);
-
- return 128;
- }
-
- if (sram_test_location(adapter, 0x00000, 0x10000) != 0) {
- sram_set_size(adapter, 0x00000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 64K\n", __FUNCTION__);
-
- return 64;
- }
-
- if (sram_test_location(adapter, 0x10000, 0x00000) != 0) {
- sram_set_size(adapter, 0x10000);
- sram_init(adapter);
- write_reg_dw(adapter, 0x208, tmp);
-
- dprintk("%s: sram size = 32K\n", __FUNCTION__);
-
- 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", __FUNCTION__);
-
- return 0;
-}
-
-static void sll_detect_sram_size(struct adapter *adapter)
-{
- sram_detect_for_flex2(adapter);
-}
-
-/* EEPROM (Skystar2 has one "24LC08B" chip on board) */
-/*
-static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
- return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-*/
-
-static int eeprom_read(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
-{
- return flex_i2c_read(adapter, 0x20000000, 0x50, addr, buf, len);
-}
-
-static u8 calc_lrc(u8 *buf, int len)
-{
- int i;
- u8 sum;
-
- sum = 0;
-
- for (i = 0; i < len; i++)
- sum = sum ^ buf[i];
-
- return sum;
-}
-
-static int eeprom_lrc_read(struct adapter *adapter, u32 addr, u32 len, u8 *buf, int retries)
-{
- int i;
-
- for (i = 0; i < retries; i++) {
- if (eeprom_read(adapter, addr, buf, len) == len) {
- if (calc_lrc(buf, len - 1) == buf[len - 1])
- return 1;
- }
- }
-
- return 0;
-}
-
-/*
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
-{
- int i;
-
- for (i = 0; i < retries; i++) {
- if (eeprom_write(adapter, addr, wbuf, len) == len) {
- if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
- return 1;
- }
- }
-
- return 0;
-}
-*/
-
-
-/* These functions could be used to unlock SkyStar2 cards. */
-
-/*
-static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
-{
- u8 rbuf[20];
- u8 wbuf[20];
-
- if (len != 16)
- return 0;
-
- memcpy(wbuf, key, len);
-
- wbuf[16] = 0;
- wbuf[17] = 0;
- wbuf[18] = 0;
- wbuf[19] = calc_lrc(wbuf, 19);
-
- return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
-}
-
-static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
-{
- u8 buf[20];
-
- if (len != 16)
- return 0;
-
- if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0)
- return 0;
-
- memcpy(key, buf, len);
-
- return 1;
-}
-*/
-
-static int eeprom_get_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
- u8 tmp[8];
-
- if (eeprom_lrc_read(adapter, 0x3f8, 8, tmp, 4) != 0) {
- if (type != 0) {
- mac[0] = tmp[0];
- mac[1] = tmp[1];
- mac[2] = tmp[2];
- mac[3] = 0xfe;
- mac[4] = 0xff;
- mac[5] = tmp[3];
- mac[6] = tmp[4];
- mac[7] = tmp[5];
-
- } else {
-
- mac[0] = tmp[0];
- mac[1] = tmp[1];
- mac[2] = tmp[2];
- mac[3] = tmp[3];
- mac[4] = tmp[4];
- mac[5] = tmp[5];
- }
-
- return 1;
-
- } else {
-
- if (type == 0) {
- memset(mac, 0, 6);
-
- } else {
-
- memset(mac, 0, 8);
- }
-
- return 0;
- }
-}
-
-/*
-static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
-{
- u8 tmp[8];
-
- if (type != 0) {
- tmp[0] = mac[0];
- tmp[1] = mac[1];
- tmp[2] = mac[2];
- tmp[3] = mac[5];
- tmp[4] = mac[6];
- tmp[5] = mac[7];
-
- } else {
-
- tmp[0] = mac[0];
- tmp[1] = mac[1];
- tmp[2] = mac[2];
- tmp[3] = mac[3];
- tmp[4] = mac[4];
- tmp[5] = mac[5];
- }
-
- tmp[6] = 0;
- tmp[7] = calc_lrc(tmp, 7);
-
- if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
- return 1;
-
- return 0;
-}
-*/
-
-/* PID filter */
-
-/* every flexcop has 6 "lower" hw PID filters */
-/* these are enabled by setting bits 0-5 of 0x208 */
-/* for the 32 additional filters we have to select one */
-/* of them through 0x310 and modify through 0x314 */
-/* op: 0=disable, 1=enable */
-static void filter_enable_hw_filter(struct adapter *adapter, int id, u8 op)
-{
- dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
- if (id <= 5) {
- u32 mask = (0x00000001 << id);
- write_reg_bitfield(adapter, 0x208, mask, op ? mask : 0);
- } else {
- /* select */
- write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
- /* modify */
- write_reg_bitfield(adapter, 0x314, 0x00006000, op ? 0x00004000 : 0);
- }
-}
-
-/* this sets the PID that should pass the specified filter */
-static void pid_set_hw_pid(struct adapter *adapter, int id, u16 pid)
-{
- dprintk("%s: id=%d pid=%d\n", __FUNCTION__, id, pid);
- if (id <= 5) {
- u32 adr = 0x300 + ((id & 6) << 1);
- int shift = (id & 1) ? 16 : 0;
- dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id & 1) ? 'h' : 'l', pid);
- write_reg_bitfield(adapter, adr, (0x7fff) << shift, (pid & 0x1fff) << shift);
- } else {
- /* select */
- write_reg_bitfield(adapter, 0x310, 0x1f, (id - 6) & 0x1f);
- /* modify */
- write_reg_bitfield(adapter, 0x314, 0x1fff, pid & 0x1fff);
- }
-}
-
-
-/*
-static void filter_enable_null_filter(struct adapter *adapter, u32 op)
-{
- dprintk("%s: op=%x\n", __FUNCTION__, op);
-
- write_reg_bitfield(adapter, 0x208, 0x00000040, op?0x00000040:0);
-}
-*/
-
-static void filter_enable_mask_filter(struct adapter *adapter, u32 op)
-{
- dprintk("%s: op=%x\n", __FUNCTION__, op);
-
- write_reg_bitfield(adapter, 0x208, 0x00000080, op ? 0x00000080 : 0);
-}
-
-
-static void ctrl_enable_mac(struct adapter *adapter, u32 op)
-{
- write_reg_bitfield(adapter, 0x208, 0x00004000, op ? 0x00004000 : 0);
-}
-
-static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 *mac)
-{
- u32 tmp1, tmp2;
-
- tmp1 = (mac[3] << 0x18) | (mac[2] << 0x10) | (mac[1] << 0x08) | mac[0];
- tmp2 = (mac[5] << 0x08) | mac[4];
-
- write_reg_dw(adapter, 0x418, tmp1);
- write_reg_dw(adapter, 0x41c, tmp2);
-
- return 0;
-}
-
-/*
-static void set_ignore_mac_filter(struct adapter *adapter, u8 op)
-{
- if (op != 0) {
- write_reg_bitfield(adapter, 0x208, 0x00004000, 0);
- adapter->mac_filter = 1;
- } else {
- if (adapter->mac_filter != 0) {
- adapter->mac_filter = 0;
- write_reg_bitfield(adapter, 0x208, 0x00004000, 0x00004000);
- }
- }
-}
-*/
-
-/*
-static void check_null_filter_enable(struct adapter *adapter)
-{
- filter_enable_null_filter(adapter, 1);
- filter_enable_mask_filter(adapter, 1);
-}
-*/
-
-static void pid_set_group_pid(struct adapter *adapter, u16 pid)
-{
- u32 value;
-
- dprintk("%s: pid=%x\n", __FUNCTION__, pid);
- value = (pid & 0x3fff) | (read_reg_dw(adapter, 0x30c) & 0xffff0000);
- write_reg_dw(adapter, 0x30c, value);
-}
-
-static void pid_set_group_mask(struct adapter *adapter, u16 pid)
-{
- u32 value;
-
- dprintk("%s: pid=%x\n", __FUNCTION__, pid);
- value = ((pid & 0x3fff) << 0x10) | (read_reg_dw(adapter, 0x30c) & 0xffff);
- write_reg_dw(adapter, 0x30c, value);
-}
-
-/*
-static int pid_get_group_pid(struct adapter *adapter)
-{
- return read_reg_dw(adapter, 0x30c) & 0x00001fff;
-}
-
-static int pid_get_group_mask(struct adapter *adapter)
-{
- return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;
-}
-*/
-
-/*
-static void reset_hardware_pid_filter(struct adapter *adapter)
-{
- pid_set_stream1_pid(adapter, 0x1fff);
-
- pid_set_stream2_pid(adapter, 0x1fff);
- filter_enable_stream2_filter(adapter, 0);
-
- pid_set_pcr_pid(adapter, 0x1fff);
- filter_enable_pcr_filter(adapter, 0);
-
- pid_set_pmt_pid(adapter, 0x1fff);
- filter_enable_pmt_filter(adapter, 0);
-
- pid_set_ecm_pid(adapter, 0x1fff);
- filter_enable_ecm_filter(adapter, 0);
-
- pid_set_emm_pid(adapter, 0x1fff);
- filter_enable_emm_filter(adapter, 0);
-}
-*/
-
-static void init_pids(struct adapter *adapter)
-{
- int i;
-
- adapter->pid_count = 0;
- adapter->whole_bandwidth_count = 0;
- for (i = 0; i < adapter->useable_hw_filters; i++) {
- dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i);
- adapter->hw_pids[i] = 0x1fff;
- pid_set_hw_pid(adapter, i, 0x1fff);
-}
-
- pid_set_group_pid(adapter, 0);
- pid_set_group_mask(adapter, 0x1fe0);
-}
-
-static void open_whole_bandwidth(struct adapter *adapter)
-{
- dprintk("%s:\n", __FUNCTION__);
- pid_set_group_pid(adapter, 0);
- pid_set_group_mask(adapter, 0);
-/*
- filter_enable_mask_filter(adapter, 1);
-*/
-}
-
-static void close_whole_bandwidth(struct adapter *adapter)
-{
- dprintk("%s:\n", __FUNCTION__);
- pid_set_group_pid(adapter, 0);
- pid_set_group_mask(adapter, 0x1fe0);
-/*
- filter_enable_mask_filter(adapter, 1);
-*/
-}
-
-static void whole_bandwidth_inc(struct adapter *adapter)
-{
- if (adapter->whole_bandwidth_count++ == 0)
- open_whole_bandwidth(adapter);
-}
-
-static void whole_bandwidth_dec(struct adapter *adapter)
-{
- if (--adapter->whole_bandwidth_count <= 0)
- close_whole_bandwidth(adapter);
-}
-
-/* The specified PID has to be let through the
- hw filters.
- We try to allocate an hardware filter and open whole
- bandwidth when allocation is impossible.
- All pids<=0x1f pass through the group filter.
- Returns 1 on success, -1 on error */
-static int add_hw_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid <= 0x1f)
- return 1;
-
- /* we can't use a filter for 0x2000, so no search */
- if (pid != 0x2000) {
- /* find an unused hardware filter */
- for (i = 0; i < adapter->useable_hw_filters; i++) {
- dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
- if (adapter->hw_pids[i] == 0x1fff) {
- dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
- adapter->hw_pids[i] = pid;
- pid_set_hw_pid(adapter, i, pid);
- filter_enable_hw_filter(adapter, i, 1);
- return 1;
- }
- }
- }
- /* if we have not used a filter, this pid depends on whole bandwidth */
- dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
- whole_bandwidth_inc(adapter);
- return 1;
- }
-
-/* returns -1 if the pid was not present in the filters */
-static int remove_hw_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid <= 0x1f)
- return 1;
-
- /* we can't use a filter for 0x2000, so no search */
- if (pid != 0x2000) {
- for (i = 0; i < adapter->useable_hw_filters; i++) {
- dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i);
- if (adapter->hw_pids[i] == pid) { // find the pid slot
- dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i);
- adapter->hw_pids[i] = 0x1fff;
- pid_set_hw_pid(adapter, i, 0x1fff);
- filter_enable_hw_filter(adapter, i, 0);
- return 1;
- }
- }
- }
- /* if we have not used a filter, this pid depended on whole bandwith */
- dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid);
- whole_bandwidth_dec(adapter);
- return 1;
- }
-
-/* Adds a PID to the filters.
- Adding a pid more than once is possible, we keep reference counts.
- Whole stream available through pid==0x2000.
- Returns 1 on success, -1 on error */
-static int add_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid > 0x1ffe && pid != 0x2000)
- return -1;
-
- // check if the pid is already present
- for (i = 0; i < adapter->pid_count; i++)
- if (adapter->pid_list[i] == pid) {
- adapter->pid_rc[i]++; // increment ref counter
- return 1;
- }
-
- if (adapter->pid_count == N_PID_SLOTS)
- return -1; // no more pids can be added
- adapter->pid_list[adapter->pid_count] = pid; // register pid
- adapter->pid_rc[adapter->pid_count] = 1;
- adapter->pid_count++;
- // hardware setting
- add_hw_pid(adapter, pid);
-
- return 1;
- }
-
-/* Removes a PID from the filters. */
-static int remove_pid(struct adapter *adapter, u16 pid)
-{
- int i;
-
- dprintk("%s: pid=%d\n", __FUNCTION__, pid);
-
- if (pid > 0x1ffe && pid != 0x2000)
- return -1;
-
- // check if the pid is present (it must be!)
- for (i = 0; i < adapter->pid_count; i++) {
- if (adapter->pid_list[i] == pid) {
- adapter->pid_rc[i]--;
- if (adapter->pid_rc[i] <= 0) {
- // remove from the list
- adapter->pid_count--;
- adapter->pid_list[i]=adapter->pid_list[adapter->pid_count];
- adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count];
- // hardware setting
- remove_hw_pid(adapter, pid);
- }
- return 1;
- }
- }
-
- return -1;
-}
-
-
-/* dma & irq */
-static void ctrl_enable_smc(struct adapter *adapter, u32 op)
-{
- write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);
-}
-
-static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3)
-{
- adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000;
-
- if (flag1 == 0) {
- if (flag2 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000;
-
- if (flag3 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000;
-
- } else {
-
- if (flag2 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000;
-
- if (flag3 == 0)
- adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000;
- else
- adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000;
- }
-}
-
-static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op)
-{
- u32 value;
-
- value = read_reg_dw(adapter, 0x208) & 0xfff0ffff;
-
- if (op != 0)
- value = value | (adapter->dma_ctrl & 0x000f0000);
-
- write_reg_dw(adapter, 0x208, value);
-}
-
-/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to
- system memory.
-
- The DMA1 buffer is divided in 2 subbuffers of equal size.
- FlexCopII will transfer TS data to one subbuffer, signal an interrupt
- when the subbuffer is full and continue fillig the second subbuffer.
-
- For DMA1:
- subbuffer size in 32-bit words is stored in the first 24 bits of
- register 0x004. The last 8 bits of register 0x004 contain the number
- of subbuffers.
-
- the first 30 bits of register 0x000 contain the address of the first
- subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
- when dma1 is enabled.
-
- the first 30 bits of register 0x00c contain the address of the second
- subbuffer. the last 2 bits contain 1.
-
- register 0x008 will contain the address of the subbuffer that was filled
- with TS data, when FlexCopII will generate an interrupt.
-
- For DMA2:
- subbuffer size in 32-bit words is stored in the first 24 bits of
- register 0x014. The last 8 bits of register 0x014 contain the number
- of subbuffers.
-
- the first 30 bits of register 0x010 contain the address of the first
- subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1,
- when dma1 is enabled.
-
- the first 30 bits of register 0x01c contain the address of the second
- subbuffer. the last 2 bits contain 1.
-
- register 0x018 contains the address of the subbuffer that was filled
- with TS data, when FlexCopII generates an interrupt.
-*/
-static int dma_init_dma(struct adapter *adapter, u32 dma_channel)
-{
- u32 subbuffers, subbufsize, subbuf0, subbuf1;
-
- if (dma_channel == 0) {
- dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__);
-
- subbuffers = 2;
-
- subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers;
-
- subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc;
-
- subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1;
-
- dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
- udelay(1000);
- write_reg_dw(adapter, 0x000, subbuf0);
-
- dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
- udelay(1000);
- write_reg_dw(adapter, 0x004, subbufsize);
-
- dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1);
- udelay(1000);
- write_reg_dw(adapter, 0x00c, subbuf1);
-
- dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc);
- write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc);
- udelay(1000);
-
- dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0);
-
- irq_dma_enable_disable_irq(adapter, 1);
-
- sram_set_media_dest(adapter, 1);
- sram_set_net_dest(adapter, 1);
- sram_set_cai_dest(adapter, 2);
- sram_set_cao_dest(adapter, 2);
- }
-
- if (dma_channel == 1) {
- dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__);
-
- subbuffers = 2;
-
- subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers;
-
- subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc;
-
- subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1;
-
- dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0);
- udelay(1000);
- write_reg_dw(adapter, 0x010, subbuf0);
-
- dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4);
- udelay(1000);
- write_reg_dw(adapter, 0x014, subbufsize);
-
- dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1);
- udelay(1000);
- write_reg_dw(adapter, 0x01c, subbuf1);
-
- sram_set_cai_dest(adapter, 2);
- }
-
- return 0;
-}
-
-static void ctrl_enable_receive_data(struct adapter *adapter, u32 op)
-{
- if (op == 0) {
- write_reg_bitfield(adapter, 0x208, 0x00008000, 0);
- adapter->dma_status = adapter->dma_status & ~0x00000004;
- } else {
- write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000);
- adapter->dma_status = adapter->dma_status | 0x00000004;
- }
-}
-
-/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled
- bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled
-*/
-static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop)
-{
- u32 dma_enable, dma1_enable, dma2_enable;
-
- dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask);
-
- if (start_stop == 1) {
- dprintk("%s: starting dma\n", __FUNCTION__);
-
- dma1_enable = 0;
- dma2_enable = 0;
-
- if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) {
- adapter->dma_status = adapter->dma_status | 1;
- dma1_enable = 1;
- }
-
- if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) {
- adapter->dma_status = adapter->dma_status | 2;
- dma2_enable = 1;
- }
- // enable dma1 and dma2
- if ((dma1_enable == 1) && (dma2_enable == 1)) {
- write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
- write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
- write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
- // enable dma1
- if ((dma1_enable == 1) && (dma2_enable == 0)) {
- write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1);
- write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
- // enable dma2
- if ((dma1_enable == 0) && (dma2_enable == 1)) {
- write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1);
-
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
- // start dma
- if ((dma1_enable == 0) && (dma2_enable == 0)) {
- ctrl_enable_receive_data(adapter, 1);
-
- return;
- }
-
- } else {
-
- dprintk("%s: stopping dma\n", __FUNCTION__);
-
- dma_enable = adapter->dma_status & 0x00000003;
-
- if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) {
- dma_enable = dma_enable & 0xfffffffe;
- }
-
- if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) {
- dma_enable = dma_enable & 0xfffffffd;
- }
- //stop dma
- if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) {
- ctrl_enable_receive_data(adapter, 0);
-
- udelay(3000);
- }
- //disable dma1
- if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) {
- write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr);
- write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1);
-
- adapter->dma_status = adapter->dma_status & ~0x00000001;
- }
- //disable dma2
- if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) {
- write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr);
-
- adapter->dma_status = adapter->dma_status & ~0x00000002;
- }
- }
-}
-
-static void open_stream(struct adapter *adapter, u16 pid)
-{
- u32 dma_mask;
-
- ++adapter->capturing;
-
- filter_enable_mask_filter(adapter, 1);
-
- add_pid(adapter, pid);
-
- dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-
- if ((adapter->dma_status & 7) != 7) {
- dma_mask = 0;
-
- if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) {
- dma_mask = dma_mask | 1;
-
- adapter->dmaq1.head = 0;
- adapter->dmaq1.tail = 0;
-
- memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size);
- }
-
- if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) {
- dma_mask = dma_mask | 2;
-
- adapter->dmaq2.head = 0;
- adapter->dmaq2.tail = 0;
- }
-
- if (dma_mask != 0) {
- irq_dma_enable_disable_irq(adapter, 1);
-
- dma_start_stop(adapter, dma_mask, 1);
- }
- }
-}
-
-static void close_stream(struct adapter *adapter, u16 pid)
-{
- if (adapter->capturing > 0)
- --adapter->capturing;
-
- dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status);
-
- if (adapter->capturing == 0) {
- u32 dma_mask = 0;
-
- if ((adapter->dma_status & 1) != 0)
- dma_mask = dma_mask | 0x00000001;
- if ((adapter->dma_status & 2) != 0)
- dma_mask = dma_mask | 0x00000002;
-
- if (dma_mask != 0) {
- dma_start_stop(adapter, dma_mask, 0);
- }
- }
- remove_pid(adapter, pid);
-}
-
-static void interrupt_service_dma1(struct adapter *adapter)
-{
- struct dvb_demux *dvbdmx = &adapter->demux;
-
- int n_cur_dma_counter;
- u32 n_num_bytes_parsed;
- u32 n_num_new_bytes_transferred;
- u32 dw_default_packet_size = 188;
- u8 gb_tmp_buffer[188];
- u8 *pb_dma_buf_cur_pos;
-
- n_cur_dma_counter = readl(adapter->io_mem + 0x008) - adapter->dmaq1.bus_addr;
- n_cur_dma_counter = (n_cur_dma_counter / dw_default_packet_size) * dw_default_packet_size;
-
- if ((n_cur_dma_counter < 0) || (n_cur_dma_counter > adapter->dmaq1.buffer_size)) {
- dprintk("%s: dma counter outside dma buffer\n", __FUNCTION__);
- return;
- }
-
- adapter->dmaq1.head = n_cur_dma_counter;
-
- if (adapter->dmaq1.tail <= n_cur_dma_counter) {
- n_num_new_bytes_transferred = n_cur_dma_counter - adapter->dmaq1.tail;
-
- } else {
-
- n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
- }
-
- ddprintk("%s: n_cur_dma_counter = %d\n", __FUNCTION__, n_cur_dma_counter);
- ddprintk("%s: dmaq1.tail = %d\n", __FUNCTION__, adapter->dmaq1.tail);
- ddprintk("%s: bytes_transferred = %d\n", __FUNCTION__, n_num_new_bytes_transferred);
-
- if (n_num_new_bytes_transferred < dw_default_packet_size)
- return;
-
- n_num_bytes_parsed = 0;
-
- while (n_num_bytes_parsed < n_num_new_bytes_transferred) {
- pb_dma_buf_cur_pos = adapter->dmaq1.buffer + adapter->dmaq1.tail;
-
- if (adapter->dmaq1.buffer + adapter->dmaq1.buffer_size < adapter->dmaq1.buffer + adapter->dmaq1.tail + 188) {
- memcpy(gb_tmp_buffer, adapter->dmaq1.buffer + adapter->dmaq1.tail,
- adapter->dmaq1.buffer_size - adapter->dmaq1.tail);
- memcpy(gb_tmp_buffer + (adapter->dmaq1.buffer_size - adapter->dmaq1.tail), adapter->dmaq1.buffer,
- (188 - (adapter->dmaq1.buffer_size - adapter->dmaq1.tail)));
-
- pb_dma_buf_cur_pos = gb_tmp_buffer;
- }
-
- if (adapter->capturing != 0) {
- dvb_dmx_swfilter_packets(dvbdmx, pb_dma_buf_cur_pos, dw_default_packet_size / 188);
- }
-
- n_num_bytes_parsed = n_num_bytes_parsed + dw_default_packet_size;
-
- adapter->dmaq1.tail = adapter->dmaq1.tail + dw_default_packet_size;
-
- if (adapter->dmaq1.tail >= adapter->dmaq1.buffer_size)
- adapter->dmaq1.tail = adapter->dmaq1.tail - adapter->dmaq1.buffer_size;
- };
-}
-
-static void interrupt_service_dma2(struct adapter *adapter)
-{
- printk("%s:\n", __FUNCTION__);
-}
-
-static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs)
-{
- struct adapter *tmp = dev_id;
-
- u32 value;
-
- ddprintk("%s:\n", __FUNCTION__);
-
- spin_lock_irq(&tmp->lock);
-
- if (0 == ((value = read_reg_dw(tmp, 0x20c)) & 0x0f)) {
- spin_unlock_irq(&tmp->lock);
- return IRQ_NONE;
- }
-
- while (value != 0) {
- if ((value & 0x03) != 0)
- interrupt_service_dma1(tmp);
- if ((value & 0x0c) != 0)
- interrupt_service_dma2(tmp);
- value = read_reg_dw(tmp, 0x20c) & 0x0f;
- }
-
- spin_unlock_irq(&tmp->lock);
- return IRQ_HANDLED;
-}
-
-static int init_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq,
- int size, int dmaq_offset)
-{
- struct pci_dev *pdev = adapter->pdev;
- dma_addr_t dma_addr;
-
- dmaq->head = 0;
- dmaq->tail = 0;
-
- dmaq->buffer = pci_alloc_consistent(pdev, size + 0x80, &dma_addr);
- if (!dmaq->buffer)
- return -ENOMEM;
-
- dmaq->bus_addr = dma_addr;
- dmaq->buffer_size = size;
-
- dma_init_dma(adapter, dmaq_offset);
-
- ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n",
- __FUNCTION__, dmaq->buffer, size);
-
- return 0;
- }
-
-static int init_dma_queue(struct adapter *adapter)
-{
- struct {
- struct dmaq *dmaq;
- u32 dma_status;
- int size;
- } dmaq_desc[] = {
- { &adapter->dmaq1, 0x10000000, SIZE_OF_BUF_DMA1 },
- { &adapter->dmaq2, 0x20000000, SIZE_OF_BUF_DMA2 }
- }, *p = dmaq_desc;
- int i;
-
- for (i = 0; i < 2; i++, p++) {
- if (init_dma_queue_one(adapter, p->dmaq, p->size, i) < 0)
- adapter->dma_status &= ~p->dma_status;
- else
- adapter->dma_status |= p->dma_status;
- }
- return (adapter->dma_status & 0x30000000) ? 0 : -ENOMEM;
-}
-
-static void free_dma_queue_one(struct adapter *adapter, struct dmaq *dmaq)
-{
- if (dmaq->buffer) {
- pci_free_consistent(adapter->pdev, dmaq->buffer_size + 0x80,
- dmaq->buffer, dmaq->bus_addr);
- memset(dmaq, 0, sizeof(*dmaq));
- }
-}
-
-static void free_dma_queue(struct adapter *adapter)
-{
- struct dmaq *dmaq[] = {
- &adapter->dmaq1,
- &adapter->dmaq2,
- NULL
- }, **p;
-
- for (p = dmaq; *p; p++)
- free_dma_queue_one(adapter, *p);
- }
-
-static void release_adapter(struct adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
-
- iounmap(adapter->io_mem);
- pci_disable_device(pdev);
- pci_release_region(pdev, 0);
- pci_release_region(pdev, 1);
-}
-
-static void free_adapter_object(struct adapter *adapter)
-{
- dprintk("%s:\n", __FUNCTION__);
-
- close_stream(adapter, 0);
- free_irq(adapter->irq, adapter);
- free_dma_queue(adapter);
- release_adapter(adapter);
- kfree(adapter);
-}
-
-static struct pci_driver skystar2_pci_driver;
-
-static int claim_adapter(struct adapter *adapter)
-{
- struct pci_dev *pdev = adapter->pdev;
- u16 var;
- int ret;
-
- ret = pci_request_region(pdev, 1, skystar2_pci_driver.name);
- if (ret < 0)
- goto out;
-
- ret = pci_request_region(pdev, 0, skystar2_pci_driver.name);
- if (ret < 0)
- goto err_pci_release_1;
-
- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &adapter->card_revision);
-
- dprintk("%s: card revision %x \n", __FUNCTION__, adapter->card_revision);
-
- ret = pci_enable_device(pdev);
- if (ret < 0)
- goto err_pci_release_0;
-
- pci_read_config_word(pdev, 4, &var);
-
- if ((var & 4) == 0)
- pci_set_master(pdev);
-
- adapter->io_port = pdev->resource[1].start;
-
- adapter->io_mem = ioremap(pdev->resource[0].start, 0x800);
-
- if (!adapter->io_mem) {
- dprintk("%s: can not map io memory\n", __FUNCTION__);
- ret = -EIO;
- goto err_pci_disable;
- }
-
- dprintk("%s: io memory maped at %p\n", __FUNCTION__, adapter->io_mem);
-
- ret = 1;
-out:
- return ret;
-
-err_pci_disable:
- pci_disable_device(pdev);
-err_pci_release_0:
- pci_release_region(pdev, 0);
-err_pci_release_1:
- pci_release_region(pdev, 1);
- goto out;
-}
-
-/*
-static int sll_reset_flexcop(struct adapter *adapter)
-{
- write_reg_dw(adapter, 0x208, 0);
- write_reg_dw(adapter, 0x210, 0xb2ff);
-
- return 0;
-}
-*/
-
-static void decide_how_many_hw_filters(struct adapter *adapter)
-{
- int hw_filters;
- int mod_option_hw_filters;
-
- // FlexCop IIb & III have 6+32 hw filters
- // FlexCop II has 6 hw filters, every other should have at least 6
- switch (adapter->b2c2_revision) {
- case 0x82: /* II */
- hw_filters = 6;
- break;
- case 0xc3: /* IIB */
- hw_filters = 6 + 32;
- break;
- case 0xc0: /* III */
- hw_filters = 6 + 32;
- break;
- default:
- hw_filters = 6;
- break;
- }
- printk("%s: the chip has %i hardware filters", __FILE__, hw_filters);
-
- mod_option_hw_filters = 0;
- if (enable_hw_filters >= 1)
- mod_option_hw_filters += 6;
- if (enable_hw_filters >= 2)
- mod_option_hw_filters += 32;
-
- if (mod_option_hw_filters >= hw_filters) {
- adapter->useable_hw_filters = hw_filters;
- } else {
- adapter->useable_hw_filters = mod_option_hw_filters;
- printk(", but only %d will be used because of module option", mod_option_hw_filters);
- }
- printk("\n");
- dprintk("%s: useable_hardware_filters set to %i\n", __FILE__, adapter->useable_hw_filters);
-}
-
-static int driver_initialize(struct pci_dev *pdev)
-{
- struct adapter *adapter;
- u32 tmp;
- int ret = -ENOMEM;
-
- adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL);
- if (!adapter) {
- dprintk("%s: out of memory!\n", __FUNCTION__);
- goto out;
- }
-
- memset(adapter, 0, sizeof(struct adapter));
-
- pci_set_drvdata(pdev,adapter);
-
- adapter->pdev = pdev;
- adapter->irq = pdev->irq;
-
- ret = claim_adapter(adapter);
- if (ret < 0)
- goto err_kfree;
-
- irq_dma_enable_disable_irq(adapter, 0);
-
- ret = request_irq(pdev->irq, isr, 0x4000000, "Skystar2", adapter);
- if (ret < 0) {
- dprintk("%s: unable to allocate irq=%d !\n", __FUNCTION__, pdev->irq);
- goto err_release_adapter;
- }
-
- read_reg_dw(adapter, 0x208);
- write_reg_dw(adapter, 0x208, 0);
- write_reg_dw(adapter, 0x210, 0xb2ff);
- write_reg_dw(adapter, 0x208, 0x40);
-
- ret = init_dma_queue(adapter);
- if (ret < 0)
- goto err_free_irq;
-
- adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
-
- switch (adapter->b2c2_revision) {
- case 0x82:
- printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
- break;
- case 0xc3:
- printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
- break;
- case 0xc0:
- printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
- break;
- default:
- printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
- printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev.192).\n", __FILE__);
- ret = -ENODEV;
- goto err_free_dma_queue;
- }
-
- decide_how_many_hw_filters(adapter);
-
- init_pids(adapter);
-
- tmp = read_reg_dw(adapter, 0x204);
-
- write_reg_dw(adapter, 0x204, 0);
- mdelay(20);
-
- write_reg_dw(adapter, 0x204, tmp);
- mdelay(10);
-
- tmp = read_reg_dw(adapter, 0x308);
- write_reg_dw(adapter, 0x308, 0x4000 | tmp);
-
- adapter->dw_sram_type = 0x10000;
-
- sll_detect_sram_size(adapter);
-
- dprintk("%s sram length = %d, sram type= %x\n", __FUNCTION__, sram_length(adapter), adapter->dw_sram_type);
-
- sram_set_media_dest(adapter, 1);
- sram_set_net_dest(adapter, 1);
-
- ctrl_enable_smc(adapter, 0);
-
- sram_set_cai_dest(adapter, 2);
- sram_set_cao_dest(adapter, 2);
-
- dma_enable_disable_irq(adapter, 1, 0, 0);
-
- if (eeprom_get_mac_addr(adapter, 0, adapter->mac_addr) != 0) {
- printk("%s MAC address = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n", __FUNCTION__, adapter->mac_addr[0],
- adapter->mac_addr[1], adapter->mac_addr[2], adapter->mac_addr[3], adapter->mac_addr[4], adapter->mac_addr[5],
- adapter->mac_addr[6], adapter->mac_addr[7]
- );
-
- ca_set_mac_dst_addr_filter(adapter, adapter->mac_addr);
- ctrl_enable_mac(adapter, 1);
- }
-
- spin_lock_init(&adapter->lock);
-
-out:
- return ret;
-
-err_free_dma_queue:
- free_dma_queue(adapter);
-err_free_irq:
- free_irq(pdev->irq, adapter);
-err_release_adapter:
- release_adapter(adapter);
-err_kfree:
- pci_set_drvdata(pdev, NULL);
- kfree(adapter);
- goto out;
-}
-
-static void driver_halt(struct pci_dev *pdev)
-{
- struct adapter *adapter = pci_get_drvdata(pdev);
-
- irq_dma_enable_disable_irq(adapter, 0);
-
- ctrl_enable_receive_data(adapter, 0);
-
- free_adapter_object(adapter);
-
- pci_set_drvdata(pdev, NULL);
-}
-
-static int dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-
- dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-
- open_stream(adapter, dvbdmxfeed->pid);
-
- return 0;
-}
-
-static int dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
-{
- struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
- struct adapter *adapter = (struct adapter *) dvbdmx->priv;
-
- dprintk("%s: PID=%d, type=%d\n", __FUNCTION__, dvbdmxfeed->pid, dvbdmxfeed->type);
-
- close_stream(adapter, dvbdmxfeed->pid);
-
- return 0;
-}
-
-/* lnb control */
-static void set_tuner_tone(struct adapter *adapter, u8 tone)
-{
- u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc };
- u16 ax;
-
- dprintk("%s: %u\n", __FUNCTION__, tone);
-
- switch (tone) {
- case 1:
- ax = wz_half_period_for_45_mhz[0];
- break;
- case 2:
- ax = wz_half_period_for_45_mhz[1];
- break;
- case 3:
- ax = wz_half_period_for_45_mhz[2];
- break;
- case 4:
- ax = wz_half_period_for_45_mhz[3];
- break;
-
- default:
- ax = 0;
- }
-
- if (ax != 0) {
- write_reg_dw(adapter, 0x200, ((ax << 0x0f) + (ax & 0x7fff)) | 0x40000000);
-
- } else {
-
- write_reg_dw(adapter, 0x200, 0x40ff8000);
- }
-}
-
-static void set_tuner_polarity(struct adapter *adapter, u8 polarity)
-{
- u32 var;
-
- dprintk("%s : polarity = %u \n", __FUNCTION__, polarity);
-
- var = read_reg_dw(adapter, 0x204);
-
- if (polarity == 0) {
- dprintk("%s: LNB power off\n", __FUNCTION__);
- var = var | 1;
- };
-
- if (polarity == 1) {
- var = var & ~1;
- var = var & ~4;
- };
-
- if (polarity == 2) {
- var = var & ~1;
- var = var | 4;
- }
-
- write_reg_dw(adapter, 0x204, var);
-}
-
-static void diseqc_send_bit(struct adapter *adapter, int data)
-{
- set_tuner_tone(adapter, 1);
- udelay(data ? 500 : 1000);
- set_tuner_tone(adapter, 0);
- udelay(data ? 1000 : 500);
-}
-
-
-static void diseqc_send_byte(struct adapter *adapter, int data)
- {
- int i, par = 1, d;
-
- for (i = 7; i >= 0; i--) {
- d = (data >> i) & 1;
- par ^= d;
- diseqc_send_bit(adapter, d);
- }
-
- diseqc_send_bit(adapter, par);
- }
-
-
-static int send_diseqc_msg(struct adapter *adapter, int len, u8 *msg, unsigned long burst)
-{
- int i;
-
- set_tuner_tone(adapter, 0);
- mdelay(16);
-
- for (i = 0; i < len; i++)
- diseqc_send_byte(adapter, msg[i]);
-
- mdelay(16);
-
- if (burst != -1) {
- if (burst)
- diseqc_send_byte(adapter, 0xff);
- else {
- set_tuner_tone(adapter, 1);
- udelay(12500);
- set_tuner_tone(adapter, 0);
- }
- msleep(20);
- }
-
- return 0;
-}
-
-static int flexcop_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- switch(tone) {
- case SEC_TONE_ON:
- set_tuner_tone(adapter, 1);
- break;
- case SEC_TONE_OFF:
- set_tuner_tone(adapter, 0);
- break;
- default:
- return -EINVAL;
- };
-
- return 0;
-}
-
-static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
- {
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- send_diseqc_msg(adapter, cmd->msg_len, cmd->msg, 0);
-
- return 0;
- }
-
-static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- send_diseqc_msg(adapter, 0, NULL, minicmd);
-
- return 0;
-}
-
-static int flexcop_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
- {
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__);
-
- switch (voltage) {
- case SEC_VOLTAGE_13:
- dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13);
- set_tuner_polarity(adapter, 1);
- return 0;
-
- case SEC_VOLTAGE_18:
- dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18);
- set_tuner_polarity(adapter, 2);
- return 0;
-
- default:
- return -EINVAL;
- }
- }
-
-static int flexcop_sleep(struct dvb_frontend* fe)
- {
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- dprintk("%s: FE_SLEEP\n", __FUNCTION__);
- set_tuner_polarity(adapter, 0);
-
- if (adapter->fe_sleep) return adapter->fe_sleep(fe);
- return 0;
- }
-
-static u32 flexcop_i2c_func(struct i2c_adapter *adapter)
- {
- printk("flexcop_i2c_func\n");
-
- return I2C_FUNC_I2C;
-}
-
-static struct i2c_algorithm flexcop_algo = {
- .name = "flexcop i2c algorithm",
- .id = I2C_ALGO_BIT,
- .master_xfer = master_xfer,
- .functionality = flexcop_i2c_func,
-};
-
-
-
-
-static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
-{
- u8 aclk = 0;
- u8 bclk = 0;
-
- if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
- else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
- else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
- else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
- else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
- else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
-
- stv0299_writereg (fe, 0x13, aclk);
- stv0299_writereg (fe, 0x14, bclk);
- stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
- stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff);
- stv0299_writereg (fe, 0x21, (ratio ) & 0xf0);
-
- return 0;
-}
-
-static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- u8 buf[4];
- u32 div;
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- div = params->frequency / 125;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = div & 0xff;
- buf[2] = 0x84; // 0xC4
- buf[3] = 0x08;
-
- if (params->frequency < 1500000) buf[3] |= 0x10;
-
- if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
- return 0;
-}
-
-static u8 samsung_tbmu24112_inittab[] = {
- 0x01, 0x15,
- 0x02, 0x30,
- 0x03, 0x00,
- 0x04, 0x7D,
- 0x05, 0x35,
- 0x06, 0x02,
- 0x07, 0x00,
- 0x08, 0xC3,
- 0x0C, 0x00,
- 0x0D, 0x81,
- 0x0E, 0x23,
- 0x0F, 0x12,
- 0x10, 0x7E,
- 0x11, 0x84,
- 0x12, 0xB9,
- 0x13, 0x88,
- 0x14, 0x89,
- 0x15, 0xC9,
- 0x16, 0x00,
- 0x17, 0x5C,
- 0x18, 0x00,
- 0x19, 0x00,
- 0x1A, 0x00,
- 0x1C, 0x00,
- 0x1D, 0x00,
- 0x1E, 0x00,
- 0x1F, 0x3A,
- 0x20, 0x2E,
- 0x21, 0x80,
- 0x22, 0xFF,
- 0x23, 0xC1,
- 0x28, 0x00,
- 0x29, 0x1E,
- 0x2A, 0x14,
- 0x2B, 0x0F,
- 0x2C, 0x09,
- 0x2D, 0x05,
- 0x31, 0x1F,
- 0x32, 0x19,
- 0x33, 0xFE,
- 0x34, 0x93,
- 0xff, 0xff,
- };
-
-static struct stv0299_config samsung_tbmu24112_config = {
- .demod_address = 0x68,
- .inittab = samsung_tbmu24112_inittab,
- .mclk = 88000000UL,
- .invert = 0,
- .enhanced_tuning = 0,
- .skip_reinit = 0,
- .lock_output = STV0229_LOCKOUTPUT_LK,
- .volt13_op0_op1 = STV0299_VOLT13_OP1,
- .min_delay_ms = 100,
- .set_symbol_rate = samsung_tbmu24112_set_symbol_rate,
- .pll_set = samsung_tbmu24112_pll_set,
-};
-
-
-
-static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- return request_firmware(fw, name, &adapter->pdev->dev);
-}
-
-
-static struct nxt2002_config samsung_tbmv_config = {
- .demod_address = 0x0A,
- .request_firmware = nxt2002_request_firmware,
-};
-
-static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe)
-{
- static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d };
- static u8 mt352_reset [] = { 0x50, 0x80 };
- static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
- static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 };
- static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
-
- mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
- udelay(2000);
- mt352_write(fe, mt352_reset, sizeof(mt352_reset));
- mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg));
-
- mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg));
- mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg));
-
- return 0;
-}
-
-static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf)
-{
- u32 div;
- unsigned char bs = 0;
-
- #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
- div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
- if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09;
- if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a;
- if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08;
-
- pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address
- pllbuf[1] = div >> 8;
- pllbuf[2] = div & 0xff;
- pllbuf[3] = 0xcc;
- pllbuf[4] = bs;
-
- return 0;
-}
-
-static struct mt352_config samsung_tdtc9251dh0_config = {
-
- .demod_address = 0x0f,
- .demod_init = samsung_tdtc9251dh0_demod_init,
- .pll_set = samsung_tdtc9251dh0_pll_set,
-};
-
-static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- u8 buf[4];
- u32 div;
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- struct adapter* adapter = (struct adapter*) fe->dvb->priv;
-
- div = (params->frequency + (125/2)) / 125;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = (div >> 0) & 0xff;
- buf[2] = 0x84 | ((div >> 10) & 0x60);
- buf[3] = 0x80;
-
- if (params->frequency < 1550000)
- buf[3] |= 0x02;
-
- if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO;
- return 0;
-}
-
-static struct mt312_config skystar23_samsung_tbdu18132_config = {
-
- .demod_address = 0x0e,
- .pll_set = skystar23_samsung_tbdu18132_pll_set,
-};
-
-
-
-
-static void frontend_init(struct adapter *skystar2)
-{
- switch(skystar2->pdev->device) {
- case 0x2103: // Technisat Skystar2 OR Technisat Airstar2 (DVB-T or ATSC)
-
- // Attempt to load the Nextwave nxt2002 for ATSC support
- skystar2->fe = nxt2002_attach(&samsung_tbmv_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe_sleep = skystar2->fe->ops->sleep;
- skystar2->fe->ops->sleep = flexcop_sleep;
- break;
- }
-
- // try the skystar2 v2.6 first (stv0299/Samsung tbmu24112(sl1935))
- skystar2->fe = stv0299_attach(&samsung_tbmu24112_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe->ops->set_voltage = flexcop_set_voltage;
- skystar2->fe_sleep = skystar2->fe->ops->sleep;
- skystar2->fe->ops->sleep = flexcop_sleep;
- break;
-}
-
- // try the airstar2 (mt352/Samsung tdtc9251dh0(??))
- skystar2->fe = mt352_attach(&samsung_tdtc9251dh0_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe->ops->info.frequency_min = 474000000;
- skystar2->fe->ops->info.frequency_max = 858000000;
- break;
- }
-
- // try the skystar2 v2.3 (vp310/Samsung tbdu18132(tsa5059))
- skystar2->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &skystar2->i2c_adap);
- if (skystar2->fe != NULL) {
- skystar2->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd;
- skystar2->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst;
- skystar2->fe->ops->set_tone = flexcop_set_tone;
- skystar2->fe->ops->set_voltage = flexcop_set_voltage;
- skystar2->fe_sleep = skystar2->fe->ops->sleep;
- skystar2->fe->ops->sleep = flexcop_sleep;
- break;
- }
- break;
- }
-
- if (skystar2->fe == NULL) {
- printk("skystar2: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
- skystar2->pdev->vendor,
- skystar2->pdev->device,
- skystar2->pdev->subsystem_vendor,
- skystar2->pdev->subsystem_device);
- } else {
- if (dvb_register_frontend(&skystar2->dvb_adapter, skystar2->fe)) {
- printk("skystar2: Frontend registration failed!\n");
- if (skystar2->fe->ops->release)
- skystar2->fe->ops->release(skystar2->fe);
- skystar2->fe = NULL;
- }
- }
-}
-
-
-static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- struct adapter *adapter;
- struct dvb_adapter *dvb_adapter;
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
- int ret = -ENODEV;
-
- if (!pdev)
- goto out;
-
- ret = driver_initialize(pdev);
- if (ret < 0)
- goto out;
-
- adapter = pci_get_drvdata(pdev);
- dvb_adapter = &adapter->dvb_adapter;
-
- ret = dvb_register_adapter(dvb_adapter, skystar2_pci_driver.name,
- THIS_MODULE);
- if (ret < 0) {
- printk("%s: Error registering DVB adapter\n", __FUNCTION__);
- goto err_halt;
- }
-
- dvb_adapter->priv = adapter;
-
-
- init_MUTEX(&adapter->i2c_sem);
-
-
- memset(&adapter->i2c_adap, 0, sizeof(struct i2c_adapter));
- strcpy(adapter->i2c_adap.name, "SkyStar2");
-
- i2c_set_adapdata(&adapter->i2c_adap, adapter);
-
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- adapter->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
- adapter->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-#endif
- adapter->i2c_adap.algo = &flexcop_algo;
- adapter->i2c_adap.algo_data = NULL;
- adapter->i2c_adap.id = I2C_ALGO_BIT;
-
- ret = i2c_add_adapter(&adapter->i2c_adap);
- if (ret < 0)
- goto err_dvb_unregister;
-
- dvbdemux = &adapter->demux;
-
- dvbdemux->priv = adapter;
- dvbdemux->filternum = N_PID_SLOTS;
- dvbdemux->feednum = N_PID_SLOTS;
- dvbdemux->start_feed = dvb_start_feed;
- dvbdemux->stop_feed = dvb_stop_feed;
- dvbdemux->write_to_decoder = NULL;
- dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
-
- ret = dvb_dmx_init(&adapter->demux);
- if (ret < 0)
- goto err_i2c_del;
-
- dmx = &dvbdemux->dmx;
-
- adapter->hw_frontend.source = DMX_FRONTEND_0;
- adapter->dmxdev.filternum = N_PID_SLOTS;
- adapter->dmxdev.demux = dmx;
- adapter->dmxdev.capabilities = 0;
-
- ret = dvb_dmxdev_init(&adapter->dmxdev, &adapter->dvb_adapter);
- if (ret < 0)
- goto err_dmx_release;
-
- ret = dmx->add_frontend(dmx, &adapter->hw_frontend);
- if (ret < 0)
- goto err_dmxdev_release;
-
- adapter->mem_frontend.source = DMX_MEMORY_FE;
-
- ret = dmx->add_frontend(dmx, &adapter->mem_frontend);
- if (ret < 0)
- goto err_remove_hw_frontend;
-
- ret = dmx->connect_frontend(dmx, &adapter->hw_frontend);
- if (ret < 0)
- goto err_remove_mem_frontend;
-
- dvb_net_init(&adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx);
-
- frontend_init(adapter);
-out:
- return ret;
-
-err_remove_mem_frontend:
- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->mem_frontend);
-err_remove_hw_frontend:
- dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &adapter->hw_frontend);
-err_dmxdev_release:
- dvb_dmxdev_release(&adapter->dmxdev);
-err_dmx_release:
- dvb_dmx_release(&adapter->demux);
-err_i2c_del:
- i2c_del_adapter(&adapter->i2c_adap);
-err_dvb_unregister:
- dvb_unregister_adapter(&adapter->dvb_adapter);
-err_halt:
- driver_halt(pdev);
- goto out;
-}
-
-static void skystar2_remove(struct pci_dev *pdev)
-{
- struct adapter *adapter = pci_get_drvdata(pdev);
- struct dvb_demux *dvbdemux;
- struct dmx_demux *dmx;
-
- if (!adapter)
- return;
-
- dvb_net_release(&adapter->dvbnet);
- dvbdemux = &adapter->demux;
- dmx = &dvbdemux->dmx;
-
- dmx->close(dmx);
- dmx->remove_frontend(dmx, &adapter->hw_frontend);
- dmx->remove_frontend(dmx, &adapter->mem_frontend);
-
- dvb_dmxdev_release(&adapter->dmxdev);
- dvb_dmx_release(dvbdemux);
-
- if (adapter->fe != NULL)
- dvb_unregister_frontend(adapter->fe);
-
- dvb_unregister_adapter(&adapter->dvb_adapter);
-
- i2c_del_adapter(&adapter->i2c_adap);
-
- driver_halt(pdev);
- }
-
-static struct pci_device_id skystar2_pci_tbl[] = {
- {0x000013d0, 0x00002103, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000},
-/* {0x000013d0, 0x00002200, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000}, UNDEFINED HARDWARE - mail linuxtv.org list */ //FCIII
- {0,},
-};
-
-MODULE_DEVICE_TABLE(pci, skystar2_pci_tbl);
-
-static struct pci_driver skystar2_pci_driver = {
- .name = "SkyStar2",
- .id_table = skystar2_pci_tbl,
- .probe = skystar2_probe,
- .remove = skystar2_remove,
-};
-
-static int skystar2_init(void)
-{
- return pci_register_driver(&skystar2_pci_driver);
-}
-
-static void skystar2_cleanup(void)
-{
- pci_unregister_driver(&skystar2_pci_driver);
-}
-
-module_init(skystar2_init);
-module_exit(skystar2_cleanup);
-
-MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
-MODULE_LICENSE("GPL");