Path: blob/master/drivers/media/dvb/dm1105/dm1105.c
15112 views
/*1* dm1105.c - driver for DVB cards based on SDMC DM1105 PCI chip2*3* Copyright (C) 2008 Igor M. Liplianin <[email protected]>4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (at your option) any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.18*19*/2021#include <linux/i2c.h>22#include <linux/i2c-algo-bit.h>23#include <linux/init.h>24#include <linux/kernel.h>25#include <linux/module.h>26#include <linux/proc_fs.h>27#include <linux/pci.h>28#include <linux/dma-mapping.h>29#include <linux/slab.h>30#include <media/rc-core.h>3132#include "demux.h"33#include "dmxdev.h"34#include "dvb_demux.h"35#include "dvb_frontend.h"36#include "dvb_net.h"37#include "dvbdev.h"38#include "dvb-pll.h"3940#include "stv0299.h"41#include "stv0288.h"42#include "stb6000.h"43#include "si21xx.h"44#include "cx24116.h"45#include "z0194a.h"46#include "ds3000.h"4748#define MODULE_NAME "dm1105"4950#define UNSET (-1U)5152#define DM1105_BOARD_NOAUTO UNSET53#define DM1105_BOARD_UNKNOWN 054#define DM1105_BOARD_DVBWORLD_2002 155#define DM1105_BOARD_DVBWORLD_2004 256#define DM1105_BOARD_AXESS_DM05 357#define DM1105_BOARD_UNBRANDED_I2C_ON_GPIO 45859/* ----------------------------------------------- */60/*61* PCI ID's62*/63#ifndef PCI_VENDOR_ID_TRIGEM64#define PCI_VENDOR_ID_TRIGEM 0x109f65#endif66#ifndef PCI_VENDOR_ID_AXESS67#define PCI_VENDOR_ID_AXESS 0x195d68#endif69#ifndef PCI_DEVICE_ID_DM110570#define PCI_DEVICE_ID_DM1105 0x036f71#endif72#ifndef PCI_DEVICE_ID_DW200273#define PCI_DEVICE_ID_DW2002 0x200274#endif75#ifndef PCI_DEVICE_ID_DW200476#define PCI_DEVICE_ID_DW2004 0x200477#endif78#ifndef PCI_DEVICE_ID_DM0579#define PCI_DEVICE_ID_DM05 0x110580#endif81/* ----------------------------------------------- */82/* sdmc dm1105 registers */8384/* TS Control */85#define DM1105_TSCTR 0x0086#define DM1105_DTALENTH 0x048788/* GPIO Interface */89#define DM1105_GPIOVAL 0x0890#define DM1105_GPIOCTR 0x0c9192/* PID serial number */93#define DM1105_PIDN 0x109495/* Odd-even secret key select */96#define DM1105_CWSEL 0x149798/* Host Command Interface */99#define DM1105_HOST_CTR 0x18100#define DM1105_HOST_AD 0x1c101102/* PCI Interface */103#define DM1105_CR 0x30104#define DM1105_RST 0x34105#define DM1105_STADR 0x38106#define DM1105_RLEN 0x3c107#define DM1105_WRP 0x40108#define DM1105_INTCNT 0x44109#define DM1105_INTMAK 0x48110#define DM1105_INTSTS 0x4c111112/* CW Value */113#define DM1105_ODD 0x50114#define DM1105_EVEN 0x58115116/* PID Value */117#define DM1105_PID 0x60118119/* IR Control */120#define DM1105_IRCTR 0x64121#define DM1105_IRMODE 0x68122#define DM1105_SYSTEMCODE 0x6c123#define DM1105_IRCODE 0x70124125/* Unknown Values */126#define DM1105_ENCRYPT 0x74127#define DM1105_VER 0x7c128129/* I2C Interface */130#define DM1105_I2CCTR 0x80131#define DM1105_I2CSTS 0x81132#define DM1105_I2CDAT 0x82133#define DM1105_I2C_RA 0x83134/* ----------------------------------------------- */135/* Interrupt Mask Bits */136137#define INTMAK_TSIRQM 0x01138#define INTMAK_HIRQM 0x04139#define INTMAK_IRM 0x08140#define INTMAK_ALLMASK (INTMAK_TSIRQM | \141INTMAK_HIRQM | \142INTMAK_IRM)143#define INTMAK_NONEMASK 0x00144145/* Interrupt Status Bits */146#define INTSTS_TSIRQ 0x01147#define INTSTS_HIRQ 0x04148#define INTSTS_IR 0x08149150/* IR Control Bits */151#define DM1105_IR_EN 0x01152#define DM1105_SYS_CHK 0x02153#define DM1105_REP_FLG 0x08154155/* EEPROM addr */156#define IIC_24C01_addr 0xa0157/* Max board count */158#define DM1105_MAX 0x04159160#define DRIVER_NAME "dm1105"161#define DM1105_I2C_GPIO_NAME "dm1105-gpio"162163#define DM1105_DMA_PACKETS 47164#define DM1105_DMA_PACKET_LENGTH (128*4)165#define DM1105_DMA_BYTES (128 * 4 * DM1105_DMA_PACKETS)166167/* */168#define GPIO08 (1 << 8)169#define GPIO13 (1 << 13)170#define GPIO14 (1 << 14)171#define GPIO15 (1 << 15)172#define GPIO16 (1 << 16)173#define GPIO17 (1 << 17)174#define GPIO_ALL 0x03ffff175176/* GPIO's for LNB power control */177#define DM1105_LNB_MASK (GPIO_ALL & ~(GPIO14 | GPIO13))178#define DM1105_LNB_OFF GPIO17179#define DM1105_LNB_13V (GPIO16 | GPIO08)180#define DM1105_LNB_18V GPIO08181182/* GPIO's for LNB power control for Axess DM05 */183#define DM05_LNB_MASK (GPIO_ALL & ~(GPIO14 | GPIO13))184#define DM05_LNB_OFF GPIO17/* actually 13v */185#define DM05_LNB_13V GPIO17186#define DM05_LNB_18V (GPIO17 | GPIO16)187188/* GPIO's for LNB power control for unbranded with I2C on GPIO */189#define UNBR_LNB_MASK (GPIO17 | GPIO16)190#define UNBR_LNB_OFF 0191#define UNBR_LNB_13V GPIO17192#define UNBR_LNB_18V (GPIO17 | GPIO16)193194static unsigned int card[] = {[0 ... 3] = UNSET };195module_param_array(card, int, NULL, 0444);196MODULE_PARM_DESC(card, "card type");197198static int ir_debug;199module_param(ir_debug, int, 0644);200MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");201202static unsigned int dm1105_devcount;203204DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);205206struct dm1105_board {207char *name;208struct {209u32 mask, off, v13, v18;210} lnb;211u32 gpio_scl, gpio_sda;212};213214struct dm1105_subid {215u16 subvendor;216u16 subdevice;217u32 card;218};219220static const struct dm1105_board dm1105_boards[] = {221[DM1105_BOARD_UNKNOWN] = {222.name = "UNKNOWN/GENERIC",223.lnb = {224.mask = DM1105_LNB_MASK,225.off = DM1105_LNB_OFF,226.v13 = DM1105_LNB_13V,227.v18 = DM1105_LNB_18V,228},229},230[DM1105_BOARD_DVBWORLD_2002] = {231.name = "DVBWorld PCI 2002",232.lnb = {233.mask = DM1105_LNB_MASK,234.off = DM1105_LNB_OFF,235.v13 = DM1105_LNB_13V,236.v18 = DM1105_LNB_18V,237},238},239[DM1105_BOARD_DVBWORLD_2004] = {240.name = "DVBWorld PCI 2004",241.lnb = {242.mask = DM1105_LNB_MASK,243.off = DM1105_LNB_OFF,244.v13 = DM1105_LNB_13V,245.v18 = DM1105_LNB_18V,246},247},248[DM1105_BOARD_AXESS_DM05] = {249.name = "Axess/EasyTv DM05",250.lnb = {251.mask = DM05_LNB_MASK,252.off = DM05_LNB_OFF,253.v13 = DM05_LNB_13V,254.v18 = DM05_LNB_18V,255},256},257[DM1105_BOARD_UNBRANDED_I2C_ON_GPIO] = {258.name = "Unbranded DM1105 with i2c on GPIOs",259.lnb = {260.mask = UNBR_LNB_MASK,261.off = UNBR_LNB_OFF,262.v13 = UNBR_LNB_13V,263.v18 = UNBR_LNB_18V,264},265.gpio_scl = GPIO14,266.gpio_sda = GPIO13,267},268};269270static const struct dm1105_subid dm1105_subids[] = {271{272.subvendor = 0x0000,273.subdevice = 0x2002,274.card = DM1105_BOARD_DVBWORLD_2002,275}, {276.subvendor = 0x0001,277.subdevice = 0x2002,278.card = DM1105_BOARD_DVBWORLD_2002,279}, {280.subvendor = 0x0000,281.subdevice = 0x2004,282.card = DM1105_BOARD_DVBWORLD_2004,283}, {284.subvendor = 0x0001,285.subdevice = 0x2004,286.card = DM1105_BOARD_DVBWORLD_2004,287}, {288.subvendor = 0x195d,289.subdevice = 0x1105,290.card = DM1105_BOARD_AXESS_DM05,291},292};293294static void dm1105_card_list(struct pci_dev *pci)295{296int i;297298if (0 == pci->subsystem_vendor &&2990 == pci->subsystem_device) {300printk(KERN_ERR301"dm1105: Your board has no valid PCI Subsystem ID\n"302"dm1105: and thus can't be autodetected\n"303"dm1105: Please pass card=<n> insmod option to\n"304"dm1105: workaround that. Redirect complaints to\n"305"dm1105: the vendor of the TV card. Best regards,\n"306"dm1105: -- tux\n");307} else {308printk(KERN_ERR309"dm1105: Your board isn't known (yet) to the driver.\n"310"dm1105: You can try to pick one of the existing\n"311"dm1105: card configs via card=<n> insmod option.\n"312"dm1105: Updating to the latest version might help\n"313"dm1105: as well.\n");314}315printk(KERN_ERR "Here is a list of valid choices for the card=<n> "316"insmod option:\n");317for (i = 0; i < ARRAY_SIZE(dm1105_boards); i++)318printk(KERN_ERR "dm1105: card=%d -> %s\n",319i, dm1105_boards[i].name);320}321322/* infrared remote control */323struct infrared {324struct rc_dev *dev;325char input_phys[32];326struct work_struct work;327u32 ir_command;328};329330struct dm1105_dev {331/* pci */332struct pci_dev *pdev;333u8 __iomem *io_mem;334335/* ir */336struct infrared ir;337338/* dvb */339struct dmx_frontend hw_frontend;340struct dmx_frontend mem_frontend;341struct dmxdev dmxdev;342struct dvb_adapter dvb_adapter;343struct dvb_demux demux;344struct dvb_frontend *fe;345struct dvb_net dvbnet;346unsigned int full_ts_users;347unsigned int boardnr;348int nr;349350/* i2c */351struct i2c_adapter i2c_adap;352struct i2c_adapter i2c_bb_adap;353struct i2c_algo_bit_data i2c_bit;354355/* irq */356struct work_struct work;357struct workqueue_struct *wq;358char wqn[16];359360/* dma */361dma_addr_t dma_addr;362unsigned char *ts_buf;363u32 wrp;364u32 nextwrp;365u32 buffer_size;366unsigned int PacketErrorCount;367unsigned int dmarst;368spinlock_t lock;369};370371#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))372373#define dm_readb(reg) inb(dm_io_mem(reg))374#define dm_writeb(reg, value) outb((value), (dm_io_mem(reg)))375376#define dm_readw(reg) inw(dm_io_mem(reg))377#define dm_writew(reg, value) outw((value), (dm_io_mem(reg)))378379#define dm_readl(reg) inl(dm_io_mem(reg))380#define dm_writel(reg, value) outl((value), (dm_io_mem(reg)))381382#define dm_andorl(reg, mask, value) \383outl((inl(dm_io_mem(reg)) & ~(mask)) |\384((value) & (mask)), (dm_io_mem(reg)))385386#define dm_setl(reg, bit) dm_andorl((reg), (bit), (bit))387#define dm_clearl(reg, bit) dm_andorl((reg), (bit), 0)388389/* The chip has 18 GPIOs. In HOST mode GPIO's used as 15 bit address lines,390so we can use only 3 GPIO's from GPIO15 to GPIO17.391Here I don't check whether HOST is enebled as it is not implemented yet.392*/393static void dm1105_gpio_set(struct dm1105_dev *dev, u32 mask)394{395if (mask & 0xfffc0000)396printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);397398if (mask & 0x0003ffff)399dm_setl(DM1105_GPIOVAL, mask & 0x0003ffff);400401}402403static void dm1105_gpio_clear(struct dm1105_dev *dev, u32 mask)404{405if (mask & 0xfffc0000)406printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);407408if (mask & 0x0003ffff)409dm_clearl(DM1105_GPIOVAL, mask & 0x0003ffff);410411}412413static void dm1105_gpio_andor(struct dm1105_dev *dev, u32 mask, u32 val)414{415if (mask & 0xfffc0000)416printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);417418if (mask & 0x0003ffff)419dm_andorl(DM1105_GPIOVAL, mask & 0x0003ffff, val);420421}422423static u32 dm1105_gpio_get(struct dm1105_dev *dev, u32 mask)424{425if (mask & 0xfffc0000)426printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);427428if (mask & 0x0003ffff)429return dm_readl(DM1105_GPIOVAL) & mask & 0x0003ffff;430431return 0;432}433434static void dm1105_gpio_enable(struct dm1105_dev *dev, u32 mask, int asoutput)435{436if (mask & 0xfffc0000)437printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);438439if ((mask & 0x0003ffff) && asoutput)440dm_clearl(DM1105_GPIOCTR, mask & 0x0003ffff);441else if ((mask & 0x0003ffff) && !asoutput)442dm_setl(DM1105_GPIOCTR, mask & 0x0003ffff);443444}445446static void dm1105_setline(struct dm1105_dev *dev, u32 line, int state)447{448if (state)449dm1105_gpio_enable(dev, line, 0);450else {451dm1105_gpio_enable(dev, line, 1);452dm1105_gpio_clear(dev, line);453}454}455456static void dm1105_setsda(void *data, int state)457{458struct dm1105_dev *dev = data;459460dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_sda, state);461}462463static void dm1105_setscl(void *data, int state)464{465struct dm1105_dev *dev = data;466467dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_scl, state);468}469470static int dm1105_getsda(void *data)471{472struct dm1105_dev *dev = data;473474return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_sda)475? 1 : 0;476}477478static int dm1105_getscl(void *data)479{480struct dm1105_dev *dev = data;481482return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_scl)483? 1 : 0;484}485486static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,487struct i2c_msg *msgs, int num)488{489struct dm1105_dev *dev ;490491int addr, rc, i, j, k, len, byte, data;492u8 status;493494dev = i2c_adap->algo_data;495for (i = 0; i < num; i++) {496dm_writeb(DM1105_I2CCTR, 0x00);497if (msgs[i].flags & I2C_M_RD) {498/* read bytes */499addr = msgs[i].addr << 1;500addr |= 1;501dm_writeb(DM1105_I2CDAT, addr);502for (byte = 0; byte < msgs[i].len; byte++)503dm_writeb(DM1105_I2CDAT + byte + 1, 0);504505dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);506for (j = 0; j < 55; j++) {507mdelay(10);508status = dm_readb(DM1105_I2CSTS);509if ((status & 0xc0) == 0x40)510break;511}512if (j >= 55)513return -1;514515for (byte = 0; byte < msgs[i].len; byte++) {516rc = dm_readb(DM1105_I2CDAT + byte + 1);517if (rc < 0)518goto err;519msgs[i].buf[byte] = rc;520}521} else if ((msgs[i].buf[0] == 0xf7) && (msgs[i].addr == 0x55)) {522/* prepaired for cx24116 firmware */523/* Write in small blocks */524len = msgs[i].len - 1;525k = 1;526do {527dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);528dm_writeb(DM1105_I2CDAT + 1, 0xf7);529for (byte = 0; byte < (len > 48 ? 48 : len); byte++) {530data = msgs[i].buf[k + byte];531dm_writeb(DM1105_I2CDAT + byte + 2, data);532}533dm_writeb(DM1105_I2CCTR, 0x82 + (len > 48 ? 48 : len));534for (j = 0; j < 25; j++) {535mdelay(10);536status = dm_readb(DM1105_I2CSTS);537if ((status & 0xc0) == 0x40)538break;539}540541if (j >= 25)542return -1;543544k += 48;545len -= 48;546} while (len > 0);547} else {548/* write bytes */549dm_writeb(DM1105_I2CDAT, msgs[i].addr << 1);550for (byte = 0; byte < msgs[i].len; byte++) {551data = msgs[i].buf[byte];552dm_writeb(DM1105_I2CDAT + byte + 1, data);553}554dm_writeb(DM1105_I2CCTR, 0x81 + msgs[i].len);555for (j = 0; j < 25; j++) {556mdelay(10);557status = dm_readb(DM1105_I2CSTS);558if ((status & 0xc0) == 0x40)559break;560}561562if (j >= 25)563return -1;564}565}566return num;567err:568return rc;569}570571static u32 functionality(struct i2c_adapter *adap)572{573return I2C_FUNC_I2C;574}575576static struct i2c_algorithm dm1105_algo = {577.master_xfer = dm1105_i2c_xfer,578.functionality = functionality,579};580581static inline struct dm1105_dev *feed_to_dm1105_dev(struct dvb_demux_feed *feed)582{583return container_of(feed->demux, struct dm1105_dev, demux);584}585586static inline struct dm1105_dev *frontend_to_dm1105_dev(struct dvb_frontend *fe)587{588return container_of(fe->dvb, struct dm1105_dev, dvb_adapter);589}590591static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)592{593struct dm1105_dev *dev = frontend_to_dm1105_dev(fe);594595dm1105_gpio_enable(dev, dm1105_boards[dev->boardnr].lnb.mask, 1);596if (voltage == SEC_VOLTAGE_18)597dm1105_gpio_andor(dev,598dm1105_boards[dev->boardnr].lnb.mask,599dm1105_boards[dev->boardnr].lnb.v18);600else if (voltage == SEC_VOLTAGE_13)601dm1105_gpio_andor(dev,602dm1105_boards[dev->boardnr].lnb.mask,603dm1105_boards[dev->boardnr].lnb.v13);604else605dm1105_gpio_andor(dev,606dm1105_boards[dev->boardnr].lnb.mask,607dm1105_boards[dev->boardnr].lnb.off);608609return 0;610}611612static void dm1105_set_dma_addr(struct dm1105_dev *dev)613{614dm_writel(DM1105_STADR, cpu_to_le32(dev->dma_addr));615}616617static int __devinit dm1105_dma_map(struct dm1105_dev *dev)618{619dev->ts_buf = pci_alloc_consistent(dev->pdev,6206 * DM1105_DMA_BYTES,621&dev->dma_addr);622623return !dev->ts_buf;624}625626static void dm1105_dma_unmap(struct dm1105_dev *dev)627{628pci_free_consistent(dev->pdev,6296 * DM1105_DMA_BYTES,630dev->ts_buf,631dev->dma_addr);632}633634static void dm1105_enable_irqs(struct dm1105_dev *dev)635{636dm_writeb(DM1105_INTMAK, INTMAK_ALLMASK);637dm_writeb(DM1105_CR, 1);638}639640static void dm1105_disable_irqs(struct dm1105_dev *dev)641{642dm_writeb(DM1105_INTMAK, INTMAK_IRM);643dm_writeb(DM1105_CR, 0);644}645646static int dm1105_start_feed(struct dvb_demux_feed *f)647{648struct dm1105_dev *dev = feed_to_dm1105_dev(f);649650if (dev->full_ts_users++ == 0)651dm1105_enable_irqs(dev);652653return 0;654}655656static int dm1105_stop_feed(struct dvb_demux_feed *f)657{658struct dm1105_dev *dev = feed_to_dm1105_dev(f);659660if (--dev->full_ts_users == 0)661dm1105_disable_irqs(dev);662663return 0;664}665666/* ir work handler */667static void dm1105_emit_key(struct work_struct *work)668{669struct infrared *ir = container_of(work, struct infrared, work);670u32 ircom = ir->ir_command;671u8 data;672673if (ir_debug)674printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);675676data = (ircom >> 8) & 0x7f;677678rc_keydown(ir->dev, data, 0);679}680681/* work handler */682static void dm1105_dmx_buffer(struct work_struct *work)683{684struct dm1105_dev *dev = container_of(work, struct dm1105_dev, work);685unsigned int nbpackets;686u32 oldwrp = dev->wrp;687u32 nextwrp = dev->nextwrp;688689if (!((dev->ts_buf[oldwrp] == 0x47) &&690(dev->ts_buf[oldwrp + 188] == 0x47) &&691(dev->ts_buf[oldwrp + 188 * 2] == 0x47))) {692dev->PacketErrorCount++;693/* bad packet found */694if ((dev->PacketErrorCount >= 2) &&695(dev->dmarst == 0)) {696dm_writeb(DM1105_RST, 1);697dev->wrp = 0;698dev->PacketErrorCount = 0;699dev->dmarst = 0;700return;701}702}703704if (nextwrp < oldwrp) {705memcpy(dev->ts_buf + dev->buffer_size, dev->ts_buf, nextwrp);706nbpackets = ((dev->buffer_size - oldwrp) + nextwrp) / 188;707} else708nbpackets = (nextwrp - oldwrp) / 188;709710dev->wrp = nextwrp;711dvb_dmx_swfilter_packets(&dev->demux, &dev->ts_buf[oldwrp], nbpackets);712}713714static irqreturn_t dm1105_irq(int irq, void *dev_id)715{716struct dm1105_dev *dev = dev_id;717718/* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */719unsigned int intsts = dm_readb(DM1105_INTSTS);720dm_writeb(DM1105_INTSTS, intsts);721722switch (intsts) {723case INTSTS_TSIRQ:724case (INTSTS_TSIRQ | INTSTS_IR):725dev->nextwrp = dm_readl(DM1105_WRP) - dm_readl(DM1105_STADR);726queue_work(dev->wq, &dev->work);727break;728case INTSTS_IR:729dev->ir.ir_command = dm_readl(DM1105_IRCODE);730schedule_work(&dev->ir.work);731break;732}733734return IRQ_HANDLED;735}736737int __devinit dm1105_ir_init(struct dm1105_dev *dm1105)738{739struct rc_dev *dev;740int err = -ENOMEM;741742dev = rc_allocate_device();743if (!dev)744return -ENOMEM;745746snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),747"pci-%s/ir0", pci_name(dm1105->pdev));748749dev->driver_name = MODULE_NAME;750dev->map_name = RC_MAP_DM1105_NEC;751dev->driver_type = RC_DRIVER_SCANCODE;752dev->input_name = "DVB on-card IR receiver";753dev->input_phys = dm1105->ir.input_phys;754dev->input_id.bustype = BUS_PCI;755dev->input_id.version = 1;756if (dm1105->pdev->subsystem_vendor) {757dev->input_id.vendor = dm1105->pdev->subsystem_vendor;758dev->input_id.product = dm1105->pdev->subsystem_device;759} else {760dev->input_id.vendor = dm1105->pdev->vendor;761dev->input_id.product = dm1105->pdev->device;762}763dev->dev.parent = &dm1105->pdev->dev;764765INIT_WORK(&dm1105->ir.work, dm1105_emit_key);766767err = rc_register_device(dev);768if (err < 0) {769rc_free_device(dev);770return err;771}772773dm1105->ir.dev = dev;774return 0;775}776777void __devexit dm1105_ir_exit(struct dm1105_dev *dm1105)778{779rc_unregister_device(dm1105->ir.dev);780}781782static int __devinit dm1105_hw_init(struct dm1105_dev *dev)783{784dm1105_disable_irqs(dev);785786dm_writeb(DM1105_HOST_CTR, 0);787788/*DATALEN 188,*/789dm_writeb(DM1105_DTALENTH, 188);790/*TS_STRT TS_VALP MSBFIRST TS_MODE ALPAS TSPES*/791dm_writew(DM1105_TSCTR, 0xc10a);792793/* map DMA and set address */794dm1105_dma_map(dev);795dm1105_set_dma_addr(dev);796/* big buffer */797dm_writel(DM1105_RLEN, 5 * DM1105_DMA_BYTES);798dm_writeb(DM1105_INTCNT, 47);799800/* IR NEC mode enable */801dm_writeb(DM1105_IRCTR, (DM1105_IR_EN | DM1105_SYS_CHK));802dm_writeb(DM1105_IRMODE, 0);803dm_writew(DM1105_SYSTEMCODE, 0);804805return 0;806}807808static void dm1105_hw_exit(struct dm1105_dev *dev)809{810dm1105_disable_irqs(dev);811812/* IR disable */813dm_writeb(DM1105_IRCTR, 0);814dm_writeb(DM1105_INTMAK, INTMAK_NONEMASK);815816dm1105_dma_unmap(dev);817}818819static struct stv0299_config sharp_z0194a_config = {820.demod_address = 0x68,821.inittab = sharp_z0194a_inittab,822.mclk = 88000000UL,823.invert = 1,824.skip_reinit = 0,825.lock_output = STV0299_LOCKOUTPUT_1,826.volt13_op0_op1 = STV0299_VOLT13_OP1,827.min_delay_ms = 100,828.set_symbol_rate = sharp_z0194a_set_symbol_rate,829};830831static struct stv0288_config earda_config = {832.demod_address = 0x68,833.min_delay_ms = 100,834};835836static struct si21xx_config serit_config = {837.demod_address = 0x68,838.min_delay_ms = 100,839840};841842static struct cx24116_config serit_sp2633_config = {843.demod_address = 0x55,844};845846static struct ds3000_config dvbworld_ds3000_config = {847.demod_address = 0x68,848};849850static int __devinit frontend_init(struct dm1105_dev *dev)851{852int ret;853854switch (dev->boardnr) {855case DM1105_BOARD_UNBRANDED_I2C_ON_GPIO:856dm1105_gpio_enable(dev, GPIO15, 1);857dm1105_gpio_clear(dev, GPIO15);858msleep(100);859dm1105_gpio_set(dev, GPIO15);860msleep(200);861dev->fe = dvb_attach(862stv0299_attach, &sharp_z0194a_config,863&dev->i2c_bb_adap);864if (dev->fe) {865dev->fe->ops.set_voltage = dm1105_set_voltage;866dvb_attach(dvb_pll_attach, dev->fe, 0x60,867&dev->i2c_bb_adap, DVB_PLL_OPERA1);868break;869}870871dev->fe = dvb_attach(872stv0288_attach, &earda_config,873&dev->i2c_bb_adap);874if (dev->fe) {875dev->fe->ops.set_voltage = dm1105_set_voltage;876dvb_attach(stb6000_attach, dev->fe, 0x61,877&dev->i2c_bb_adap);878break;879}880881dev->fe = dvb_attach(882si21xx_attach, &serit_config,883&dev->i2c_bb_adap);884if (dev->fe)885dev->fe->ops.set_voltage = dm1105_set_voltage;886break;887case DM1105_BOARD_DVBWORLD_2004:888dev->fe = dvb_attach(889cx24116_attach, &serit_sp2633_config,890&dev->i2c_adap);891if (dev->fe) {892dev->fe->ops.set_voltage = dm1105_set_voltage;893break;894}895896dev->fe = dvb_attach(897ds3000_attach, &dvbworld_ds3000_config,898&dev->i2c_adap);899if (dev->fe)900dev->fe->ops.set_voltage = dm1105_set_voltage;901902break;903case DM1105_BOARD_DVBWORLD_2002:904case DM1105_BOARD_AXESS_DM05:905default:906dev->fe = dvb_attach(907stv0299_attach, &sharp_z0194a_config,908&dev->i2c_adap);909if (dev->fe) {910dev->fe->ops.set_voltage = dm1105_set_voltage;911dvb_attach(dvb_pll_attach, dev->fe, 0x60,912&dev->i2c_adap, DVB_PLL_OPERA1);913break;914}915916dev->fe = dvb_attach(917stv0288_attach, &earda_config,918&dev->i2c_adap);919if (dev->fe) {920dev->fe->ops.set_voltage = dm1105_set_voltage;921dvb_attach(stb6000_attach, dev->fe, 0x61,922&dev->i2c_adap);923break;924}925926dev->fe = dvb_attach(927si21xx_attach, &serit_config,928&dev->i2c_adap);929if (dev->fe)930dev->fe->ops.set_voltage = dm1105_set_voltage;931932}933934if (!dev->fe) {935dev_err(&dev->pdev->dev, "could not attach frontend\n");936return -ENODEV;937}938939ret = dvb_register_frontend(&dev->dvb_adapter, dev->fe);940if (ret < 0) {941if (dev->fe->ops.release)942dev->fe->ops.release(dev->fe);943dev->fe = NULL;944return ret;945}946947return 0;948}949950static void __devinit dm1105_read_mac(struct dm1105_dev *dev, u8 *mac)951{952static u8 command[1] = { 0x28 };953954struct i2c_msg msg[] = {955{956.addr = IIC_24C01_addr >> 1,957.flags = 0,958.buf = command,959.len = 1960}, {961.addr = IIC_24C01_addr >> 1,962.flags = I2C_M_RD,963.buf = mac,964.len = 6965},966};967968dm1105_i2c_xfer(&dev->i2c_adap, msg , 2);969dev_info(&dev->pdev->dev, "MAC %pM\n", mac);970}971972static int __devinit dm1105_probe(struct pci_dev *pdev,973const struct pci_device_id *ent)974{975struct dm1105_dev *dev;976struct dvb_adapter *dvb_adapter;977struct dvb_demux *dvbdemux;978struct dmx_demux *dmx;979int ret = -ENOMEM;980int i;981982dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL);983if (!dev)984return -ENOMEM;985986/* board config */987dev->nr = dm1105_devcount;988dev->boardnr = UNSET;989if (card[dev->nr] < ARRAY_SIZE(dm1105_boards))990dev->boardnr = card[dev->nr];991for (i = 0; UNSET == dev->boardnr &&992i < ARRAY_SIZE(dm1105_subids); i++)993if (pdev->subsystem_vendor ==994dm1105_subids[i].subvendor &&995pdev->subsystem_device ==996dm1105_subids[i].subdevice)997dev->boardnr = dm1105_subids[i].card;998999if (UNSET == dev->boardnr) {1000dev->boardnr = DM1105_BOARD_UNKNOWN;1001dm1105_card_list(pdev);1002}10031004dm1105_devcount++;1005dev->pdev = pdev;1006dev->buffer_size = 5 * DM1105_DMA_BYTES;1007dev->PacketErrorCount = 0;1008dev->dmarst = 0;10091010ret = pci_enable_device(pdev);1011if (ret < 0)1012goto err_kfree;10131014ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));1015if (ret < 0)1016goto err_pci_disable_device;10171018pci_set_master(pdev);10191020ret = pci_request_regions(pdev, DRIVER_NAME);1021if (ret < 0)1022goto err_pci_disable_device;10231024dev->io_mem = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));1025if (!dev->io_mem) {1026ret = -EIO;1027goto err_pci_release_regions;1028}10291030spin_lock_init(&dev->lock);1031pci_set_drvdata(pdev, dev);10321033ret = dm1105_hw_init(dev);1034if (ret < 0)1035goto err_pci_iounmap;10361037/* i2c */1038i2c_set_adapdata(&dev->i2c_adap, dev);1039strcpy(dev->i2c_adap.name, DRIVER_NAME);1040dev->i2c_adap.owner = THIS_MODULE;1041dev->i2c_adap.dev.parent = &pdev->dev;1042dev->i2c_adap.algo = &dm1105_algo;1043dev->i2c_adap.algo_data = dev;1044ret = i2c_add_adapter(&dev->i2c_adap);10451046if (ret < 0)1047goto err_dm1105_hw_exit;10481049i2c_set_adapdata(&dev->i2c_bb_adap, dev);1050strcpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME);1051dev->i2c_bb_adap.owner = THIS_MODULE;1052dev->i2c_bb_adap.dev.parent = &pdev->dev;1053dev->i2c_bb_adap.algo_data = &dev->i2c_bit;1054dev->i2c_bit.data = dev;1055dev->i2c_bit.setsda = dm1105_setsda;1056dev->i2c_bit.setscl = dm1105_setscl;1057dev->i2c_bit.getsda = dm1105_getsda;1058dev->i2c_bit.getscl = dm1105_getscl;1059dev->i2c_bit.udelay = 10;1060dev->i2c_bit.timeout = 10;10611062/* Raise SCL and SDA */1063dm1105_setsda(dev, 1);1064dm1105_setscl(dev, 1);10651066ret = i2c_bit_add_bus(&dev->i2c_bb_adap);1067if (ret < 0)1068goto err_i2c_del_adapter;10691070/* dvb */1071ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME,1072THIS_MODULE, &pdev->dev, adapter_nr);1073if (ret < 0)1074goto err_i2c_del_adapters;10751076dvb_adapter = &dev->dvb_adapter;10771078dm1105_read_mac(dev, dvb_adapter->proposed_mac);10791080dvbdemux = &dev->demux;1081dvbdemux->filternum = 256;1082dvbdemux->feednum = 256;1083dvbdemux->start_feed = dm1105_start_feed;1084dvbdemux->stop_feed = dm1105_stop_feed;1085dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |1086DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);1087ret = dvb_dmx_init(dvbdemux);1088if (ret < 0)1089goto err_dvb_unregister_adapter;10901091dmx = &dvbdemux->dmx;1092dev->dmxdev.filternum = 256;1093dev->dmxdev.demux = dmx;1094dev->dmxdev.capabilities = 0;10951096ret = dvb_dmxdev_init(&dev->dmxdev, dvb_adapter);1097if (ret < 0)1098goto err_dvb_dmx_release;10991100dev->hw_frontend.source = DMX_FRONTEND_0;11011102ret = dmx->add_frontend(dmx, &dev->hw_frontend);1103if (ret < 0)1104goto err_dvb_dmxdev_release;11051106dev->mem_frontend.source = DMX_MEMORY_FE;11071108ret = dmx->add_frontend(dmx, &dev->mem_frontend);1109if (ret < 0)1110goto err_remove_hw_frontend;11111112ret = dmx->connect_frontend(dmx, &dev->hw_frontend);1113if (ret < 0)1114goto err_remove_mem_frontend;11151116ret = frontend_init(dev);1117if (ret < 0)1118goto err_disconnect_frontend;11191120dvb_net_init(dvb_adapter, &dev->dvbnet, dmx);1121dm1105_ir_init(dev);11221123INIT_WORK(&dev->work, dm1105_dmx_buffer);1124sprintf(dev->wqn, "%s/%d", dvb_adapter->name, dvb_adapter->num);1125dev->wq = create_singlethread_workqueue(dev->wqn);1126if (!dev->wq)1127goto err_dvb_net;11281129ret = request_irq(pdev->irq, dm1105_irq, IRQF_SHARED,1130DRIVER_NAME, dev);1131if (ret < 0)1132goto err_workqueue;11331134return 0;11351136err_workqueue:1137destroy_workqueue(dev->wq);1138err_dvb_net:1139dvb_net_release(&dev->dvbnet);1140err_disconnect_frontend:1141dmx->disconnect_frontend(dmx);1142err_remove_mem_frontend:1143dmx->remove_frontend(dmx, &dev->mem_frontend);1144err_remove_hw_frontend:1145dmx->remove_frontend(dmx, &dev->hw_frontend);1146err_dvb_dmxdev_release:1147dvb_dmxdev_release(&dev->dmxdev);1148err_dvb_dmx_release:1149dvb_dmx_release(dvbdemux);1150err_dvb_unregister_adapter:1151dvb_unregister_adapter(dvb_adapter);1152err_i2c_del_adapters:1153i2c_del_adapter(&dev->i2c_bb_adap);1154err_i2c_del_adapter:1155i2c_del_adapter(&dev->i2c_adap);1156err_dm1105_hw_exit:1157dm1105_hw_exit(dev);1158err_pci_iounmap:1159pci_iounmap(pdev, dev->io_mem);1160err_pci_release_regions:1161pci_release_regions(pdev);1162err_pci_disable_device:1163pci_disable_device(pdev);1164err_kfree:1165pci_set_drvdata(pdev, NULL);1166kfree(dev);1167return ret;1168}11691170static void __devexit dm1105_remove(struct pci_dev *pdev)1171{1172struct dm1105_dev *dev = pci_get_drvdata(pdev);1173struct dvb_adapter *dvb_adapter = &dev->dvb_adapter;1174struct dvb_demux *dvbdemux = &dev->demux;1175struct dmx_demux *dmx = &dvbdemux->dmx;11761177dm1105_ir_exit(dev);1178dmx->close(dmx);1179dvb_net_release(&dev->dvbnet);1180if (dev->fe)1181dvb_unregister_frontend(dev->fe);11821183dmx->disconnect_frontend(dmx);1184dmx->remove_frontend(dmx, &dev->mem_frontend);1185dmx->remove_frontend(dmx, &dev->hw_frontend);1186dvb_dmxdev_release(&dev->dmxdev);1187dvb_dmx_release(dvbdemux);1188dvb_unregister_adapter(dvb_adapter);1189if (&dev->i2c_adap)1190i2c_del_adapter(&dev->i2c_adap);11911192dm1105_hw_exit(dev);1193synchronize_irq(pdev->irq);1194free_irq(pdev->irq, dev);1195pci_iounmap(pdev, dev->io_mem);1196pci_release_regions(pdev);1197pci_disable_device(pdev);1198pci_set_drvdata(pdev, NULL);1199dm1105_devcount--;1200kfree(dev);1201}12021203static struct pci_device_id dm1105_id_table[] __devinitdata = {1204{1205.vendor = PCI_VENDOR_ID_TRIGEM,1206.device = PCI_DEVICE_ID_DM1105,1207.subvendor = PCI_ANY_ID,1208.subdevice = PCI_ANY_ID,1209}, {1210.vendor = PCI_VENDOR_ID_AXESS,1211.device = PCI_DEVICE_ID_DM05,1212.subvendor = PCI_ANY_ID,1213.subdevice = PCI_ANY_ID,1214}, {1215/* empty */1216},1217};12181219MODULE_DEVICE_TABLE(pci, dm1105_id_table);12201221static struct pci_driver dm1105_driver = {1222.name = DRIVER_NAME,1223.id_table = dm1105_id_table,1224.probe = dm1105_probe,1225.remove = __devexit_p(dm1105_remove),1226};12271228static int __init dm1105_init(void)1229{1230return pci_register_driver(&dm1105_driver);1231}12321233static void __exit dm1105_exit(void)1234{1235pci_unregister_driver(&dm1105_driver);1236}12371238module_init(dm1105_init);1239module_exit(dm1105_exit);12401241MODULE_AUTHOR("Igor M. Liplianin <[email protected]>");1242MODULE_DESCRIPTION("SDMC DM1105 DVB driver");1243MODULE_LICENSE("GPL");124412451246