diff options
Diffstat (limited to 'linux/drivers/media/dvb/b2c2/skystar2.c')
-rw-r--r-- | linux/drivers/media/dvb/b2c2/skystar2.c | 233 |
1 files changed, 120 insertions, 113 deletions
diff --git a/linux/drivers/media/dvb/b2c2/skystar2.c b/linux/drivers/media/dvb/b2c2/skystar2.c index 8677e752d..4490cbc86 100644 --- a/linux/drivers/media/dvb/b2c2/skystar2.c +++ b/linux/drivers/media/dvb/b2c2/skystar2.c @@ -2,7 +2,7 @@ * skystar2.c - driver for the Technisat SkyStar2 PCI DVB card * based on the FlexCopII by B2C2,Inc. * - * Copyright (C) 2003 V.C. , skystar@moldova.cc + * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -224,7 +224,7 @@ static u32 FLEXI2C_read(struct adapter * adapter, u32 device, u32 bus, u32 addr, u32 bytes_to_transfer; u8 *start; -// dprintk("%s:\n", __FUNCTION__); + dprintk("%s:\n", __FUNCTION__); start = buf; @@ -253,7 +253,7 @@ static u32 FLEXI2C_write(struct adapter * adapter, u32 device, u32 bus, u32 addr u32 bytes_to_transfer; u8 *start; -// dprintk("%s:\n", __FUNCTION__); + dprintk("%s:\n", __FUNCTION__); start = buf; @@ -284,59 +284,68 @@ static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg *msgs, int if (down_interruptible(&tmp->i2c_sem)) return -ERESTARTSYS; - if (0) { - dprintk("%s:\n", __FUNCTION__); + dprintk("%s: %d messages to transfer\n", __FUNCTION__, num); - for (i = 0; i < num; i++) { - printk("message %d: flags=%x, addr=0x%04x, buf=%p, len=%d \n", i, msgs[i].flags, msgs[i].addr, msgs[i].buf, msgs[i].len); + for (i = 0; i < num; 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); + + /* allow only the mt312 and stv0299 frontends to access the bus */ + if ((msgs[i].addr != 0x0E) && (msgs[i].addr != 0x68) && (msgs[i].addr != 0x61) ) + { + up(&tmp->i2c_sem); + + return -EREMOTEIO; } } - - /* allow only the vp310 frontend to access the bus */ - if ((msgs[0].addr != 0x0E) && (msgs[0].addr != 0x61)) { - up(&tmp->i2c_sem); - return -EREMOTEIO; - } + // read command + if ( (num == 2) && (msgs[0].flags == 0) && (msgs[1].flags == I2C_M_RD) && + (msgs[0].buf != NULL) && (msgs[1].buf != NULL) ) + { + ret = FLEXI2C_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len); - if ((num == 1) && (msgs[0].buf != NULL)) { - if (msgs[0].flags == I2C_M_RD) { - ret = -EINVAL; + up(&tmp->i2c_sem); - } else { + if (ret != msgs[1].len) + { + printk("%s: read error !\n", __FUNCTION__); - // single writes do have the reg addr in buf[0] and data in buf[1] to buf[n] - ret = FLEXI2C_write(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], &msgs[0].buf[1], msgs[0].len - 1); + printk("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); - if (ret != msgs[0].len - 1) - ret = -EREMOTEIO; - else - ret = num; - } + return -EREMOTEIO; + } + + return num; + } - } else if ((num == 2) && (msgs[1].buf != NULL)) { + // write command + for (i = 0; i < num; i++) { - // i2c reads consist of a reg addr _write_ followed by a data read, so msg[1].flags has to be examined - if (msgs[1].flags == I2C_M_RD) { - ret = FLEXI2C_read(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len); + if ( (msgs[i].flags != 0) || (msgs[i].buf == NULL) || ( msgs[i].len < 2 ) ) return -EINVAL; - } else { + ret = FLEXI2C_write(tmp, 0x10000000, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1); - ret = FLEXI2C_write(tmp, 0x10000000, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len); - } + up(&tmp->i2c_sem); - if (ret != msgs[1].len) - ret = -EREMOTEIO; - else - ret = num; - } + if (ret != msgs[0].len - 1) + { + printk("%s: write error %i !\n", __FUNCTION__, ret); - up(&tmp->i2c_sem); + printk("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; + } - /* master xfer functions always return the number of successfully - transmitted messages, not the number of transmitted bytes. - return -EREMOTEIO in case of failure. */ - return ret; + printk("%s: unknown command format !\n", __FUNCTION__); + + return -EINVAL; } /* SRAM (Skystar2 rev2.3 has one "ISSI IS61LV256" chip on board, @@ -811,31 +820,9 @@ static int EEPROM_LRC_write(struct adapter *adapter, u32 addr, u32 len, u8 * wbu } */ -/* These functions could be called from the initialization routine - to unlock SkyStar2 cards, locked by "Europe On Line". - - in cards from "Europe On Line" the key is: - - u8 key[20] = { - 0xB2, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - LRC = 0xB3; - - in unlocked cards the key is: - - u8 key[20] = { - 0xB2, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - }; - - LRC = 0xB2; -*/ + +/* These functions could be used to unlock SkyStar2 cards. */ + /* static int EEPROM_writeKey(struct adapter *adapter, u8 * key, u32 len) { @@ -854,7 +841,7 @@ static int EEPROM_writeKey(struct adapter *adapter, u8 * key, u32 len) return EEPROM_LRC_write(adapter, 0x3E4, 20, wbuf, rbuf, 4); } -*/ + static int EEPROM_readKey(struct adapter *adapter, u8 * key, u32 len) { u8 buf[20]; @@ -869,6 +856,7 @@ static int EEPROM_readKey(struct adapter *adapter, u8 * key, u32 len) return 1; } +*/ static int EEPROM_getMacAddr(struct adapter *adapter, char type, u8 * mac) { @@ -1839,9 +1827,9 @@ static void InterruptServiceDMA1(struct adapter *adapter) nNumNewBytesTransferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + nCurDmaCounter; } -// dprintk("%s: nCurDmaCounter = %d\n" , __FUNCTION__, nCurDmaCounter); -// dprintk("%s: dmaq1.tail = %d\n" , __FUNCTION__, adapter->dmaq1.tail): -// dprintk("%s: BytesTransferred = %d\n" , __FUNCTION__, nNumNewBytesTransferred); + dprintk("%s: nCurDmaCounter = %d\n" , __FUNCTION__, nCurDmaCounter); + dprintk("%s: dmaq1.tail = %d\n" , __FUNCTION__, adapter->dmaq1.tail); + dprintk("%s: BytesTransferred = %d\n" , __FUNCTION__, nNumNewBytesTransferred); if (nNumNewBytesTransferred < dwDefaultPacketSize) return; @@ -1871,12 +1859,13 @@ static void InterruptServiceDMA1(struct adapter *adapter) packet_header.continuity_counter = (*dq & 0x0F000000) >> 0x18; if ((packet_header.sync_byte == 0x47) && (packet_header.transport_error_indicator == 0) && (packet_header.pid != 0x1FFF)) { - if (CheckPID(adapter, packet_header.pid & 0x0000FFFF) != 0) { - dvb_dmx_swfilter_packets(dvbdmx, pbDMABufCurPos, dwDefaultPacketSize / 188); + if (CheckPID(adapter, packet_header.pid & 0x0000FFFF) != 0) + { + dvb_dmx_swfilter_packets(dvbdmx, pbDMABufCurPos, dwDefaultPacketSize / 188); } else { -// dprintk("%s: pid=%x\n", __FUNCTION__, packet_header.pid); + dprintk("%s: pid=%x\n", __FUNCTION__, packet_header.pid); } } } @@ -1901,7 +1890,7 @@ static irqreturn_t isr(int irq, void *dev_id, struct pt_regs *regs) u32 value; -// dprintk("%s:\n", __FUNCTION__); + dprintk("%s:\n", __FUNCTION__); spin_lock_irq(&tmp->lock); @@ -2075,8 +2064,7 @@ static int DriverInitialize(struct pci_dev * pdev) { struct adapter *adapter; u32 tmp; - u8 key[16]; - + if (!(adapter = kmalloc(sizeof(struct adapter), GFP_KERNEL))) { dprintk("%s: out of memory!\n", __FUNCTION__); @@ -2177,10 +2165,6 @@ static int DriverInitialize(struct pci_dev * pdev) CtrlEnableMAC(adapter, 1); } - EEPROM_readKey(adapter, key, 16); - - printk("%s key = \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n %02x %02x %02x %02x \n", __FUNCTION__, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], key[8], key[9], key[10], key[11], key[12], key[13], key[14], key[15]); - adapter->lock = SPIN_LOCK_UNLOCKED; return 0; @@ -2294,78 +2278,101 @@ static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void { struct adapter *adapter = fe->before_after_data; + struct dvb_frontend_info info; + switch (cmd) { - case FE_SLEEP: - { - printk("%s: FE_SLEEP\n", __FUNCTION__); - set_tuner_polarity(adapter, 0); + case FE_SLEEP: + { + dprintk("%s: FE_SLEEP\n", __FUNCTION__); - // return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend. - return -EOPNOTSUPP; - } + set_tuner_polarity(adapter, 0); - case FE_SET_VOLTAGE: - { - dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__); + // return -EOPNOTSUPP, to make DVB core also send "FE_SLEEP" command to frontend. + return -EOPNOTSUPP; + } - switch ((fe_sec_voltage_t) arg) { + case FE_SET_VOLTAGE: + { + dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__); + + switch ((fe_sec_voltage_t) arg) + { case SEC_VOLTAGE_13: - printk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13); + dprintk("%s: SEC_VOLTAGE_13, %x\n", __FUNCTION__, SEC_VOLTAGE_13); set_tuner_polarity(adapter, 1); - break; + return 0; case SEC_VOLTAGE_18: - printk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18); + dprintk("%s: SEC_VOLTAGE_18, %x\n", __FUNCTION__, SEC_VOLTAGE_18); set_tuner_polarity(adapter, 2); - break; + return 0; default: return -EINVAL; - }; + }; - break; - } + } + + case FE_SET_TONE: + { + dprintk("%s: FE_SET_TONE\n", __FUNCTION__); - case FE_SET_TONE: + fe->ioctl(fe, FE_GET_INFO, &info); + + if ( strcmp(info.name, "Zarlink MT312") == 0) { - dprintk("%s: FE_SET_TONE\n", __FUNCTION__); + dprintk("%s: FE_SET_TONE for %s frontend\n", __FUNCTION__, info.name); - switch ((fe_sec_tone_mode_t) arg) { + switch ((fe_sec_tone_mode_t) arg) + { case SEC_TONE_ON: - printk("%s: SEC_TONE_ON, %x\n", __FUNCTION__, SEC_TONE_ON); + dprintk("%s: SEC_TONE_ON, %x\n", __FUNCTION__, SEC_TONE_ON); - set_tuner_tone(adapter, 1); + set_tuner_tone(adapter, 1); - break; + return 0; case SEC_TONE_OFF: - printk("%s: SEC_TONE_OFF, %x\n", __FUNCTION__, SEC_TONE_OFF); + dprintk("%s: SEC_TONE_OFF, %x\n", __FUNCTION__, SEC_TONE_OFF); - set_tuner_tone(adapter, 0); + set_tuner_tone(adapter, 0); - break; + return 0; default: - return -EINVAL; - }; + return -EINVAL; + }; - break; - } + }; + + 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; + }; + + printk("%s: FE_SET_TONE unknown frontend : %s\n", __FUNCTION__, info.name); + + return -EINVAL; + } + + default: + + return -EOPNOTSUPP; - return -EOPNOTSUPP; }; return 0; |