diff options
author | Holger Waechtler <devnull@localhost> | 2003-12-04 19:15:49 +0000 |
---|---|---|
committer | Holger Waechtler <devnull@localhost> | 2003-12-04 19:15:49 +0000 |
commit | 2b17bc52d2eacffa537f7cbbea626e5a48c2d054 (patch) | |
tree | 75934acb9eb31c2f27205621d8cf1ad59fa70610 /linux/drivers/media/dvb/b2c2 | |
parent | f3e7c1c071288e92cb53c08ec379ccf9a07a4136 (diff) | |
download | mediapointer-dvb-s2-2b17bc52d2eacffa537f7cbbea626e5a48c2d054.tar.gz mediapointer-dvb-s2-2b17bc52d2eacffa537f7cbbea626e5a48c2d054.tar.bz2 |
update by Niklas Peinecke, Wolfgang This, Vincenzo Di Massa et al.
Diffstat (limited to 'linux/drivers/media/dvb/b2c2')
-rw-r--r-- | linux/drivers/media/dvb/b2c2/skystar2.c | 847 |
1 files changed, 348 insertions, 499 deletions
diff --git a/linux/drivers/media/dvb/b2c2/skystar2.c b/linux/drivers/media/dvb/b2c2/skystar2.c index a95b0b422..75ce9140f 100644 --- a/linux/drivers/media/dvb/b2c2/skystar2.c +++ b/linux/drivers/media/dvb/b2c2/skystar2.c @@ -4,15 +4,16 @@ * * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc * - * FIX: DiSEqC Tone Burst in flexcop_diseqc_ioctl() + * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl() + * FIX: FULL soft DiSEqC for skystar2 (rev 193) VP310 equipped * Vincenzo Di Massa, hawk.it at tiscalinet.it * * IMP: Converted to Linux coding style * Roberto Ragusa, r.ragusa at libero.it * - * FIX: FULL soft DiSEqC for skystar2 (rev 193) VP310 equipped - * Vincenzo Di Massa, hawk.it at tiscalinet.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 @@ -28,7 +29,6 @@ * 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/delay.h> #include <linux/pci.h> @@ -51,11 +51,16 @@ #include "dvb_functions.h" static int debug = 0; -#define dprintk(x...) do { if (debug) printk(x); } while (0) +#define dprintk(x...) do { if (debug>=1) printk(x); } while (0) +#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0) +static int enable_hw_filters=1; #define SIZE_OF_BUF_DMA1 0x3AC00 #define SIZE_OF_BUF_DMA2 0x758 +#define N_HW_FILTERS (6+32) +#define N_PID_SLOTS 256 + struct dmaq { u32 bus_addr; @@ -100,7 +105,11 @@ struct adapter { spinlock_t lock; - u16 pids[0x27]; + u16 pids[N_HW_FILTERS]; + u16 pid_list[N_PID_SLOTS]; + u8 pid_rc[N_PID_SLOTS]; // ref counters for the pids + u16 pid_count; + int whole_bandwidth; u32 mac_filter; }; @@ -224,7 +233,7 @@ static u32 flex_i2c_read(struct adapter * adapter, u32 device, u32 bus, u32 addr u32 bytes_to_transfer; u8 *start; - dprintk("%s:\n", __FUNCTION__); + ddprintk("%s:\n", __FUNCTION__); start = buf; @@ -253,7 +262,7 @@ static u32 flex_i2c_write(struct adapter * adapter, u32 device, u32 bus, u32 add u32 bytes_to_transfer; u8 *start; - dprintk("%s:\n", __FUNCTION__); + ddprintk("%s:\n", __FUNCTION__); start = buf; @@ -284,11 +293,11 @@ static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg *msgs, int if (down_interruptible(&tmp->i2c_sem)) return -ERESTARTSYS; - dprintk("%s: %d messages to transfer\n", __FUNCTION__, num); + ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num); for (i = 0; i < num; i++) { - dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", 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); /* allow only the mt312 and stv0299 frontends to access the bus */ @@ -602,13 +611,13 @@ static void sram_init(struct adapter *adapter) adapter->dw_sram_type = tmp & 0x30000; - dprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); + ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); } else { adapter->dw_sram_type = 0x10000; - dprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); + ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); } /* return value is never used? */ @@ -933,83 +942,31 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 * mac) */ /* PID filter */ -static void filter_enable_stream1_filter(struct adapter *adapter, u32 op) -{ - dprintk("%s: op=%x\n", __FUNCTION__, op); - - if (op == 0) { - write_reg_op(adapter, 0x208, 2, ~0x00000001, 0); - - } else { - - write_reg_op(adapter, 0x208, 1, 0, 0x00000001); - } -} -static void filter_enable_stream2_filter(struct adapter *adapter, u32 op) +/* every flexcop has 6 "lower" hw PID filters */ +/* these are enabled by setting bits 0-5 of 0x208 */ +/* we do not check for id>5 here! */ +static void filter_enable_hw_filter(struct adapter *adapter,u8 id,u8 op) { - dprintk("%s: op=%x\n", __FUNCTION__, op); + u32 mask=( 0x00000001 << id ); - if (op == 0) { - write_reg_op(adapter, 0x208, 2, ~0x00000002, 0); - - } else { + dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op); - write_reg_op(adapter, 0x208, 1, 0, 0x00000002); - } + if (op == 0) write_reg_op(adapter, 0x208, 2, ~mask, 0); + else write_reg_op(adapter, 0x208, 1, 0, mask); } -static void filter_enable_pcr_filter(struct adapter *adapter, u32 op) +/* this sets the PID that should pass the specified filter */ +static void pid_set_hw_pid(struct adapter * adapter,u8 id,u32 pid) { - dprintk("%s: op=%x\n", __FUNCTION__, op); - - if (op == 0) { - write_reg_op(adapter, 0x208, 2, ~0x00000004, 0); + u32 adr=0x300+((id&6)<<1); - } else { + dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id&1)? 'h':'l', pid); - write_reg_op(adapter, 0x208, 1, 0, 0x00000004); - } + if((id&1)==0) write_reg_op(adapter,adr,3,0xffff8000,pid&0x1fff); + else write_reg_op(adapter,adr,3,0x8000ffff,(pid&0x1fff)<<16); } -static void filter_enable_pmt_filter(struct adapter *adapter, u32 op) -{ - dprintk("%s: op=%x\n", __FUNCTION__, op); - - if (op == 0) { - write_reg_op(adapter, 0x208, 2, ~0x00000008, 0); - - } else { - - write_reg_op(adapter, 0x208, 1, 0, 0x00000008); - } -} - -static void filter_enable_emm_fFilter(struct adapter *adapter, u32 op) -{ - dprintk("%s: op=%x\n", __FUNCTION__, op); - - if (op == 0) { - write_reg_op(adapter, 0x208, 2, ~0x00000010, 0); - - } else { - - write_reg_op(adapter, 0x208, 1, 0, 0x00000010); - } -} - -static void filter_enable_ecm_filter(struct adapter *adapter, u32 op) -{ - dprintk("%s: op=%x\n", __FUNCTION__, op); - - if (op == 0) { - write_reg_op(adapter, 0x208, 2, ~0x00000020, 0); - - } else { - - write_reg_op(adapter, 0x208, 1, 0, 0x00000020); - } -} /* static void filter_enable_null_filter(struct adapter *adapter, u32 op) @@ -1051,6 +1008,25 @@ static void ctrl_enable_mac(struct adapter *adapter, u32 op) } } +/* select data filter nr. id for setup */ +static void filter_select_data_filter(struct adapter *adapter,u8 id) +{ + write_reg_op(adapter,0x310,3,0xffffffe0,id&0x1f); +} + +/* enable data filter; 0: disable, 1: enable */ +static void filter_enable_data_filter(struct adapter *adapter,u8 op) +{ + if(op==0) write_reg_op(adapter,0x314,2,0xffff9fff,0); + else write_reg_op(adapter,0x314,3,0xffff9fff,0x00004000); +} + +/* set PID for data filter */ +static void pid_set_data_pid(struct adapter *adapter,u32 pid) +{ + write_reg_op(adapter,0x314,3,0xffffe000,pid & 0x1fff); +} + static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 * mac) { u32 tmp1, tmp2; @@ -1091,29 +1067,6 @@ static void check_null_filter_enable(struct adapter *adapter) } */ -static void init_pids_info(struct adapter *adapter) -{ - int i; - - for (i = 0; i < 0x27; i++) - adapter->pids[i] = 0x1FFF; -} - -static int check_pid(struct adapter *adapter, u16 pid) -{ - u32 i; - - if (pid == 0x1FFF) - return 0; - - for (i = 0; i < 0x27; i++) { - if (adapter->pids[i] == pid || adapter->pids[i] == 0x2000) - return 1; - } - - return 0; -} - static void pid_set_group_pid(struct adapter * adapter, u32 pid) { u32 value; @@ -1142,120 +1095,7 @@ static void pid_set_group_mask(struct adapter * adapter, u32 pid) /* return value; */ } -static void pid_set_stream1_pid(struct adapter * adapter, u32 pid) -{ - u32 value; - - dprintk("%s: pid=%x\n", __FUNCTION__, pid); - - value = (pid & 0x3FFF) | (read_reg_dw(adapter, 0x300) & 0xFFFFC000); - - write_reg_dw(adapter, 0x300, value); - - /* return value is never used? */ -/* return value; */ -} - -static void pid_set_stream2_pid(struct adapter * adapter, u32 pid) -{ - u32 value; - - dprintk("%s: pid=%x\n", __FUNCTION__, pid); - - value = ((pid & 0x3FFF) << 0x10) | (read_reg_dw(adapter, 0x300) & 0xFFFF); - - write_reg_dw(adapter, 0x300, value); - - /* return value is never used? */ -/* return value; */ -} - -static void pid_set_pcr_pid(struct adapter * adapter, u32 pid) -{ - u32 value; - - dprintk("%s: pid=%x\n", __FUNCTION__, pid); - - value = (pid & 0x3FFF) | (read_reg_dw(adapter, 0x304) & 0xFFFFC000); - - write_reg_dw(adapter, 0x304, value); - - /* return value is never used? */ -/* return value; */ -} - -static void pid_set_pmt_pid(struct adapter * adapter, u32 pid) -{ - u32 value; - - dprintk("%s: pid=%x\n", __FUNCTION__, pid); - - value = ((pid & 0x3FFF) << 0x10) | (read_reg_dw(adapter, 0x304) & 0x3FFF); - - write_reg_dw(adapter, 0x304, value); - - /* return value is never used? */ -/* return value; */ -} - -static void pid_set_emm_pid(struct adapter * adapter, u32 pid) -{ - u32 value; - - dprintk("%s: pid=%x\n", __FUNCTION__, pid); - - value = (pid & 0xFFFF) | (read_reg_dw(adapter, 0x308) & 0xFFFF0000); - - write_reg_dw(adapter, 0x308, value); - - /* return value is never used? */ -/* return value; */ -} - -static void pid_set_ecm_pid(struct adapter * adapter, u32 pid) -{ - u32 value; - - dprintk("%s: pid=%x\n", __FUNCTION__, pid); - - value = (pid << 0x10) | (read_reg_dw(adapter, 0x308) & 0xFFFF); - - write_reg_dw(adapter, 0x308, value); - - /* return value is never used? */ -/* return value; */ -} - -static int pid_get_stream1_pid(struct adapter * adapter) -{ - return read_reg_dw(adapter, 0x300) & 0x00001FFF; -} - -static int pid_get_stream2_pid(struct adapter * adapter) -{ - return (read_reg_dw(adapter, 0x300) >> 0x10)& 0x00001FFF; -} - -static int pid_get_pcr_pid(struct adapter * adapter) -{ - return read_reg_dw(adapter, 0x304) & 0x00001FFF; -} - -static int pid_get_pmt_pid(struct adapter * adapter) -{ - return (read_reg_dw(adapter, 0x304) >> 0x10)& 0x00001FFF; -} - -static int pid_get_emm_pid(struct adapter * adapter) -{ - return read_reg_dw(adapter, 0x308) & 0x00001FFF; -} - -static int pid_get_ecm_pid(struct adapter * adapter) -{ - return (read_reg_dw(adapter, 0x308) >> 0x10)& 0x00001FFF; -} - +/* static int pid_get_group_pid(struct adapter * adapter) { return read_reg_dw(adapter, 0x30C) & 0x00001FFF; @@ -1265,6 +1105,7 @@ 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) @@ -1284,10 +1125,29 @@ static void reset_hardware_pid_filter(struct adapter *adapter) filter_enable_ecm_filter(adapter, 0); pid_set_emm_pid(adapter, 0x1FFF); - filter_enable_emm_fFilter(adapter, 0); + filter_enable_emm_filter(adapter, 0); } */ +static void init_pids(struct adapter *adapter) +{ + int i; + + for (i = 0; i < N_HW_FILTERS; i++) + adapter->pids[i] = 0x1FFF; + adapter->pid_count=0; + adapter->whole_bandwidth = 0; + + pid_set_group_pid(adapter, 0); + pid_set_group_mask(adapter, 0x1FE0); + pid_set_hw_pid(adapter,0,0x1FFF); + pid_set_hw_pid(adapter,1,0x1FFF); + pid_set_hw_pid(adapter,2,0x1FFF); + pid_set_hw_pid(adapter,3,0x1FFF); + pid_set_hw_pid(adapter,4,0x1FFF); + pid_set_hw_pid(adapter,5,0x1FFF); +} + static void open_whole_bandwidth(struct adapter *adapter) { dprintk("%s:\n", __FUNCTION__); @@ -1297,175 +1157,167 @@ static void open_whole_bandwidth(struct adapter *adapter) pid_set_group_mask(adapter, 0); filter_enable_mask_filter(adapter, 1); - } -static int add_hw_pid(struct adapter *adapter, u32 pid) +static void close_whole_bandwidth(struct adapter *adapter) { - dprintk("%s: pid=%d\n", __FUNCTION__, pid); - - if (pid <= 0x1F) - return 1; - - if ((pid_get_group_mask(adapter) == 0) && (pid_get_group_pid(adapter) == 0)) - return 0; - - if (pid_get_stream1_pid(adapter) == 0x1FFF) { - pid_set_stream1_pid(adapter, pid & 0xFFFF); - - filter_enable_stream1_filter(adapter, 1); - - return 1; - } - - if (pid_get_stream2_pid(adapter) == 0x1FFF) { - pid_set_stream2_pid(adapter, (pid & 0xFFFF)); - - filter_enable_stream2_filter(adapter, 1); - - return 1; - } - - if (pid_get_pcr_pid(adapter) == 0x1FFF) { - pid_set_pcr_pid(adapter, (pid & 0xFFFF)); - - filter_enable_pcr_filter(adapter, 1); - - return 1; - } - - if ((pid_get_pmt_pid(adapter) & 0x1FFF) == 0x1FFF) { - pid_set_pmt_pid(adapter, (pid & 0xFFFF)); - - filter_enable_pmt_filter(adapter, 1); - - return 1; - } - - if ((pid_get_emm_pid(adapter) & 0x1FFF) == 0x1FFF) { - pid_set_emm_pid(adapter, (pid & 0xFFFF)); - - filter_enable_emm_fFilter(adapter, 1); - - return 1; - } + dprintk("%s:\n", __FUNCTION__); + + pid_set_group_pid(adapter, 0); - if ((pid_get_ecm_pid(adapter) & 0x1FFF) == 0x1FFF) { - pid_set_ecm_pid(adapter, (pid & 0xFFFF)); + pid_set_group_mask(adapter, 0x1fe0); - filter_enable_ecm_filter(adapter, 1); + filter_enable_mask_filter(adapter, 1); +} - return 1; +/* this tries to add the specified PID to be let through the + hw filters. return 1 on success. + if this cannot be done (all filter in use), returns -1 + for PID <= 0x1f there is always success reported, since + these are let through by the group filters anyway. */ +static int add_hw_pid(struct adapter *adapter, u32 pid) +{ + int num,i; + + if(pid<=0x1f) return 1; + + if(adapter->b2c2_revision==0xc0 || adapter->b2c2_revision==0xc3) + num=38; // FlexCop IIb & III have 6+32 hw filters + else num=6; // FlexCop II has 6 hw filters, every other should have at least 6 + + for (i=0; i<num; i++) { + if (adapter->pids[i] == 0x1fff) { // find a free pid slot + adapter->pids[i]=pid; + if(i<6) { + pid_set_hw_pid(adapter,i,pid); + filter_enable_hw_filter(adapter,i,1); + return 1; + } else { + filter_select_data_filter(adapter,i-6); + pid_set_data_pid(adapter,pid); + filter_enable_data_filter(adapter,1); + return 1; + } + } } - return -1; } +/* returns -1 if the pid was not present in the filters */ static int remove_hw_pid(struct adapter *adapter, u32 pid) { - dprintk("%s: pid=%d\n", __FUNCTION__, pid); - - if (pid <= 0x1F) - return 1; - - if (pid_get_stream1_pid(adapter) == pid) { - pid_set_stream1_pid(adapter, 0x1FFF); - - return 1; - } - - if (pid_get_stream2_pid(adapter) == pid) { - pid_set_stream2_pid(adapter, 0x1FFF); - - filter_enable_stream2_filter(adapter, 0); - - return 1; - } - - if (pid_get_pcr_pid(adapter) == pid) { - pid_set_pcr_pid(adapter, 0x1FFF); - - filter_enable_pcr_filter(adapter, 0); - - return 1; - } - - if (pid_get_pmt_pid(adapter) == pid) { - pid_set_pmt_pid(adapter, 0x1FFF); - - filter_enable_pmt_filter(adapter, 0); - - return 1; - } - - if (pid_get_emm_pid(adapter) == pid) { - pid_set_emm_pid(adapter, 0x1FFF); - - filter_enable_emm_fFilter(adapter, 0); - - return 1; - } - - if (pid_get_ecm_pid(adapter) == pid) { - pid_set_ecm_pid(adapter, 0x1FFF); - - filter_enable_ecm_filter(adapter, 0); - - return 1; + int num,i; + + if(pid<=0x1f) return 1; + + if(adapter->b2c2_revision==0xc0 || adapter->b2c2_revision==0xc3) + num=38; // FlexCop IIb & III have 6+32 hw filters + else num=6; // FlexCop II has 6 hw filters, every other should have at least 6 + + for(i=0; i<num; i++) { + if (adapter->pids[i] == pid) { // find the pid slot + adapter->pids[i]=0x1fff; + if(i<6) { + pid_set_hw_pid(adapter,i,pid); + filter_enable_hw_filter(adapter,i,0); + return 1; + } else { + filter_select_data_filter(adapter,i-6); + pid_set_data_pid(adapter,pid); + filter_enable_data_filter(adapter,0); + return 1; + } + } } - return -1; } -static int add_pid(struct adapter *adapter, u32 pid) +/* Adds a PID to the filters. + If there are no more hw filters available, open the whole + ts stream to pass by. + Adding a pid more than once has no effect. + If pid==0x2000, open whole ts stream also. + Returns 1 on success, -1 on error */ +static int add_pid(struct adapter *adapter,u32 pid) { int i; - + dprintk("%s: pid=%d\n", __FUNCTION__, pid); - - if (pid > 0x1FFE && pid != 0x2000) - return -1; - - if (check_pid(adapter, pid) == 1) + + if(pid==0x2000) { + if (adapter->whole_bandwidth == 0) + open_whole_bandwidth(adapter); + ++adapter->whole_bandwidth; return 1; - - for (i = 0; i < 0x27; i++) { - if (adapter->pids[i] == 0x1FFF) // find free pid filter - { - adapter->pids[i] = pid; - - if (pid == 0x2000 || add_hw_pid(adapter, pid) < 0) - open_whole_bandwidth(adapter); - + } + + if (pid > 0x1ffe) 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++; + + // setup a filter for the pid + // if there are no filters left, let the whole ts pass + if (add_hw_pid(adapter,pid)==-1) { + if (adapter->whole_bandwidth == 0) + open_whole_bandwidth(adapter); + adapter->whole_bandwidth++; } - - return -1; + + return 1; } +/* Removes a PID from the filters. */ static int remove_pid(struct adapter *adapter, u32 pid) { - u32 i; - - dprintk("%s: pid=%d\n", __FUNCTION__, pid); - - if (pid > 0x1FFE) - return -1; - - for (i = 0; i < 0x27; i++) { - if (adapter->pids[i] == pid) { - adapter->pids[i] = 0x1FFF; - - remove_hw_pid(adapter, pid); + int i,j; + + if (pid==0x2000) { + if (adapter->whole_bandwidth <= 0) return -1; // cannot remove a pid that was not added ;) + adapter->whole_bandwidth--; + if (adapter->whole_bandwidth == 0) + close_whole_bandwidth(adapter); + return 1; + } + + if (pid > 0x1ffe && pid != 0x2000) return -1; + + // check if the pid is present + 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--; + for(j=i; j<adapter->pid_count; j++) { + adapter->pid_list[j]=adapter->pid_list[j+1]; + adapter->pid_rc[j]=adapter->pid_rc[j+1]; + } + // close filter and take care to reverse the effect of open_whole_bandwidth + if (remove_hw_pid(adapter,pid)==-1) { + if (adapter->whole_bandwidth > 0) + --adapter->whole_bandwidth; + if (adapter->whole_bandwidth == 0) + close_whole_bandwidth(adapter); + } + } return 1; } } - return -1; } + /* dma & irq */ static void ctrl_enable_smc(struct adapter *adapter, u32 op) { @@ -1745,7 +1597,12 @@ static void open_stream(struct adapter *adapter, u32 pid) filter_enable_mask_filter(adapter, 1); - add_pid(adapter, pid); + if(enable_hw_filters==1) add_pid(adapter, pid); + else { + if (adapter->whole_bandwidth == 0) + open_whole_bandwidth(adapter); + adapter->whole_bandwidth++; + } dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status); @@ -1795,7 +1652,15 @@ static void close_stream(struct adapter *adapter, u32 pid) dma_start_stop0x2102(adapter, dma_mask, 0); } } - remove_pid(adapter, pid); + if (enable_hw_filters==1) + remove_pid(adapter, pid); + else { + if (adapter->whole_bandwidth > 0) { + adapter->whole_bandwidth--; + if (adapter->whole_bandwidth == 0) + close_whole_bandwidth(adapter); + } + } } static void interrupt_service_dma1(struct adapter *adapter) @@ -1827,9 +1692,9 @@ static void interrupt_service_dma1(struct adapter *adapter) n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter; } - dprintk("%s: n_cur_dma_counter = %d\n" , __FUNCTION__, n_cur_dma_counter); - dprintk("%s: dmaq1.tail = %d\n" , __FUNCTION__, adapter->dmaq1.tail); - dprintk("%s: bytes_transferred = %d\n" , __FUNCTION__, n_num_new_bytes_transferred); + 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; @@ -1871,7 +1736,7 @@ static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs) u32 value; - dprintk("%s:\n", __FUNCTION__); + ddprintk("%s:\n", __FUNCTION__); spin_lock_irq(&tmp->lock); @@ -1915,7 +1780,7 @@ static void init_dma_queue(struct adapter *adapter) adapter->dma_status = adapter->dma_status | 0x10000000; - dprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1); + ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1); } else { @@ -1941,7 +1806,7 @@ static void init_dma_queue(struct adapter *adapter) adapter->dma_status = adapter->dma_status | 0x20000000; - dprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2); + ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2); } else { @@ -2080,16 +1945,7 @@ static int driver_initialize(struct pci_dev * pdev) write_reg_dw(adapter, 0x210, 0xB2FF); write_reg_dw(adapter, 0x208, 0x40); - init_pids_info(adapter); - - pid_set_group_pid(adapter, 0); - pid_set_group_mask(adapter, 0x1FE0); - pid_set_stream1_pid(adapter, 0x1FFF); - pid_set_stream2_pid(adapter, 0x1FFF); - pid_set_pmt_pid(adapter, 0x1FFF); - pid_set_pcr_pid(adapter, 0x1FFF); - pid_set_ecm_pid(adapter, 0x1FFF); - pid_set_emm_pid(adapter, 0x1FFF); + init_pids(adapter); init_dma_queue(adapter); @@ -2101,25 +1957,25 @@ static int driver_initialize(struct pci_dev * pdev) 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__); - free_adapter_object(adapter); - pci_set_drvdata(pdev, NULL); - release_region(pci_resource_start(pdev,1), pci_resource_len(pdev,1)); - release_mem_region(pci_resource_start(pdev,0), pci_resource_len(pdev,0)); - return -ENODEV; - } + 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__); + free_adapter_object(adapter); + pci_set_drvdata(pdev, NULL); + release_region(pci_resource_start(pdev,1), pci_resource_len(pdev,1)); + release_mem_region(pci_resource_start(pdev,0), pci_resource_len(pdev,0)); + return -ENODEV; + } tmp = read_reg_dw(adapter, 0x204); @@ -2265,147 +2121,138 @@ static void set_tuner_polarity(struct adapter *adapter, u8 polarity) write_reg_dw(adapter, 0x204, var); } -static void diseqc_send_bit (struct adapter *adapter, int data) +static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) { - set_tuner_tone(adapter, 1); - udelay(data ? 500 : 1000); - set_tuner_tone(adapter, 0); - udelay(data ? 1000 : 500); -} + struct adapter *adapter = fe->before_after_data; + struct dvb_frontend_info info; + + switch (cmd) { + + case FE_DISEQC_SEND_BURST: + { + u8 count; + fe_sec_mini_cmd_t b = (fe_sec_mini_cmd_t) arg; + dprintk("%s: FE_SEND_BURST ", __FUNCTION__); + switch ( b ) + { + case SEC_MINI_A: + { + dprintk("SEC_MINI_A\n"); + set_tuner_tone(adapter, 1); // This lines are needed + udelay(500*25); // to do a down-step + set_tuner_tone(adapter, 0); + udelay(500*25); + break; + } + case SEC_MINI_B: + { + dprintk("SEC_MINI_B\n"); + set_tuner_tone(adapter, 0); + udelay(1000*15); + for (count=0;count<9; count++) + { + set_tuner_tone(adapter, 1); + udelay(500); + set_tuner_tone(adapter, 0); + udelay(1000); + } + udelay(1000*15); + break; + } + default: + break; + }; + return 0; + } + -static void diseqc_send_byte (struct adapter *adapter, int data) -{ - int i, par=1, d; + case FE_SLEEP: + { + dprintk("%s: FE_SLEEP\n", __FUNCTION__); - for (i=7; i>=0; i--) { - d = (data>>i)&1; - par ^= d; - diseqc_send_bit(adapter, d); - } + set_tuner_polarity(adapter, 0); - diseqc_send_bit(adapter, par); -} + // return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend. + return -EOPNOTSUPP; + } + case FE_SET_VOLTAGE: + { + dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__); -static int send_diseqc_msg (struct adapter *adapter, int len, u8 *msg, unsigned long burst) -{ - int i; + switch ((fe_sec_voltage_t) arg) + { + case SEC_VOLTAGE_13: - set_tuner_tone(adapter, 0); - mdelay(16); + dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13); - for (i=0; i<len; i++) - diseqc_send_byte(adapter, msg[i]); + set_tuner_polarity(adapter, 1); - mdelay(16); + return 0; - if (burst!=-1) { - if (burst) - diseqc_send_byte(adapter, 0xff); - else { - set_tuner_tone(adapter, 1); - udelay(12500); - set_tuner_tone(adapter, 0); - } - dvb_delay(20); - } + case SEC_VOLTAGE_18: - return 0; -} + dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18); + set_tuner_polarity(adapter, 2); -int soft_diseqc (struct adapter *adapter, unsigned int cmd, void *arg) -{ - switch (cmd) { - case FE_SET_TONE: - switch ((fe_sec_tone_mode_t) arg) { - case SEC_TONE_ON: - set_tuner_tone(adapter, 1); - break; - case SEC_TONE_OFF: - set_tuner_tone(adapter, 0); - break; - default: - return -EINVAL; - }; - break; - - case FE_DISEQC_SEND_MASTER_CMD: - { - struct dvb_diseqc_master_cmd *cmd = arg; - - send_diseqc_msg (adapter, cmd->msg_len, cmd->msg, 0); - break; - } + return 0; - case FE_DISEQC_SEND_BURST: - send_diseqc_msg (adapter, 0, NULL, (unsigned long)arg); - break; + default: - default: - return -EOPNOTSUPP; - }; + return -EINVAL; + }; - return 0; -} + } -static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) -{ - struct adapter *adapter = fe->before_after_data; + case FE_SET_TONE: + { + dprintk("%s: FE_SET_TONE\n", __FUNCTION__); - struct dvb_frontend_info info; - - fe->ioctl(fe, FE_GET_INFO, &info); + fe->ioctl(fe, FE_GET_INFO, &info); - // we must use different DiSEqC hw - - if ( strcmp(info.name, "Zarlink MT312") == 0){ - //VP310 using mt312 driver for tuning only: diseqc not wired - //use FCII instead - if (!soft_diseqc(adapter,cmd,arg)) - return 0; - } - - switch (cmd) { - case FE_SLEEP: - { - dprintk("%s: FE_SLEEP\n", __FUNCTION__); + if ( strcmp(info.name, "Zarlink MT312") == 0) + { + dprintk("%s: FE_SET_TONE for %s frontend\n", __FUNCTION__, info.name); - set_tuner_polarity(adapter, 0); + switch ((fe_sec_tone_mode_t) arg) + { + case SEC_TONE_ON: - // return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend. - return -EOPNOTSUPP; - } + dprintk("%s: SEC_TONE_ON, %x\n", __FUNCTION__, SEC_TONE_ON); - case FE_SET_VOLTAGE: - { - dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__); + set_tuner_tone(adapter, 1); - switch ((fe_sec_voltage_t) arg) - { - case SEC_VOLTAGE_13: + return 0; - dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13); + case SEC_TONE_OFF: - set_tuner_polarity(adapter, 1); + dprintk("%s: SEC_TONE_OFF, %x\n", __FUNCTION__, SEC_TONE_OFF); - return 0; + set_tuner_tone(adapter, 0); - case SEC_VOLTAGE_18: + return 0; - dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18); + default: - set_tuner_polarity(adapter, 2); + return -EINVAL; + }; - return 0; + }; + + if ( strcmp(info.name, "STV0299/TSA5059/SL1935 based") == 0) + { + dprintk("%s: FE_SET_TONE for %s frontend\n", __FUNCTION__, info.name); - default: + /* allow the frontend driver to handle this command*/ + return -EOPNOTSUPP; + }; - return -EINVAL; - }; - } + printk("%s: FE_SET_TONE unknown frontend : %s\n", __FUNCTION__, info.name); + return -EINVAL; + } default: @@ -2456,8 +2303,8 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dvbdemux = &adapter->demux; dvbdemux->priv = (void *) adapter; - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; + 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 = 0; @@ -2551,7 +2398,9 @@ module_init(skystar2_init); module_exit(skystar2_cleanup); MODULE_PARM(debug,"i"); -MODULE_PARM_DESC(debug, "enable verbose debug messages"); +MODULE_PARM_DESC(debug, "enable verbose debug messages: supported values: 1 and 2"); +MODULE_PARM(enable_hw_filters,"i"); +MODULE_PARM_DESC(enable_hw_filters, "enable hardware filters, if disabled the whole ts is passed through"); MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver"); MODULE_LICENSE("GPL"); |