⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skystar2.c

📁 linux环境下的dvb驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
			}		}	}	/* 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);		if (subbuffers == 0)			dma_enable_disable_irq(adapter, 0, 1, 0);		else			dma_enable_disable_irq(adapter, 0, 1, 1);		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 void init_dma_queue(struct adapter *adapter){	dma_addr_t dma_addr;	if (adapter->dmaq1.buffer != 0)		return;	adapter->dmaq1.head = 0;	adapter->dmaq1.tail = 0;	adapter->dmaq1.buffer = 0;	adapter->dmaq1.buffer = pci_alloc_consistent(adapter->pdev, SIZE_OF_BUF_DMA1 + 0x80, &dma_addr);	if (adapter->dmaq1.buffer != 0) {		memset(adapter->dmaq1.buffer, 0, SIZE_OF_BUF_DMA1);		adapter->dmaq1.bus_addr = dma_addr;		adapter->dmaq1.buffer_size = SIZE_OF_BUF_DMA1;		dma_init_dma(adapter, 0);		adapter->dma_status = adapter->dma_status | 0x10000000;		ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1);	} else {		adapter->dma_status = adapter->dma_status & ~0x10000000;	}	if (adapter->dmaq2.buffer != 0)		return;	adapter->dmaq2.head = 0;	adapter->dmaq2.tail = 0;	adapter->dmaq2.buffer = 0;	adapter->dmaq2.buffer = pci_alloc_consistent(adapter->pdev, SIZE_OF_BUF_DMA2 + 0x80, &dma_addr);	if (adapter->dmaq2.buffer != 0) {		memset(adapter->dmaq2.buffer, 0, SIZE_OF_BUF_DMA2);		adapter->dmaq2.bus_addr = dma_addr;		adapter->dmaq2.buffer_size = SIZE_OF_BUF_DMA2;		dma_init_dma(adapter, 1);		adapter->dma_status = adapter->dma_status | 0x20000000;		ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2);	} else {		adapter->dma_status = adapter->dma_status & ~0x20000000;	}}static void free_dma_queue(struct adapter *adapter){	if (adapter->dmaq1.buffer != 0) {		pci_free_consistent(adapter->pdev, SIZE_OF_BUF_DMA1 + 0x80, adapter->dmaq1.buffer, adapter->dmaq1.bus_addr);		adapter->dmaq1.bus_addr = 0;		adapter->dmaq1.head = 0;		adapter->dmaq1.tail = 0;		adapter->dmaq1.buffer_size = 0;		adapter->dmaq1.buffer = 0;	}	if (adapter->dmaq2.buffer != 0) {		pci_free_consistent(adapter->pdev, SIZE_OF_BUF_DMA2 + 0x80, adapter->dmaq2.buffer, adapter->dmaq2.bus_addr);		adapter->dmaq2.bus_addr = 0;		adapter->dmaq2.head = 0;		adapter->dmaq2.tail = 0;		adapter->dmaq2.buffer_size = 0;		adapter->dmaq2.buffer = 0;	}}static void free_adapter_object(struct adapter *adapter){	dprintk("%s:\n", __FUNCTION__);	close_stream(adapter, 0);	if (adapter->irq != 0)		free_irq(adapter->irq, adapter);	free_dma_queue(adapter);	if (adapter->io_mem != 0)		iounmap((void *) adapter->io_mem);	if (adapter != 0)		kfree(adapter);}static struct pci_driver skystar2_pci_driver;static int claim_adapter(struct adapter *adapter){	struct pci_dev *pdev = adapter->pdev;	u16 var;	if (!request_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1), skystar2_pci_driver.name))		return -EBUSY;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -