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

📄 dm1105.c

📁 trident tm5600的linux驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			if ((dm1105dvb->PacketErrorCount >= 2) &&					(dm1105dvb->dmarst == 0)) {				outb(1, dm_io_mem(DM1105_RST));				dm1105dvb->wrp = 0;				dm1105dvb->PacketErrorCount = 0;				dm1105dvb->dmarst = 0;				spin_unlock(&dm1105dvb->lock);				return IRQ_HANDLED;			}		}		if (nextwrp < oldwrp) {			piece = dm1105dvb->buffer_size - oldwrp;			memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp);			nbpackets = (piece + nextwrp)/188;		} else	{			nbpackets = (nextwrp - oldwrp)/188;		}		dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets);		dm1105dvb->wrp = nextwrp;		spin_unlock(&dm1105dvb->lock);		break;	case INTSTS_IR:		command = inl(dm_io_mem(DM1105_IRCODE));		if (ir_debug)			printk("dm1105: received byte 0x%04x\n", command);		dm1105dvb->ir.ir_command = command;		tasklet_schedule(&dm1105dvb->ir.ir_tasklet);		break;	}	return IRQ_HANDLED;}/* register with input layer */static void input_register_keys(struct infrared *ir){	int i;	memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));	for (i = 0; i < ARRAY_SIZE(ir->key_map); i++)			set_bit(ir->key_map[i], ir->input_dev->keybit);	ir->input_dev->keycode = ir->key_map;	ir->input_dev->keycodesize = sizeof(ir->key_map[0]);	ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);}int __devinit dm1105_ir_init(struct dm1105dvb *dm1105){	struct input_dev *input_dev;	int err;	dm1105dvb_local = dm1105;	input_dev = input_allocate_device();	if (!input_dev)		return -ENOMEM;	dm1105->ir.input_dev = input_dev;	snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),		"pci-%s/ir0", pci_name(dm1105->pdev));	input_dev->evbit[0] = BIT(EV_KEY);	input_dev->name = "DVB on-card IR receiver";	input_dev->phys = dm1105->ir.input_phys;	input_dev->id.bustype = BUS_PCI;	input_dev->id.version = 2;	if (dm1105->pdev->subsystem_vendor) {		input_dev->id.vendor = dm1105->pdev->subsystem_vendor;		input_dev->id.product = dm1105->pdev->subsystem_device;	} else {		input_dev->id.vendor = dm1105->pdev->vendor;		input_dev->id.product = dm1105->pdev->device;	}	input_dev->dev.parent = &dm1105->pdev->dev;	/* initial keymap */	memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map);	input_register_keys(&dm1105->ir);	err = input_register_device(input_dev);	if (err) {		input_free_device(input_dev);		return err;	}	tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir);	return 0;}void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105){	tasklet_kill(&dm1105->ir.ir_tasklet);	input_unregister_device(dm1105->ir.input_dev);}static int __devinit dm1105dvb_hw_init(struct dm1105dvb *dm1105dvb){	dm1105dvb_disable_irqs(dm1105dvb);	outb(0, dm_io_mem(DM1105_HOST_CTR));	/*DATALEN 188,*/	outb(188, dm_io_mem(DM1105_DTALENTH));	/*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/	outw(0xc10a, dm_io_mem(DM1105_TSCTR));	/* map DMA and set address */	dm1105dvb_dma_map(dm1105dvb);	dm1105dvb_set_dma_addr(dm1105dvb);	/* big buffer */	outl(5*DM1105_DMA_BYTES, dm_io_mem(DM1105_RLEN));	outb(47, dm_io_mem(DM1105_INTCNT));	/* IR NEC mode enable */	outb((DM1105_IR_EN | DM1105_SYS_CHK), dm_io_mem(DM1105_IRCTR));	outb(0, dm_io_mem(DM1105_IRMODE));	outw(0, dm_io_mem(DM1105_SYSTEMCODE));	return 0;}static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb){	dm1105dvb_disable_irqs(dm1105dvb);	/* IR disable */	outb(0, dm_io_mem(DM1105_IRCTR));	outb(INTMAK_NONEMASK, dm_io_mem(DM1105_INTMAK));	dm1105dvb_dma_unmap(dm1105dvb);}static struct stv0299_config sharp_z0194a_config = {	.demod_address = 0x68,	.inittab = sharp_z0194a_inittab,	.mclk = 88000000UL,	.invert = 1,	.skip_reinit = 0,	.lock_output = STV0299_LOCKOUTPUT_1,	.volt13_op0_op1 = STV0299_VOLT13_OP1,	.min_delay_ms = 100,	.set_symbol_rate = sharp_z0194a_set_symbol_rate,};static struct stv0288_config earda_config = {	.demod_address = 0x68,	.min_delay_ms = 100,};static struct si21xx_config serit_config = {	.demod_address = 0x68,	.min_delay_ms = 100,};static struct cx24116_config serit_sp2633_config = {	.demod_address = 0x55,};static int __devinit frontend_init(struct dm1105dvb *dm1105dvb){	int ret;	switch (dm1105dvb->pdev->subsystem_device) {	case PCI_DEVICE_ID_DW2002:		dm1105dvb->fe = dvb_attach(			stv0299_attach, &sharp_z0194a_config,			&dm1105dvb->i2c_adap);		if (dm1105dvb->fe) {			dm1105dvb->fe->ops.set_voltage =							dm1105dvb_set_voltage;			dvb_attach(dvb_pll_attach, dm1105dvb->fe, 0x60,					&dm1105dvb->i2c_adap, DVB_PLL_OPERA1);		}		if (!dm1105dvb->fe) {			dm1105dvb->fe = dvb_attach(				stv0288_attach, &earda_config,				&dm1105dvb->i2c_adap);			if (dm1105dvb->fe) {				dm1105dvb->fe->ops.set_voltage =							dm1105dvb_set_voltage;				dvb_attach(stb6000_attach, dm1105dvb->fe, 0x61,						&dm1105dvb->i2c_adap);			}		}		if (!dm1105dvb->fe) {			dm1105dvb->fe = dvb_attach(				si21xx_attach, &serit_config,				&dm1105dvb->i2c_adap);			if (dm1105dvb->fe)				dm1105dvb->fe->ops.set_voltage =							dm1105dvb_set_voltage;		}		break;	case PCI_DEVICE_ID_DW2004:		dm1105dvb->fe = dvb_attach(			cx24116_attach, &serit_sp2633_config,			&dm1105dvb->i2c_adap);		if (dm1105dvb->fe)			dm1105dvb->fe->ops.set_voltage = dm1105dvb_set_voltage;		break;	}	if (!dm1105dvb->fe) {		dev_err(&dm1105dvb->pdev->dev, "could not attach frontend\n");		return -ENODEV;	}	ret = dvb_register_frontend(&dm1105dvb->dvb_adapter, dm1105dvb->fe);	if (ret < 0) {		if (dm1105dvb->fe->ops.release)			dm1105dvb->fe->ops.release(dm1105dvb->fe);		dm1105dvb->fe = NULL;		return ret;	}	return 0;}static void __devinit dm1105dvb_read_mac(struct dm1105dvb *dm1105dvb, u8 *mac){	static u8 command[1] = { 0x28 };	struct i2c_msg msg[] = {		{ .addr = IIC_24C01_addr >> 1, .flags = 0,				.buf = command, .len = 1 },		{ .addr = IIC_24C01_addr >> 1, .flags = I2C_M_RD,				.buf = mac, .len = 6 },	};	dm1105_i2c_xfer(&dm1105dvb->i2c_adap, msg , 2);	dev_info(&dm1105dvb->pdev->dev, "MAC %02x:%02x:%02x:%02x:%02x:%02x\n",			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);}static int __devinit dm1105_probe(struct pci_dev *pdev,				  const struct pci_device_id *ent){	struct dm1105dvb *dm1105dvb;	struct dvb_adapter *dvb_adapter;	struct dvb_demux *dvbdemux;	struct dmx_demux *dmx;	int ret = -ENOMEM;	dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);	if (!dm1105dvb)		goto out;	dm1105dvb->pdev = pdev;	dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;	dm1105dvb->PacketErrorCount = 0;	dm1105dvb->dmarst = 0;	ret = pci_enable_device(pdev);	if (ret < 0)		goto err_kfree;	ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);	if (ret < 0)		goto err_pci_disable_device;	pci_set_master(pdev);	ret = pci_request_regions(pdev, DRIVER_NAME);	if (ret < 0)		goto err_pci_disable_device;	dm1105dvb->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));	if (!dm1105dvb->io_mem) {		ret = -EIO;		goto err_pci_release_regions;	}	spin_lock_init(&dm1105dvb->lock);	pci_set_drvdata(pdev, dm1105dvb);	ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb);	if (ret < 0)		goto err_pci_iounmap;	ret = dm1105dvb_hw_init(dm1105dvb);	if (ret < 0)		goto err_free_irq;	/* i2c */	i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);	strcpy(dm1105dvb->i2c_adap.name, DRIVER_NAME);	dm1105dvb->i2c_adap.owner = THIS_MODULE;	dm1105dvb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;	dm1105dvb->i2c_adap.dev.parent = &pdev->dev;	dm1105dvb->i2c_adap.algo = &dm1105_algo;	dm1105dvb->i2c_adap.algo_data = dm1105dvb;	ret = i2c_add_adapter(&dm1105dvb->i2c_adap);	if (ret < 0)		goto err_dm1105dvb_hw_exit;	/* dvb */	ret = dvb_register_adapter(&dm1105dvb->dvb_adapter, DRIVER_NAME,					THIS_MODULE, &pdev->dev, adapter_nr);	if (ret < 0)		goto err_i2c_del_adapter;	dvb_adapter = &dm1105dvb->dvb_adapter;	dm1105dvb_read_mac(dm1105dvb, dvb_adapter->proposed_mac);	dvbdemux = &dm1105dvb->demux;	dvbdemux->filternum = 256;	dvbdemux->feednum = 256;	dvbdemux->start_feed = dm1105dvb_start_feed;	dvbdemux->stop_feed = dm1105dvb_stop_feed;	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |			DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);	ret = dvb_dmx_init(dvbdemux);	if (ret < 0)		goto err_dvb_unregister_adapter;	dmx = &dvbdemux->dmx;	dm1105dvb->dmxdev.filternum = 256;	dm1105dvb->dmxdev.demux = dmx;	dm1105dvb->dmxdev.capabilities = 0;	ret = dvb_dmxdev_init(&dm1105dvb->dmxdev, dvb_adapter);	if (ret < 0)		goto err_dvb_dmx_release;	dm1105dvb->hw_frontend.source = DMX_FRONTEND_0;	ret = dmx->add_frontend(dmx, &dm1105dvb->hw_frontend);	if (ret < 0)		goto err_dvb_dmxdev_release;	dm1105dvb->mem_frontend.source = DMX_MEMORY_FE;	ret = dmx->add_frontend(dmx, &dm1105dvb->mem_frontend);	if (ret < 0)		goto err_remove_hw_frontend;	ret = dmx->connect_frontend(dmx, &dm1105dvb->hw_frontend);	if (ret < 0)		goto err_remove_mem_frontend;	ret = frontend_init(dm1105dvb);	if (ret < 0)		goto err_disconnect_frontend;	dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);	dm1105_ir_init(dm1105dvb);out:	return ret;err_disconnect_frontend:	dmx->disconnect_frontend(dmx);err_remove_mem_frontend:	dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend);err_remove_hw_frontend:	dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend);err_dvb_dmxdev_release:	dvb_dmxdev_release(&dm1105dvb->dmxdev);err_dvb_dmx_release:	dvb_dmx_release(dvbdemux);err_dvb_unregister_adapter:	dvb_unregister_adapter(dvb_adapter);err_i2c_del_adapter:	i2c_del_adapter(&dm1105dvb->i2c_adap);err_dm1105dvb_hw_exit:	dm1105dvb_hw_exit(dm1105dvb);err_free_irq:	free_irq(pdev->irq, dm1105dvb);err_pci_iounmap:	pci_iounmap(pdev, dm1105dvb->io_mem);err_pci_release_regions:	pci_release_regions(pdev);err_pci_disable_device:	pci_disable_device(pdev);err_kfree:	pci_set_drvdata(pdev, NULL);	kfree(dm1105dvb);	goto out;}static void __devexit dm1105_remove(struct pci_dev *pdev){	struct dm1105dvb *dm1105dvb = pci_get_drvdata(pdev);	struct dvb_adapter *dvb_adapter = &dm1105dvb->dvb_adapter;	struct dvb_demux *dvbdemux = &dm1105dvb->demux;	struct dmx_demux *dmx = &dvbdemux->dmx;	dm1105_ir_exit(dm1105dvb);	dmx->close(dmx);	dvb_net_release(&dm1105dvb->dvbnet);	if (dm1105dvb->fe)		dvb_unregister_frontend(dm1105dvb->fe);	dmx->disconnect_frontend(dmx);	dmx->remove_frontend(dmx, &dm1105dvb->mem_frontend);	dmx->remove_frontend(dmx, &dm1105dvb->hw_frontend);	dvb_dmxdev_release(&dm1105dvb->dmxdev);	dvb_dmx_release(dvbdemux);	dvb_unregister_adapter(dvb_adapter);	if (&dm1105dvb->i2c_adap)		i2c_del_adapter(&dm1105dvb->i2c_adap);	dm1105dvb_hw_exit(dm1105dvb);	synchronize_irq(pdev->irq);	free_irq(pdev->irq, dm1105dvb);	pci_iounmap(pdev, dm1105dvb->io_mem);	pci_release_regions(pdev);	pci_disable_device(pdev);	pci_set_drvdata(pdev, NULL);	kfree(dm1105dvb);}static struct pci_device_id dm1105_id_table[] __devinitdata = {	{		.vendor = PCI_VENDOR_ID_TRIGEM,		.device = PCI_DEVICE_ID_DM1105,		.subvendor = PCI_ANY_ID,		.subdevice = PCI_DEVICE_ID_DW2002,	}, {		.vendor = PCI_VENDOR_ID_TRIGEM,		.device = PCI_DEVICE_ID_DM1105,		.subvendor = PCI_ANY_ID,		.subdevice = PCI_DEVICE_ID_DW2004,	}, {		/* empty */	},};MODULE_DEVICE_TABLE(pci, dm1105_id_table);static struct pci_driver dm1105_driver = {	.name = DRIVER_NAME,	.id_table = dm1105_id_table,	.probe = dm1105_probe,	.remove = __devexit_p(dm1105_remove),};static int __init dm1105_init(void){	return pci_register_driver(&dm1105_driver);}static void __exit dm1105_exit(void){	pci_unregister_driver(&dm1105_driver);}module_init(dm1105_init);module_exit(dm1105_exit);MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");MODULE_DESCRIPTION("SDMC DM1105 DVB driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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