|
@@ -48,14 +48,12 @@
|
|
|
#include "ngene-ioctls.h"
|
|
|
#endif
|
|
|
|
|
|
-#define FW_INC 1
|
|
|
+/* #define FW_INC 1 */
|
|
|
#ifdef FW_INC
|
|
|
#include "ngene_fw_15.h"
|
|
|
#include "ngene_fw_16.h"
|
|
|
#include "ngene_fw_17.h"
|
|
|
|
|
|
-DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
|
|
-
|
|
|
static int load_firmware;
|
|
|
module_param(load_firmware, int, 0444);
|
|
|
MODULE_PARM_DESC(load_firmware, "Try to load firmware from file.");
|
|
@@ -73,6 +71,8 @@ static int debug;
|
|
|
module_param(debug, int, 0444);
|
|
|
MODULE_PARM_DESC(debug, "Print debugging information.");
|
|
|
|
|
|
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
|
|
+
|
|
|
#define dprintk if (debug) printk
|
|
|
|
|
|
#define DEVICE_NAME "ngene"
|
|
@@ -670,15 +670,6 @@ static void FillTSBuffer(void *Buffer, int Length, u32 Flags)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void clear_tsin(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- struct SBufferHeader *Cur = chan->nextBuffer;
|
|
|
-
|
|
|
- do {
|
|
|
- memset(&Cur->ngeneBuffer.SR, 0, sizeof(Cur->ngeneBuffer.SR));
|
|
|
- Cur = Cur->Next;
|
|
|
- } while (Cur != chan->nextBuffer);
|
|
|
-}
|
|
|
|
|
|
static void flush_buffers(struct ngene_channel *chan)
|
|
|
{
|
|
@@ -952,37 +943,6 @@ done:
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int ngene_i2c_algo_control(struct i2c_adapter *adap,
|
|
|
- unsigned int cmd, unsigned long arg)
|
|
|
-{
|
|
|
- struct ngene_channel *chan =
|
|
|
- (struct ngene_channel *)i2c_get_adapdata(adap);
|
|
|
-
|
|
|
- switch (cmd) {
|
|
|
- case IOCTL_MIC_TUN_RDY:
|
|
|
- chan->tun_rdy = 1;
|
|
|
- if (chan->dec_rdy == 1)
|
|
|
- chan->tun_dec_rdy = 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case IOCTL_MIC_DEC_RDY:
|
|
|
- chan->dec_rdy = 1;
|
|
|
- if (chan->tun_rdy == 1)
|
|
|
- chan->tun_dec_rdy = 1;
|
|
|
- break;
|
|
|
-
|
|
|
- case IOCTL_MIC_TUN_DETECT:
|
|
|
- {
|
|
|
- int *palorbtsc = (int *)arg;
|
|
|
- *palorbtsc = chan->dev->card_info->ntsc;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
static u32 ngene_i2c_functionality(struct i2c_adapter *adap)
|
|
|
{
|
|
@@ -994,16 +954,6 @@ struct i2c_algorithm ngene_i2c_algo = {
|
|
|
.functionality = ngene_i2c_functionality,
|
|
|
};
|
|
|
|
|
|
-static int ngene_i2c_attach(struct i2c_client *client)
|
|
|
-{
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int ngene_i2c_detach(struct i2c_client *client)
|
|
|
-{
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
static int ngene_i2c_init(struct ngene *dev, int dev_nr)
|
|
|
{
|
|
|
struct i2c_adapter *adap = &(dev->channel[dev_nr].i2c_adapter);
|
|
@@ -1018,8 +968,6 @@ static int ngene_i2c_init(struct ngene *dev, int dev_nr)
|
|
|
strcpy(adap->name, "nGene");
|
|
|
|
|
|
adap->id = I2C_HW_SAA7146;
|
|
|
- adap->client_register = ngene_i2c_attach;
|
|
|
- adap->client_unregister = ngene_i2c_detach;
|
|
|
adap->algo = &ngene_i2c_algo;
|
|
|
adap->algo_data = (void *)&(dev->channel[dev_nr]);
|
|
|
|
|
@@ -1040,20 +988,6 @@ int i2c_write(struct i2c_adapter *adapter, u8 adr, u8 data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int i2c_write_register(struct i2c_adapter *adapter,
|
|
|
- u8 adr, u8 reg, u8 data)
|
|
|
-{
|
|
|
- u8 m[2] = {reg, data};
|
|
|
- struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2};
|
|
|
-
|
|
|
- if (i2c_transfer(adapter, &msg, 1) != 1) {
|
|
|
- printk(KERN_ERR DEVICE_NAME
|
|
|
- ": Failed to write to I2C register %02x@%02x!\n",
|
|
|
- reg, adr);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
static int i2c_write_read(struct i2c_adapter *adapter,
|
|
|
u8 adr, u8 *w, u8 wlen, u8 *r, u8 rlen)
|
|
@@ -1143,146 +1077,6 @@ static int i2c_read_eeprom(struct i2c_adapter *adapter,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int ReadEEProm(struct i2c_adapter *adapter,
|
|
|
- u16 Tag, u32 MaxLen, u8 *data, u32 *pLength)
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- u16 Addr = MICNG_EE_START, Length, tag = 0;
|
|
|
- u8 EETag[3];
|
|
|
-
|
|
|
- while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
|
|
|
- if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
|
|
|
- return -1;
|
|
|
- tag = (EETag[0] << 8) | EETag[1];
|
|
|
- if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
|
|
|
- return -1;
|
|
|
- if (tag == Tag)
|
|
|
- break;
|
|
|
- Addr += sizeof(u16) + 1 + EETag[2];
|
|
|
- }
|
|
|
- if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
|
|
|
- printk(KERN_ERR DEVICE_NAME
|
|
|
- ": Reached EOEE @ Tag = %04x Length = %3d\n",
|
|
|
- tag, EETag[2]);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- Length = EETag[2];
|
|
|
- if (Length > MaxLen)
|
|
|
- Length = (u16) MaxLen;
|
|
|
- if (Length > 0) {
|
|
|
- Addr += sizeof(u16) + 1;
|
|
|
- status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
|
|
|
- if (!status) {
|
|
|
- *pLength = EETag[2];
|
|
|
- if (Length < EETag[2])
|
|
|
- ; /*status=STATUS_BUFFER_OVERFLOW; */
|
|
|
- }
|
|
|
- }
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-static int WriteEEProm(struct i2c_adapter *adapter,
|
|
|
- u16 Tag, u32 Length, u8 *data)
|
|
|
-{
|
|
|
- int status = 0;
|
|
|
- u16 Addr = MICNG_EE_START;
|
|
|
- u8 EETag[3];
|
|
|
- u16 tag = 0;
|
|
|
- int retry, i;
|
|
|
-
|
|
|
- while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
|
|
|
- if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
|
|
|
- return -1;
|
|
|
- tag = (EETag[0] << 8) | EETag[1];
|
|
|
- if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
|
|
|
- return -1;
|
|
|
- if (tag == Tag)
|
|
|
- break;
|
|
|
- Addr += sizeof(u16) + 1 + EETag[2];
|
|
|
- }
|
|
|
- if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
|
|
|
- printk(KERN_ERR DEVICE_NAME
|
|
|
- ": Reached EOEE @ Tag = %04x Length = %3d\n",
|
|
|
- tag, EETag[2]);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (Length > EETag[2])
|
|
|
- return -EINVAL;
|
|
|
- /* Note: We write the data one byte at a time to avoid
|
|
|
- issues with page sizes. (which are different for
|
|
|
- each manufacture and eeprom size)
|
|
|
- */
|
|
|
- Addr += sizeof(u16) + 1;
|
|
|
- for (i = 0; i < Length; i++, Addr++) {
|
|
|
- status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]);
|
|
|
-
|
|
|
- if (status)
|
|
|
- break;
|
|
|
-
|
|
|
- /* Poll for finishing write cycle */
|
|
|
- retry = 10;
|
|
|
- while (retry) {
|
|
|
- u8 Tmp;
|
|
|
-
|
|
|
- msleep(50);
|
|
|
- status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1);
|
|
|
- if (status)
|
|
|
- break;
|
|
|
- if (Tmp != data[i])
|
|
|
- printk(KERN_ERR DEVICE_NAME
|
|
|
- "eeprom write error\n");
|
|
|
- retry -= 1;
|
|
|
- }
|
|
|
- if (status) {
|
|
|
- printk(KERN_ERR DEVICE_NAME
|
|
|
- ": Timeout polling eeprom\n");
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return status;
|
|
|
-}
|
|
|
-
|
|
|
-static void i2c_init_eeprom(struct i2c_adapter *adapter)
|
|
|
-{
|
|
|
- u8 tags[] = {0x10, 0x00, 0x02, 0x00, 0x00,
|
|
|
- 0x10, 0x01, 0x02, 0x00, 0x00,
|
|
|
- 0x00, 0x00, 0x00};
|
|
|
-
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; i < sizeof(tags); i++)
|
|
|
- i2c_write_eeprom(adapter, 0x50, 0x0100 + i, tags[i]);
|
|
|
-}
|
|
|
-
|
|
|
-static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data)
|
|
|
-{
|
|
|
- int stat;
|
|
|
- u8 buf[2];
|
|
|
- u32 len = 0;
|
|
|
-
|
|
|
- stat = ReadEEProm(adapter, tag, 2, buf, &len);
|
|
|
- if (stat)
|
|
|
- return stat;
|
|
|
- if (len != 2)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- *data = (buf[0] << 8) | buf[1];
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data)
|
|
|
-{
|
|
|
- int stat;
|
|
|
- u8 buf[2];
|
|
|
-
|
|
|
- buf[0] = data >> 8;
|
|
|
- buf[1] = data & 0xff;
|
|
|
- stat = WriteEEProm(adapter, tag, 2, buf);
|
|
|
- if (stat)
|
|
|
- return stat;
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
static int i2c_dump_eeprom(struct i2c_adapter *adapter, u8 adr)
|
|
|
{
|
|
@@ -1665,36 +1459,6 @@ static void swap_buffer(u32 *p, u32 len)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void *ain_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
|
|
|
-{
|
|
|
- struct ngene_channel *chan = priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
-
|
|
|
- if (dvb_ringbuffer_free(&dev->ain_rbuf) >= len) {
|
|
|
- dvb_ringbuffer_write(&dev->ain_rbuf, buf, len);
|
|
|
- wake_up_interruptible(&dev->ain_rbuf.queue);
|
|
|
- } else
|
|
|
- printk(KERN_INFO DEVICE_NAME ": Dropped ain packet.\n");
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static void *vcap_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
|
|
|
-{
|
|
|
-
|
|
|
- struct ngene_channel *chan = priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
-
|
|
|
- if (len >= 1920 * 1080)
|
|
|
- len = 1920 * 1080;
|
|
|
- if (dvb_ringbuffer_free(&dev->vin_rbuf) >= len) {
|
|
|
- dvb_ringbuffer_write(&dev->vin_rbuf, buf, len);
|
|
|
- wake_up_interruptible(&dev->vin_rbuf.queue);
|
|
|
- } else {
|
|
|
- ;/*printk(KERN_INFO DEVICE_NAME ": Dropped vcap packet.\n"); */
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
static void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
|
|
|
{
|
|
@@ -1728,15 +1492,6 @@ static void *tsout_exchange(void *priv, void *buf, u32 len,
|
|
|
return buf;
|
|
|
}
|
|
|
|
|
|
-static void set_dto(struct ngene_channel *chan, u32 rate)
|
|
|
-{
|
|
|
- u64 val = rate * 0x89705f41ULL; /* times val for 2^26 Hz */
|
|
|
-
|
|
|
- val = ((val >> 25) + 1) >> 1;
|
|
|
- chan->AudioDTOValue = (u32) val;
|
|
|
- /* chan->AudioDTOUpdated=1; */
|
|
|
- /* printk(KERN_INFO DEVICE_NAME ": Setting DTO to %08x\n", val); */
|
|
|
-}
|
|
|
|
|
|
static void set_transfer(struct ngene_channel *chan, int state)
|
|
|
{
|
|
@@ -1814,6 +1569,7 @@ static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|
|
{
|
|
|
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
|
|
|
struct ngene_channel *chan = dvbdmx->priv;
|
|
|
+#ifdef NGENE_COMMAND_API
|
|
|
struct ngene *dev = chan->dev;
|
|
|
|
|
|
if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) {
|
|
@@ -1838,6 +1594,7 @@ static int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
if (chan->users == 0) {
|
|
|
set_transfer(chan, 1);
|
|
@@ -1851,6 +1608,7 @@ static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|
|
{
|
|
|
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
|
|
|
struct ngene_channel *chan = dvbdmx->priv;
|
|
|
+#ifdef NGENE_COMMAND_API
|
|
|
struct ngene *dev = chan->dev;
|
|
|
|
|
|
if (dev->card_info->io_type[chan->number] & NGENE_IO_TSOUT) {
|
|
@@ -1870,6 +1628,7 @@ static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
if (--chan->users)
|
|
|
return chan->users;
|
|
@@ -1879,186 +1638,7 @@ static int ngene_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static int write_demod(struct i2c_adapter *adapter, u8 adr, u16 reg, u16 data)
|
|
|
-{
|
|
|
- u8 mm[5] = { 0x10, (reg >> 8) & 0xff, reg & 0xff,
|
|
|
- (data >> 8) & 0xff, data & 0xff};
|
|
|
- struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = mm, .len = 5 };
|
|
|
-
|
|
|
- if (i2c_transfer(adapter, &msg, 1) != 1) {
|
|
|
- printk(KERN_ERR DEVICE_NAME ": error in write_demod\n");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static int ngene_drxd_pll_set(struct ngene_channel *chan,
|
|
|
- u8 *pll, u8 *aux, u8 plladr)
|
|
|
-{
|
|
|
- struct i2c_adapter *adap = &chan->i2c_adapter;
|
|
|
- struct i2c_msg msg_pll = {.addr = plladr, .flags = 0, .buf = pll,
|
|
|
- .len = 4};
|
|
|
- struct i2c_msg msg_aux = {.addr = plladr, .flags = 0, .buf = aux,
|
|
|
- .len = 2};
|
|
|
- int err = 0;
|
|
|
-
|
|
|
- if (chan->dev->card_info->i2c_access & 1)
|
|
|
- down(&chan->dev->pll_mutex);
|
|
|
-
|
|
|
- chan->fe->ops.i2c_gate_ctrl(chan->fe, 1);
|
|
|
- err = i2c_transfer(adap, &msg_pll, 1);
|
|
|
- if (err != 1)
|
|
|
- goto error;
|
|
|
- if (aux)
|
|
|
- err = i2c_transfer(adap, &msg_aux, 1);
|
|
|
-error:
|
|
|
- chan->fe->ops.i2c_gate_ctrl(chan->fe, 0);
|
|
|
- if (chan->dev->card_info->i2c_access & 1)
|
|
|
- up(&chan->dev->pll_mutex);
|
|
|
- return err;
|
|
|
-}
|
|
|
-
|
|
|
-static int ngene_pll_set_th_dtt7520x(void *priv, void *priv_params,
|
|
|
- u8 plladr, u8 dadr, s32 *off)
|
|
|
-{
|
|
|
- struct dvb_frontend_parameters *params = priv_params;
|
|
|
- struct ngene_channel *chan = priv;
|
|
|
-
|
|
|
- u32 freq = params->frequency;
|
|
|
- u8 pll[4], aux[2];
|
|
|
- u8 c1, c2;
|
|
|
- u32 div;
|
|
|
-
|
|
|
- if (freq < 185000000 || freq > 900000000)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- if (freq < 465000000)
|
|
|
- c2 = 0x12;
|
|
|
- else
|
|
|
- c2 = 0x18;
|
|
|
-
|
|
|
- if (freq < 305000000)
|
|
|
- c1 = 0xb4;
|
|
|
- else if (freq < 405000000)
|
|
|
- c1 = 0xbc;
|
|
|
- else if (freq < 445000000)
|
|
|
- c1 = 0xf4;
|
|
|
- else if (freq < 465000000)
|
|
|
- c1 = 0xfc;
|
|
|
- else if (freq < 735000000)
|
|
|
- c1 = 0xbc;
|
|
|
- else if (freq < 835000000)
|
|
|
- c1 = 0xf4;
|
|
|
- else
|
|
|
- c1 = 0xfc;
|
|
|
-
|
|
|
- if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
|
|
|
- c2 ^= 0x10;
|
|
|
-
|
|
|
- div = (freq + 36000000 + 166667 / 2) / 166667;
|
|
|
- *off = ((s32) div) * 166667 - (s32) freq - 36000000;
|
|
|
-
|
|
|
- pll[0] = (div >> 8) & 0x7f;
|
|
|
- pll[1] = div & 0xff;
|
|
|
- pll[2] = c1;
|
|
|
- pll[3] = c2;
|
|
|
-
|
|
|
- aux[0] = (c1 & 0xc7) | 0x98;
|
|
|
- aux[1] = 0x30;
|
|
|
-
|
|
|
- return ngene_drxd_pll_set(chan, pll, aux, plladr);
|
|
|
-}
|
|
|
-
|
|
|
-static int ngene_pll_set_mt_3x0823(void *priv,
|
|
|
- void *priv_params,
|
|
|
- u8 plladr, u8 dadr, s32 *off)
|
|
|
-{
|
|
|
- struct dvb_frontend_parameters *params = priv_params;
|
|
|
- struct ngene_channel *chan = priv;
|
|
|
- struct i2c_adapter *adap = &chan->i2c_adapter;
|
|
|
- u32 freq = params->frequency;
|
|
|
- u8 pll[4];
|
|
|
- u8 aux[2];
|
|
|
- u8 c1, c2;
|
|
|
- u32 div;
|
|
|
-
|
|
|
- if (freq < 47125000 || freq > 855250000)
|
|
|
- return -EINVAL;
|
|
|
- else if (freq < 120000000) {
|
|
|
- c1 = 0xcc;
|
|
|
- c2 = 0x01;
|
|
|
- } else if (freq < 155500000) {
|
|
|
- c1 = 0xfc;
|
|
|
- c2 = 0x01;
|
|
|
- } else if (freq < 300000000) {
|
|
|
- c1 = 0xbc;
|
|
|
- c2 = 0x02;
|
|
|
- } else if (freq < 467000000) {
|
|
|
- c1 = 0xcc;
|
|
|
- c2 = 0x02;
|
|
|
- } else {
|
|
|
- c1 = 0xcc;
|
|
|
- c2 = 0x04;
|
|
|
- }
|
|
|
-
|
|
|
- if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ)
|
|
|
- c2 |= 0x08;
|
|
|
-
|
|
|
-#define INTERFREQ (36000000)
|
|
|
-
|
|
|
- div = (freq + INTERFREQ + 166667 / 2) / 166667;
|
|
|
-
|
|
|
- *off = ((s32) div) * 166667 - (s32) freq - INTERFREQ;
|
|
|
-
|
|
|
- pll[0] = (div >> 8) & 0x7f;
|
|
|
- pll[1] = div & 0xff;
|
|
|
- pll[2] = c1;
|
|
|
- pll[3] = c2;
|
|
|
-
|
|
|
- aux[0] = (c1 & 0xc7) | 0x98;
|
|
|
- aux[1] = 0x20;
|
|
|
-
|
|
|
- write_demod(adap, dadr, 0x1007, 0xc27);
|
|
|
-
|
|
|
- switch (params->u.ofdm.bandwidth) {
|
|
|
- case BANDWIDTH_7_MHZ:
|
|
|
- write_demod(adap, dadr, 0x0020, 0x103);
|
|
|
- break;
|
|
|
- case BANDWIDTH_AUTO:
|
|
|
- case BANDWIDTH_8_MHZ:
|
|
|
- write_demod(adap, dadr, 0x0020, 0x003);
|
|
|
- break;
|
|
|
- case BANDWIDTH_6_MHZ:
|
|
|
- write_demod(adap, dadr, 0x0020, 0x002);
|
|
|
- /*write_demod(adap, dadr, 0x1022, 397);*/
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return ngene_drxd_pll_set(chan, pll, aux, plladr);
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-static s16 osc_deviation(void *priv, s16 deviation, int flag)
|
|
|
-{
|
|
|
- struct ngene_channel *chan = priv;
|
|
|
- struct i2c_adapter *adap = &chan->i2c_adapter;
|
|
|
- u16 data = 0;
|
|
|
-
|
|
|
- if (flag) {
|
|
|
- data = (u16) deviation;
|
|
|
- printk(KERN_INFO DEVICE_NAME ": write deviation %d\n",
|
|
|
- deviation);
|
|
|
- eeprom_write_ushort(adap, 0x1000 + chan->number, data);
|
|
|
- } else {
|
|
|
- if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data))
|
|
|
- data = 0;
|
|
|
- printk(KERN_INFO DEVICE_NAME ": read deviation %d\n",
|
|
|
- (s16) data);
|
|
|
- }
|
|
|
|
|
|
- return (s16) data;
|
|
|
-}
|
|
|
|
|
|
static int write_to_decoder(struct dvb_demux_feed *feed,
|
|
|
const u8 *buf, size_t len)
|
|
@@ -2175,8 +1755,6 @@ int dec_fw_boot(struct ngene *dev)
|
|
|
u32 size;
|
|
|
const struct firmware *fw = NULL;
|
|
|
u8 *dec_fw;
|
|
|
- char *fw_name;
|
|
|
- int err, version;
|
|
|
|
|
|
if (request_firmware(&fw, DECYPHER_FW, &dev->pci_dev->dev) < 0) {
|
|
|
printk(KERN_ERR DEVICE_NAME
|
|
@@ -2188,7 +1766,7 @@ int dec_fw_boot(struct ngene *dev)
|
|
|
DECYPHER_FW);
|
|
|
|
|
|
size = fw->size;
|
|
|
- dec_fw = fw->data;
|
|
|
+ dec_fw = (u8 *)fw->data;
|
|
|
dec_fw_send(dev, dec_fw, size);
|
|
|
release_firmware(fw);
|
|
|
return 0;
|
|
@@ -2487,83 +2065,6 @@ static u32 Buffer2Sizes[MAX_STREAM] = {
|
|
|
0
|
|
|
};
|
|
|
|
|
|
-static int allocate_buffer(struct pci_dev *pci_dev, dma_addr_t of,
|
|
|
- struct SRingBufferDescriptor *rbuf,
|
|
|
- u32 entries, u32 size1, u32 size2)
|
|
|
-{
|
|
|
- if (create_ring_buffer(pci_dev, rbuf, entries) < 0)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- if (AllocateRingBuffers(pci_dev, of, rbuf, size1, size2) < 0)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int channel_allocate_buffers(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- int type = dev->card_info->io_type[chan->number];
|
|
|
- int status;
|
|
|
-
|
|
|
- chan->State = KSSTATE_STOP;
|
|
|
-
|
|
|
- if (type & (NGENE_IO_TV | NGENE_IO_HDTV | NGENE_IO_AIN)) {
|
|
|
- status = create_ring_buffer(dev->pci_dev,
|
|
|
- &chan->RingBuffer,
|
|
|
- RingBufferSizes[chan->number]);
|
|
|
- if (status < 0)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- if (type & (NGENE_IO_TV | NGENE_IO_AIN)) {
|
|
|
- status = AllocateRingBuffers(dev->pci_dev,
|
|
|
- dev->PAOverflowBuffer,
|
|
|
- &chan->RingBuffer,
|
|
|
- Buffer1Sizes[chan->number],
|
|
|
- Buffer2Sizes[chan->
|
|
|
- number]);
|
|
|
- if (status < 0)
|
|
|
- return -ENOMEM;
|
|
|
- } else if (type & NGENE_IO_HDTV) {
|
|
|
- status = AllocateRingBuffers(dev->pci_dev,
|
|
|
- dev->PAOverflowBuffer,
|
|
|
- &chan->RingBuffer,
|
|
|
- MAX_HDTV_BUFFER_SIZE, 0);
|
|
|
- if (status < 0)
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (type & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
|
|
|
-
|
|
|
- status = create_ring_buffer(dev->pci_dev,
|
|
|
- &chan->TSRingBuffer, RING_SIZE_TS);
|
|
|
- if (status < 0)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- status = AllocateRingBuffers(dev->pci_dev,
|
|
|
- dev->PAOverflowBuffer,
|
|
|
- &chan->TSRingBuffer,
|
|
|
- MAX_TS_BUFFER_SIZE, 0);
|
|
|
- if (status)
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
-
|
|
|
- if (type & NGENE_IO_TSOUT) {
|
|
|
- status = create_ring_buffer(dev->pci_dev,
|
|
|
- &chan->TSIdleBuffer, 1);
|
|
|
- if (status < 0)
|
|
|
- return -ENOMEM;
|
|
|
- status = AllocateRingBuffers(dev->pci_dev,
|
|
|
- dev->PAOverflowBuffer,
|
|
|
- &chan->TSIdleBuffer,
|
|
|
- MAX_TS_BUFFER_SIZE, 0);
|
|
|
- if (status)
|
|
|
- return -ENOMEM;
|
|
|
- FillTSIdleBuffer(&chan->TSIdleBuffer, &chan->TSRingBuffer);
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
static int AllocCommonBuffers(struct ngene *dev)
|
|
|
{
|
|
@@ -2737,18 +2238,12 @@ static int ngene_load_firm(struct ngene *dev)
|
|
|
default:
|
|
|
case 15:
|
|
|
version = 15;
|
|
|
- ngene_fw = FW15;
|
|
|
- size = sizeof(FW15);
|
|
|
fw_name = "ngene_15.fw";
|
|
|
break;
|
|
|
case 16:
|
|
|
- ngene_fw = FW16;
|
|
|
- size = sizeof(FW16);
|
|
|
fw_name = "ngene_16.fw";
|
|
|
break;
|
|
|
case 17:
|
|
|
- ngene_fw = FW17;
|
|
|
- size = sizeof(FW17);
|
|
|
fw_name = "ngene_17.fw";
|
|
|
break;
|
|
|
}
|
|
@@ -2776,7 +2271,7 @@ static int ngene_load_firm(struct ngene *dev)
|
|
|
}
|
|
|
printk(KERN_INFO DEVICE_NAME ": Loading firmware file %s.\n", fw_name);
|
|
|
size = fw->size;
|
|
|
- ngene_fw = fw->data;
|
|
|
+ ngene_fw = (u8 *) fw->data;
|
|
|
err = ngene_command_load_firmware(dev, ngene_fw, size);
|
|
|
release_firmware(fw);
|
|
|
#endif
|
|
@@ -2843,9 +2338,6 @@ static int ngene_start(struct ngene *dev)
|
|
|
{6144 / 64, 0, 0, 2048 / 64, 2048 / 64, 2048 / 64};
|
|
|
u8 tsin4_config[6] =
|
|
|
{3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0};
|
|
|
- u8 ts5_config[6] =
|
|
|
- {2048 / 64, 2048 / 64, 0, 2048 / 64, 2048 / 64,
|
|
|
- 2048 / 64};
|
|
|
u8 default_config[6] =
|
|
|
{4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0};
|
|
|
u8 *bconf = default_config;
|
|
@@ -2883,546 +2375,23 @@ fail:
|
|
|
return stat;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/****************************************************************************/
|
|
|
-/* DVB audio/video device functions *****************************************/
|
|
|
+/* Switch control (I2C gates, etc.) *****************************************/
|
|
|
/****************************************************************************/
|
|
|
|
|
|
-static ssize_t audio_write(struct file *file,
|
|
|
- const char *buf, size_t count, loff_t *ppos)
|
|
|
-{
|
|
|
- return -EINVAL;
|
|
|
-}
|
|
|
|
|
|
-ssize_t audio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- int left;
|
|
|
- int avail;
|
|
|
+/****************************************************************************/
|
|
|
+/* Demod/tuner attachment ***************************************************/
|
|
|
+/****************************************************************************/
|
|
|
|
|
|
- left = count;
|
|
|
- while (left) {
|
|
|
- if (wait_event_interruptible(
|
|
|
- dev->ain_rbuf.queue,
|
|
|
- dvb_ringbuffer_avail(&dev->ain_rbuf) > 0) < 0)
|
|
|
- return -EAGAIN;
|
|
|
- avail = dvb_ringbuffer_avail(&dev->ain_rbuf);
|
|
|
- if (avail > left)
|
|
|
- avail = left;
|
|
|
- dvb_ringbuffer_read_user(&dev->ain_rbuf, buf, avail);
|
|
|
- left -= avail;
|
|
|
- buf += avail;
|
|
|
- }
|
|
|
- return count;
|
|
|
-}
|
|
|
|
|
|
-static int audio_open(struct inode *inode, struct file *file)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- struct ngene_channel *chan2 = &chan->dev->channel[2];
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = dvb_generic_open(inode, file);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
- my_dvb_ringbuffer_flush(&dev->ain_rbuf);
|
|
|
-
|
|
|
- chan2->Capture1Length = MAX_AUDIO_BUFFER_SIZE;
|
|
|
- chan2->pBufferExchange = ain_exchange;
|
|
|
- ngene_command_stream_control(chan2->dev, chan2->number, 0x80,
|
|
|
- SMODE_AUDIO_CAPTURE, 0);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static int audio_release(struct inode *inode, struct file *file)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- struct ngene_channel *chan2 = &chan->dev->channel[2];
|
|
|
-
|
|
|
- ngene_command_stream_control(dev, 2, 0, 0, 0);
|
|
|
- chan2->pBufferExchange = 0;
|
|
|
-
|
|
|
- return dvb_generic_release(inode, file);
|
|
|
-}
|
|
|
-
|
|
|
-static const struct file_operations audio_fops = {
|
|
|
- .owner = THIS_MODULE,
|
|
|
- .read = audio_read,
|
|
|
- .write = audio_write,
|
|
|
- .open = audio_open,
|
|
|
- .release = audio_release,
|
|
|
-};
|
|
|
-
|
|
|
-static struct dvb_device dvbdev_audio = {
|
|
|
- .priv = 0,
|
|
|
- .readers = -1,
|
|
|
- .writers = 1,
|
|
|
- .users = 1,
|
|
|
- .fops = &audio_fops,
|
|
|
-};
|
|
|
-
|
|
|
-static int video_open(struct inode *inode, struct file *file)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- struct ngene_channel *chan0 = &chan->dev->channel[0];
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = dvb_generic_open(inode, file);
|
|
|
- if (ret < 0)
|
|
|
- return ret;
|
|
|
- if ((file->f_flags & O_ACCMODE) != O_RDONLY)
|
|
|
- return ret;
|
|
|
- my_dvb_ringbuffer_flush(&dev->vin_rbuf);
|
|
|
-
|
|
|
- chan0->nBytesPerLine = 1920 * 2;
|
|
|
- chan0->nLines = 540;
|
|
|
- chan0->Capture1Length = 1920 * 2 * 540;
|
|
|
- chan0->pBufferExchange = vcap_exchange;
|
|
|
- chan0->itumode = 2;
|
|
|
- ngene_command_stream_control(chan0->dev, chan0->number,
|
|
|
- 0x80, SMODE_VIDEO_CAPTURE, 0);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static int video_release(struct inode *inode, struct file *file)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- struct ngene_channel *chan0 = &chan->dev->channel[0];
|
|
|
-
|
|
|
- ngene_command_stream_control(dev, 0, 0, 0, 0);
|
|
|
- chan0->pBufferExchange = 0;
|
|
|
-
|
|
|
- return dvb_generic_release(inode, file);
|
|
|
-}
|
|
|
-
|
|
|
-static ssize_t video_write(struct file *file,
|
|
|
- const char *buf, size_t count, loff_t *ppos)
|
|
|
-{
|
|
|
- return -EINVAL;
|
|
|
-}
|
|
|
-
|
|
|
-ssize_t video_read(struct file *file, char *buf, size_t count, loff_t *ppos)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- int left, avail;
|
|
|
-
|
|
|
- left = count;
|
|
|
- while (left) {
|
|
|
- if (wait_event_interruptible(
|
|
|
- dev->vin_rbuf.queue,
|
|
|
- dvb_ringbuffer_avail(&dev->vin_rbuf) > 0) < 0)
|
|
|
- return -EAGAIN;
|
|
|
- avail = dvb_ringbuffer_avail(&dev->vin_rbuf);
|
|
|
- if (avail > left)
|
|
|
- avail = left;
|
|
|
- dvb_ringbuffer_read_user(&dev->vin_rbuf, buf, avail);
|
|
|
- left -= avail;
|
|
|
- buf += avail;
|
|
|
- }
|
|
|
- return count;
|
|
|
-}
|
|
|
-
|
|
|
-/* Why is this not exported from dvb_core ?!?! */
|
|
|
-
|
|
|
-static int dvb_usercopy2(struct inode *inode, struct file *file,
|
|
|
- unsigned int cmd, unsigned long arg,
|
|
|
- int (*func)(struct inode *inode, struct file *file,
|
|
|
- unsigned int cmd, void *arg))
|
|
|
-{
|
|
|
- char sbuf[128];
|
|
|
- void *mbuf = NULL;
|
|
|
- void *parg = NULL;
|
|
|
- int err = -EINVAL;
|
|
|
-
|
|
|
- /* Copy arguments into temp kernel buffer */
|
|
|
- switch (_IOC_DIR(cmd)) {
|
|
|
- case _IOC_NONE:
|
|
|
- /*
|
|
|
- * For this command, the pointer is actually an integer
|
|
|
- * argument.
|
|
|
- */
|
|
|
- parg = (void *)arg;
|
|
|
- break;
|
|
|
- case _IOC_READ: /* some v4l ioctls are marked wrong ... */
|
|
|
- case _IOC_WRITE:
|
|
|
- case (_IOC_WRITE | _IOC_READ):
|
|
|
- if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
|
|
|
- parg = sbuf;
|
|
|
- } else {
|
|
|
- /* too big to allocate from stack */
|
|
|
- mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
|
|
|
- if (NULL == mbuf)
|
|
|
- return -ENOMEM;
|
|
|
- parg = mbuf;
|
|
|
- }
|
|
|
-
|
|
|
- err = -EFAULT;
|
|
|
- if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
|
|
|
- goto out;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- /* call driver */
|
|
|
- err = func(inode, file, cmd, parg);
|
|
|
- if (err == -ENOIOCTLCMD)
|
|
|
- err = -EINVAL;
|
|
|
-
|
|
|
- if (err < 0)
|
|
|
- goto out;
|
|
|
-
|
|
|
- /* Copy results into user buffer */
|
|
|
- switch (_IOC_DIR(cmd)) {
|
|
|
- case _IOC_READ:
|
|
|
- case (_IOC_WRITE | _IOC_READ):
|
|
|
- if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
|
|
|
- err = -EFAULT;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
-out:
|
|
|
- kfree(mbuf);
|
|
|
- return err;
|
|
|
-}
|
|
|
-
|
|
|
-static int video_do_ioctl(struct inode *inode, struct file *file,
|
|
|
- unsigned int cmd, void *parg)
|
|
|
-{
|
|
|
- struct dvb_device *dvbdev = file->private_data;
|
|
|
- struct ngene_channel *chan = dvbdev->priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- int ret = 0;
|
|
|
- unsigned long arg = (unsigned long)parg;
|
|
|
-
|
|
|
- switch (cmd) {
|
|
|
- case VIDEO_SET_STREAMTYPE:
|
|
|
- switch (arg) {
|
|
|
- case VIDEO_CAP_MPEG2:
|
|
|
- /* printk(KERN_INFO DEVICE_NAME ": setting MPEG2\n"); */
|
|
|
- send_cli(dev, "vdec mpeg2\n");
|
|
|
- break;
|
|
|
- case VIDEO_CAP_AVC:
|
|
|
- /* printk(KERN_INFO DEVICE_NAME ": setting H264\n"); */
|
|
|
- send_cli(dev, "vdec h264\n");
|
|
|
- break;
|
|
|
- case VIDEO_CAP_VC1:
|
|
|
- /* printk(KERN_INFO DEVICE_NAME ": setting VC1\n"); */
|
|
|
- send_cli(dev, "vdec vc1\n");
|
|
|
- break;
|
|
|
- default:
|
|
|
- ret = -EINVAL;
|
|
|
- break;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- ret = -ENOIOCTLCMD;
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static int video_ioctl(struct inode *inode, struct file *file,
|
|
|
- unsigned int cmd, unsigned long arg)
|
|
|
-{
|
|
|
- return dvb_usercopy2(inode, file, cmd, arg, video_do_ioctl);
|
|
|
-}
|
|
|
-
|
|
|
-static const struct file_operations video_fops = {
|
|
|
- .owner = THIS_MODULE,
|
|
|
- .read = video_read,
|
|
|
- .write = video_write,
|
|
|
- .open = video_open,
|
|
|
- .release = video_release,
|
|
|
- .ioctl = video_ioctl,
|
|
|
-};
|
|
|
-
|
|
|
-static struct dvb_device dvbdev_video = {
|
|
|
- .priv = 0,
|
|
|
- .readers = -1,
|
|
|
- .writers = 1,
|
|
|
- .users = -1,
|
|
|
- .fops = &video_fops,
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-/* LNBH21 *******************************************************************/
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static int lnbh21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
|
|
|
-{
|
|
|
- struct ngene_channel *chan =
|
|
|
- *(struct ngene_channel **) fe->demodulator_priv;
|
|
|
-
|
|
|
- switch (voltage) {
|
|
|
- case SEC_VOLTAGE_OFF:
|
|
|
- chan->lnbh &= 0xf3;
|
|
|
- break;
|
|
|
- case SEC_VOLTAGE_13:
|
|
|
- chan->lnbh |= 0x04;
|
|
|
- chan->lnbh &= ~0x08;
|
|
|
- break;
|
|
|
- case SEC_VOLTAGE_18:
|
|
|
- chan->lnbh |= 0x0c;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
- };
|
|
|
- chan->lnbh |= 0x10;
|
|
|
- return i2c_write(&chan->i2c_adapter,
|
|
|
- chan->dev->card_info->lnb[chan->number], chan->lnbh);
|
|
|
-}
|
|
|
-
|
|
|
-static int lnbh21_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
|
|
-{
|
|
|
- struct ngene_channel *chan =
|
|
|
- *(struct ngene_channel **)fe->demodulator_priv;
|
|
|
-
|
|
|
- switch (tone) {
|
|
|
- case SEC_TONE_ON:
|
|
|
- chan->lnbh |= 0x20;
|
|
|
- break;
|
|
|
- case SEC_TONE_OFF:
|
|
|
- chan->lnbh &= 0xdf;
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- return i2c_write(&chan->i2c_adapter,
|
|
|
- chan->dev->card_info->lnb[chan->number], chan->lnbh);
|
|
|
-}
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-/* Switch control (I2C gates, etc.) *****************************************/
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static int avf_output(struct ngene_channel *chan, int state)
|
|
|
-{
|
|
|
- if (chan->dev->card_info->avf[chan->number])
|
|
|
- i2c_write_register(&chan->i2c_adapter,
|
|
|
- chan->dev->card_info->avf[chan->number],
|
|
|
- 0xf2, state ? 0x89 : 0x80);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/* Viper expander: sw11,sw12,sw21,sw22,i2csw1,i2csw2,tsen1,tsen2 */
|
|
|
-
|
|
|
-static int exp_set(struct ngene *dev)
|
|
|
-{
|
|
|
- return i2c_write(&dev->channel[0].i2c_adapter,
|
|
|
- dev->card_info->exp, dev->exp_val);
|
|
|
-}
|
|
|
-
|
|
|
-static int exp_init(struct ngene *dev)
|
|
|
-{
|
|
|
- if (!dev->card_info->exp)
|
|
|
- return 0;
|
|
|
- dev->exp_val = dev->card_info->exp_init;
|
|
|
- return exp_set(dev);
|
|
|
-}
|
|
|
-
|
|
|
-static int exp_set_bit(struct ngene *dev, int bit, int val)
|
|
|
-{
|
|
|
- if (val)
|
|
|
- set_bit(bit, &dev->exp_val);
|
|
|
- else
|
|
|
- clear_bit(bit, &dev->exp_val);
|
|
|
- return exp_set(dev);
|
|
|
-}
|
|
|
-
|
|
|
-static int viper_switch_ctrl(struct ngene_channel *chan, int type, int val)
|
|
|
-{
|
|
|
- switch (type) {
|
|
|
- case 0: /* I2C tuner gate on/off */
|
|
|
- return exp_set_bit(chan->dev, 4 + chan->number, val);
|
|
|
- case 1: /* Stream: 0=TS 1=ITU */
|
|
|
- avf_output(chan, val);
|
|
|
- return exp_set_bit(chan->dev, 6 + chan->number, val);
|
|
|
- case 2: /* Input: 0=digital 1=analog antenna input */
|
|
|
- exp_set_bit(chan->dev, 0 + chan->number * 2, val ? 0 : 1);
|
|
|
- exp_set_bit(chan->dev, 1 + chan->number * 2, val ? 1 : 0);
|
|
|
- break;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int viper_switch_ctrl2(struct ngene_channel *chan, int type, int val)
|
|
|
-{
|
|
|
- switch (type) {
|
|
|
- case 0: /* I2C tuner gate on/off */
|
|
|
- return exp_set_bit(chan->dev, 4 + chan->number, val);
|
|
|
- case 1: /* Stream: 0=TS 1=ITU */
|
|
|
- avf_output(chan, val);
|
|
|
- return exp_set_bit(chan->dev, 6 + chan->number, val);
|
|
|
- case 2: /* Input: 0=digital 1=analog antenna input */
|
|
|
- exp_set_bit(chan->dev, 0 + chan->number * 2, val ? 0 : 1);
|
|
|
- exp_set_bit(chan->dev, 1 + chan->number * 2, 0);
|
|
|
- break;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int viper_gate_ctrl(struct dvb_frontend *fe, int enable)
|
|
|
-{
|
|
|
- /* Well, just abuse sec :-) */
|
|
|
- struct ngene_channel *chan = fe->sec_priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
-
|
|
|
- return dev->card_info->switch_ctrl(chan, 0, enable);
|
|
|
-}
|
|
|
-
|
|
|
-static int python_switch_ctrl(struct ngene_channel *chan, int type, int val)
|
|
|
-{
|
|
|
- switch (type) {
|
|
|
- case 0: /* I2C tuner gate on/off */
|
|
|
- if (chan->number > 1)
|
|
|
- return -EINVAL;
|
|
|
- return ngene_command_gpio_set(chan->dev, 3 + chan->number, val);
|
|
|
- case 1: /* Stream: 0=TS 1=ITU */
|
|
|
- avf_output(chan, val);
|
|
|
- return 0;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int viper_reset_xc(struct dvb_frontend *fe)
|
|
|
-{
|
|
|
- struct ngene_channel *chan = fe->sec_priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
-
|
|
|
- printk(KERN_INFO DEVICE_NAME ": Reset XC3028\n");
|
|
|
-
|
|
|
- if (chan->number > 1)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- ngene_command_gpio_set(dev, 3 + chan->number, 0);
|
|
|
- msleep(150);
|
|
|
- ngene_command_gpio_set(dev, 3 + chan->number, 1);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int python_gate_ctrl(struct dvb_frontend *fe, int enable)
|
|
|
-{
|
|
|
- struct ngene_channel *chan = fe->sec_priv;
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
-
|
|
|
- if (chan->number == 0)
|
|
|
- return ngene_command_gpio_set(dev, 3, enable);
|
|
|
- if (chan->number == 1)
|
|
|
- return ngene_command_gpio_set(dev, 4, enable);
|
|
|
- return -EINVAL;
|
|
|
-}
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-/* Demod/tuner attachment ***************************************************/
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static int tuner_attach_mt2060(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- void *tconf = dev->card_info->tuner_config[chan->number];
|
|
|
- u8 drxa = dev->card_info->demoda[chan->number];
|
|
|
- struct dvb_frontend *fe = chan->fe, *fe2;
|
|
|
-
|
|
|
- fe->sec_priv = chan;
|
|
|
- fe->ops.i2c_gate_ctrl = dev->card_info->gate_ctrl;
|
|
|
-
|
|
|
- dev->card_info->gate_ctrl(fe, 1);
|
|
|
- fe2 = mt2060_attach(fe, &chan->i2c_adapter, tconf, 1220);
|
|
|
- dev->card_info->gate_ctrl(fe, 0);
|
|
|
-
|
|
|
- i2c_write_register(&chan->i2c_adapter, drxa, 3, 4);
|
|
|
- write_demod(&chan->i2c_adapter, drxa, 0x1012, 15);
|
|
|
- write_demod(&chan->i2c_adapter, drxa, 0x1007, 0xc27);
|
|
|
- write_demod(&chan->i2c_adapter, drxa, 0x0020, 0x003);
|
|
|
-
|
|
|
- return fe2 ? 0 : -ENODEV;
|
|
|
-}
|
|
|
-
|
|
|
-static int tuner_attach_xc3028(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- struct ngene *dev = chan->dev;
|
|
|
- void *tconf = dev->card_info->tuner_config[chan->number];
|
|
|
- struct dvb_frontend *fe = chan->fe, *fe2;
|
|
|
-
|
|
|
- fe->sec_priv = chan;
|
|
|
- fe->ops.i2c_gate_ctrl = dev->card_info->gate_ctrl;
|
|
|
-
|
|
|
- dev->card_info->gate_ctrl(fe, 1);
|
|
|
- fe2 = xc3028_attach(fe, &chan->i2c_adapter, tconf);
|
|
|
- dev->card_info->gate_ctrl(fe, 0);
|
|
|
-
|
|
|
- /*chan->fe->ops.tuner_ops.set_frequency(chan->fe,231250000);*/
|
|
|
-
|
|
|
- return fe2 ? 0 : -ENODEV;
|
|
|
-}
|
|
|
-
|
|
|
-static int demod_attach_drxd(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- void *feconf = chan->dev->card_info->fe_config[chan->number];
|
|
|
-
|
|
|
- chan->fe = drxd_attach(feconf,
|
|
|
- chan, &chan->i2c_adapter,
|
|
|
- &chan->dev->pci_dev->dev);
|
|
|
- return (chan->fe) ? 0 : -ENODEV;
|
|
|
-}
|
|
|
-
|
|
|
-static int demod_attach_drxh(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- void *feconf = chan->dev->card_info->fe_config[chan->number];
|
|
|
-
|
|
|
- chan->fe = drxh_attach(feconf, chan,
|
|
|
- &chan->i2c_adapter, &chan->dev->pci_dev->dev);
|
|
|
- return (chan->fe) ? 0 : -ENODEV;
|
|
|
-}
|
|
|
-
|
|
|
-static int demod_attach_stb0899(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- void *feconf = chan->dev->card_info->fe_config[chan->number];
|
|
|
-
|
|
|
- chan->fe = stb0899_attach(feconf,
|
|
|
- chan, &chan->i2c_adapter,
|
|
|
- &chan->dev->pci_dev->dev);
|
|
|
- if (chan->fe) {
|
|
|
- chan->set_tone = chan->fe->ops.set_tone;
|
|
|
- chan->fe->ops.set_tone = lnbh21_set_tone;
|
|
|
- chan->fe->ops.set_voltage = lnbh21_set_voltage;
|
|
|
- }
|
|
|
-
|
|
|
- return (chan->fe) ? 0 : -ENODEV;
|
|
|
-}
|
|
|
-
|
|
|
-static int demod_attach_stv0900(struct ngene_channel *chan)
|
|
|
-{
|
|
|
- void *feconf = chan->dev->card_info->fe_config[chan->number];
|
|
|
-
|
|
|
- chan->fe = stv0900_attach(feconf,
|
|
|
- chan, &chan->i2c_adapter,
|
|
|
- &chan->dev->pci_dev->dev);
|
|
|
-
|
|
|
- if (chan->fe) {
|
|
|
- chan->set_tone = chan->fe->ops.set_tone;
|
|
|
- chan->fe->ops.set_tone = lnbh21_set_tone;
|
|
|
- chan->fe->ops.set_voltage = lnbh21_set_voltage;
|
|
|
- }
|
|
|
-
|
|
|
- return (chan->fe) ? 0 : -ENODEV;
|
|
|
-}
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-/****************************************************************************/
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static void release_channel(struct ngene_channel *chan)
|
|
|
+/****************************************************************************/
|
|
|
+/****************************************************************************/
|
|
|
+/****************************************************************************/
|
|
|
+
|
|
|
+static void release_channel(struct ngene_channel *chan)
|
|
|
{
|
|
|
struct dvb_demux *dvbdemux = &chan->demux;
|
|
|
struct ngene *dev = chan->dev;
|
|
@@ -3436,10 +2405,6 @@ static void release_channel(struct ngene_channel *chan)
|
|
|
if (chan->command_dev)
|
|
|
dvb_unregister_device(chan->command_dev);
|
|
|
#endif
|
|
|
- if (chan->audio_dev)
|
|
|
- dvb_unregister_device(chan->audio_dev);
|
|
|
- if (chan->video_dev)
|
|
|
- dvb_unregister_device(chan->video_dev);
|
|
|
if (chan->fe) {
|
|
|
dvb_unregister_frontend(chan->fe);
|
|
|
/*dvb_frontend_detach(chan->fe); */
|
|
@@ -3457,10 +2422,6 @@ static void release_channel(struct ngene_channel *chan)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
- if (io & (NGENE_IO_AIN)) {
|
|
|
- ngene_snd_exit(chan);
|
|
|
- kfree(chan->soundbuffer);
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
static int init_channel(struct ngene_channel *chan)
|
|
@@ -3502,13 +2463,6 @@ static int init_channel(struct ngene_channel *chan)
|
|
|
&chan->mem_frontend, adapter);
|
|
|
if (io & NGENE_IO_TSOUT) {
|
|
|
dvbdemux->write_to_decoder = write_to_decoder;
|
|
|
- dvb_register_device(adapter, &chan->audio_dev,
|
|
|
- &dvbdev_audio, (void *)chan,
|
|
|
- DVB_DEVICE_AUDIO);
|
|
|
- dvb_register_device(adapter, &chan->video_dev,
|
|
|
- &dvbdev_video, (void *)chan,
|
|
|
- DVB_DEVICE_VIDEO);
|
|
|
-
|
|
|
}
|
|
|
#ifdef NGENE_COMMAND_API
|
|
|
dvb_register_device(adapter, &chan->command_dev,
|
|
@@ -3536,19 +2490,6 @@ static int init_channel(struct ngene_channel *chan)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (io & (NGENE_IO_AIN)) {
|
|
|
- ngene_snd_init(chan);
|
|
|
-#ifdef NGENE_V4L
|
|
|
- spin_lock_init(&chan->s_lock);
|
|
|
- init_MUTEX(&chan->reslock);
|
|
|
- INIT_LIST_HEAD(&chan->capture);
|
|
|
-#endif
|
|
|
-
|
|
|
- chan->soundbuffer = kmalloc(MAX_AUDIO_BUFFER_SIZE, GFP_KERNEL);
|
|
|
- if (!chan->soundbuffer)
|
|
|
- return -ENOMEM;
|
|
|
- memset(chan->soundbuffer, 0, MAX_AUDIO_BUFFER_SIZE);
|
|
|
- }
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -3616,8 +2557,6 @@ static int __devinit ngene_probe(struct pci_dev *pci_dev,
|
|
|
goto fail1;
|
|
|
|
|
|
dev->i2c_current_bus = -1;
|
|
|
- exp_init(dev);
|
|
|
-
|
|
|
/* Disable analog TV decoder chips if present */
|
|
|
if (copy_eeprom) {
|
|
|
i2c_copy_eeprom(&dev->channel[0].i2c_adapter, 0x50, 0x52);
|
|
@@ -3648,321 +2587,6 @@ fail1:
|
|
|
/* Card configs *************************************************************/
|
|
|
/****************************************************************************/
|
|
|
|
|
|
-static struct drxd_config fe_terratec_dvbt_0 = {
|
|
|
- .index = 0,
|
|
|
- .demod_address = 0x70,
|
|
|
- .demod_revision = 0xa2,
|
|
|
- .demoda_address = 0x00,
|
|
|
- .pll_address = 0x60,
|
|
|
- .pll_type = DRXD_PLL_DTT7520X,
|
|
|
- .clock = 20000,
|
|
|
- .pll_set = ngene_pll_set_th_dtt7520x,
|
|
|
- .osc_deviation = osc_deviation,
|
|
|
-};
|
|
|
-
|
|
|
-static struct drxd_config fe_terratec_dvbt_1 = {
|
|
|
- .index = 1,
|
|
|
- .demod_address = 0x71,
|
|
|
- .demod_revision = 0xa2,
|
|
|
- .demoda_address = 0x00,
|
|
|
- .pll_address = 0x60,
|
|
|
- .pll_type = DRXD_PLL_DTT7520X,
|
|
|
- .clock = 20000,
|
|
|
- .pll_set = ngene_pll_set_th_dtt7520x,
|
|
|
- .osc_deviation = osc_deviation,
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_terratec = {
|
|
|
- .type = NGENE_TERRATEC,
|
|
|
- .name = "Terratec Integra/Cinergy2400i Dual DVB-T",
|
|
|
- .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
|
|
|
- .demod_attach = {demod_attach_drxd, demod_attach_drxd},
|
|
|
- .fe_config = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1},
|
|
|
- .i2c_access = 1,
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct mt2060_config tuner_python_0 = {
|
|
|
- .i2c_address = 0x60,
|
|
|
- .clock_out = 3,
|
|
|
- .input = 0
|
|
|
-};
|
|
|
-
|
|
|
-static struct mt2060_config tuner_python_1 = {
|
|
|
- .i2c_address = 0x61,
|
|
|
- .clock_out = 3,
|
|
|
- .input = 1
|
|
|
-};
|
|
|
-
|
|
|
-static struct drxd_config fe_python_0 = {
|
|
|
- .index = 0,
|
|
|
- .demod_address = 0x71,
|
|
|
- .demod_revision = 0xb1,
|
|
|
- .demoda_address = 0x41,
|
|
|
- .clock = 16000,
|
|
|
- .osc_deviation = osc_deviation,
|
|
|
-};
|
|
|
-
|
|
|
-static struct drxd_config fe_python_1 = {
|
|
|
- .index = 1,
|
|
|
- .demod_address = 0x70,
|
|
|
- .demod_revision = 0xb1,
|
|
|
- .demoda_address = 0x45,
|
|
|
- .clock = 16000,
|
|
|
- .osc_deviation = osc_deviation,
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_python = {
|
|
|
- .type = NGENE_PYTHON,
|
|
|
- .name = "Micronas MicPython/Hedgehog Dual DVB-T",
|
|
|
- .io_type = {NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_AIN, NGENE_IO_AIN},
|
|
|
- .demod_attach = {demod_attach_drxd, demod_attach_drxd},
|
|
|
- .tuner_attach = {tuner_attach_mt2060, tuner_attach_mt2060},
|
|
|
- .fe_config = {&fe_python_0, &fe_python_1},
|
|
|
- .tuner_config = {&tuner_python_0, &tuner_python_1},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
- .msp = {0x40, 0x42},
|
|
|
- .demoda = {0x41, 0x45},
|
|
|
- .gate_ctrl = python_gate_ctrl,
|
|
|
- .switch_ctrl = python_switch_ctrl,
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct drxd_config fe_appb_dvbt_0 = {
|
|
|
- .index = 0,
|
|
|
- .demod_address = 0x71,
|
|
|
- .demod_revision = 0xa2,
|
|
|
- .demoda_address = 0x41,
|
|
|
- .pll_address = 0x63,
|
|
|
- .pll_type = DRXD_PLL_MT3X0823,
|
|
|
- .clock = 20000,
|
|
|
- .pll_set = ngene_pll_set_mt_3x0823,
|
|
|
- .osc_deviation = osc_deviation,
|
|
|
-};
|
|
|
-
|
|
|
-static struct drxd_config fe_appb_dvbt_1 = {
|
|
|
- .index = 1,
|
|
|
- .demod_address = 0x70,
|
|
|
- .demod_revision = 0xa2,
|
|
|
- .demoda_address = 0x45,
|
|
|
- .pll_address = 0x60,
|
|
|
- .pll_type = DRXD_PLL_MT3X0823,
|
|
|
- .clock = 20000,
|
|
|
- .pll_set = ngene_pll_set_mt_3x0823,
|
|
|
- .osc_deviation = osc_deviation,
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_appboard = {
|
|
|
- .type = NGENE_APP,
|
|
|
- .name = "Micronas Application Board Dual DVB-T",
|
|
|
- .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
|
|
|
- .demod_attach = {demod_attach_drxd, demod_attach_drxd},
|
|
|
- .fe_config = {&fe_appb_dvbt_0, &fe_appb_dvbt_1},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_appboard_ntsc = {
|
|
|
- .type = NGENE_APP,
|
|
|
- .name = "Micronas Application Board Dual DVB-T",
|
|
|
- .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
|
|
|
- .demod_attach = {demod_attach_drxd, demod_attach_drxd},
|
|
|
- .fe_config = {&fe_appb_dvbt_0, &fe_appb_dvbt_1},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
- .ntsc = 1,
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct stb0899_config fe_sidewinder_0 = {
|
|
|
- .demod_address = 0x68,
|
|
|
- .pll_address = 0x63,
|
|
|
-};
|
|
|
-
|
|
|
-static struct stb0899_config fe_sidewinder_1 = {
|
|
|
- .demod_address = 0x6b,
|
|
|
- .pll_address = 0x60,
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_sidewinder = {
|
|
|
- .type = NGENE_SIDEWINDER,
|
|
|
- .name = "Micronas MicSquirrel/Sidewinder Dual DVB-S2",
|
|
|
- .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
|
|
|
- .demod_attach = {demod_attach_stb0899, demod_attach_stb0899},
|
|
|
- .fe_config = {&fe_sidewinder_0, &fe_sidewinder_1},
|
|
|
- .lnb = {0x0b, 0x08},
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-/* Yet unnamed S2 card with dual DVB-S2 demod */
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct stv0900_config fe_s2_0 = {
|
|
|
- .addr = 0x68,
|
|
|
- .pll = 0x63,
|
|
|
- .pll_type = 0,
|
|
|
- .nr = 0,
|
|
|
-};
|
|
|
-
|
|
|
-static struct stv0900_config fe_s2_1 = {
|
|
|
- .addr = 0x68,
|
|
|
- .pll = 0x60,
|
|
|
- .pll_type = 0,
|
|
|
- .nr = 1,
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_s2 = {
|
|
|
- .type = NGENE_SIDEWINDER,
|
|
|
- .name = "S2",
|
|
|
- .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN,
|
|
|
- NGENE_IO_TSIN, NGENE_IO_TSIN},
|
|
|
- .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
|
|
|
- .fe_config = {&fe_s2_0, &fe_s2_1},
|
|
|
- .lnb = {0x0b, 0x08},
|
|
|
- .tsf = {3, 3},
|
|
|
- .fw_version = 15,
|
|
|
-};
|
|
|
-
|
|
|
-static struct stv0900_config fe_s2b_0 = {
|
|
|
- .addr = 0x68,
|
|
|
- .pll = 0x60,
|
|
|
- .pll_type = 0x10,
|
|
|
- .nr = 0,
|
|
|
-};
|
|
|
-
|
|
|
-static struct stv0900_config fe_s2b_1 = {
|
|
|
- .addr = 0x68,
|
|
|
- .pll = 0x63,
|
|
|
- .pll_type = 0x10,
|
|
|
- .nr = 1,
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_s2_b = {
|
|
|
- .type = NGENE_SIDEWINDER,
|
|
|
- .name = "S2 V2",
|
|
|
- .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN,
|
|
|
- NGENE_IO_TSIN, NGENE_IO_TSIN},
|
|
|
- .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
|
|
|
- .fe_config = {&fe_s2b_0, &fe_s2b_1},
|
|
|
- .lnb = {0x0b, 0x08},
|
|
|
- .tsf = {3, 3},
|
|
|
- .fw_version = 17,
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct xc3028_config tuner_viper_0 = {
|
|
|
- .adr = 0x61,
|
|
|
- .reset = viper_reset_xc
|
|
|
-};
|
|
|
-
|
|
|
-static struct xc3028_config tuner_viper_1 = {
|
|
|
- .adr = 0x64,
|
|
|
- .reset = viper_reset_xc
|
|
|
-};
|
|
|
-
|
|
|
-static struct drxh_config fe_viper_h_0 = {.adr = 0x2b};
|
|
|
-
|
|
|
-static struct drxh_config fe_viper_h_1 = {.adr = 0x29};
|
|
|
-
|
|
|
-static struct drxh_config fe_viper_l_0 = {.adr = 0x2b, .type = 3931};
|
|
|
-
|
|
|
-static struct drxh_config fe_viper_l_1 = {.adr = 0x29, .type = 3931};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_viper_v1 = {
|
|
|
- .type = NGENE_VIPER,
|
|
|
- .name = "Micronas MicViper Dual ATSC DRXH",
|
|
|
- .io_type = {NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_AIN, NGENE_IO_AIN},
|
|
|
- .demod_attach = {demod_attach_drxh, demod_attach_drxh},
|
|
|
- .fe_config = {&fe_viper_h_0, &fe_viper_h_1},
|
|
|
- .tuner_config = {&tuner_viper_0, &tuner_viper_1},
|
|
|
- .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
- .msp = {0x40, 0x42},
|
|
|
- .exp = 0x20,
|
|
|
- .exp_init = 0xf5,
|
|
|
- .gate_ctrl = viper_gate_ctrl,
|
|
|
- .switch_ctrl = viper_switch_ctrl,
|
|
|
- .tsf = {2, 2},
|
|
|
-};
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_viper_v2 = {
|
|
|
- .type = NGENE_VIPER,
|
|
|
- .name = "Micronas MicViper Dual ATSC DRXL",
|
|
|
- .io_type = {NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_AIN, NGENE_IO_AIN},
|
|
|
- .demod_attach = {demod_attach_drxh, demod_attach_drxh},
|
|
|
- .fe_config = {&fe_viper_l_0, &fe_viper_l_1},
|
|
|
- .tuner_config = {&tuner_viper_0, &tuner_viper_1},
|
|
|
- .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
- .msp = {0x40, 0x42},
|
|
|
- .exp = 0x38,
|
|
|
- .exp_init = 0xf5,
|
|
|
- .gate_ctrl = viper_gate_ctrl,
|
|
|
- .switch_ctrl = viper_switch_ctrl,
|
|
|
- .tsf = {2, 2},
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_vbox_v1 = {
|
|
|
- .type = NGENE_VBOX_V1,
|
|
|
- .name = "VBox Cat's Eye 164E",
|
|
|
- .io_type = {NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_AIN, NGENE_IO_AIN},
|
|
|
- .demod_attach = {demod_attach_drxh, demod_attach_drxh},
|
|
|
- .fe_config = {&fe_viper_h_0, &fe_viper_h_1},
|
|
|
- .tuner_config = {&tuner_viper_0, &tuner_viper_1},
|
|
|
- .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
- .msp = {0x40, 0x42},
|
|
|
- .exp = 0x20,
|
|
|
- .exp_init = 0xf5,
|
|
|
- .gate_ctrl = viper_gate_ctrl,
|
|
|
- .switch_ctrl = viper_switch_ctrl,
|
|
|
- .tsf = {2, 2},
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_vbox_v2 = {
|
|
|
- .type = NGENE_VBOX_V2,
|
|
|
- .name = "VBox Cat's Eye 164E",
|
|
|
- .io_type = {NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_TSIN | NGENE_IO_TV,
|
|
|
- NGENE_IO_AIN, NGENE_IO_AIN},
|
|
|
- .demod_attach = {demod_attach_drxh, demod_attach_drxh},
|
|
|
- .fe_config = {&fe_viper_h_0, &fe_viper_h_1},
|
|
|
- .tuner_config = {&tuner_viper_0, &tuner_viper_1},
|
|
|
- .tuner_attach = {tuner_attach_xc3028, tuner_attach_xc3028},
|
|
|
- .avf = {0x43, 0x47},
|
|
|
- .msp = {0x40, 0x42},
|
|
|
- .exp = 0x20,
|
|
|
- .exp_init = 0xf5,
|
|
|
- .gate_ctrl = viper_gate_ctrl,
|
|
|
- .switch_ctrl = viper_switch_ctrl2,
|
|
|
- .tsf = {2, 2},
|
|
|
-};
|
|
|
-
|
|
|
-/****************************************************************************/
|
|
|
-
|
|
|
-static struct ngene_info ngene_info_racer = {
|
|
|
- .type = NGENE_RACER,
|
|
|
- .name = "Micronas MicRacer HDTV Decoder Card",
|
|
|
- .io_type = {NGENE_IO_HDTV, NGENE_IO_NONE,
|
|
|
- NGENE_IO_AIN, NGENE_IO_NONE,
|
|
|
- NGENE_IO_TSOUT},
|
|
|
- .i2s = {0, 0, 1, 0},
|
|
|
- .fw_version = 17,
|
|
|
-};
|
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
@@ -3977,21 +2601,6 @@ static struct ngene_info ngene_info_racer = {
|
|
|
/****************************************************************************/
|
|
|
|
|
|
static const struct pci_device_id ngene_id_tbl[] __devinitdata = {
|
|
|
- NGENE_ID(0x18c3, 0x0000, ngene_info_appboard),
|
|
|
- NGENE_ID(0x18c3, 0x0004, ngene_info_appboard),
|
|
|
- NGENE_ID(0x18c3, 0x8011, ngene_info_appboard),
|
|
|
- NGENE_ID(0x18c3, 0x8015, ngene_info_appboard_ntsc),
|
|
|
- NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
|
|
|
- NGENE_ID(0x18c3, 0x0030, ngene_info_python),
|
|
|
- NGENE_ID(0x18c3, 0x0052, ngene_info_sidewinder),
|
|
|
- NGENE_ID(0x18c3, 0x8f00, ngene_info_racer),
|
|
|
- NGENE_ID(0x18c3, 0x0041, ngene_info_viper_v1),
|
|
|
- NGENE_ID(0x18c3, 0x0042, ngene_info_viper_v2),
|
|
|
- NGENE_ID(0x14f3, 0x0041, ngene_info_vbox_v1),
|
|
|
- NGENE_ID(0x14f3, 0x0043, ngene_info_vbox_v2),
|
|
|
- NGENE_ID(0x18c3, 0xabcd, ngene_info_s2),
|
|
|
- NGENE_ID(0x18c3, 0xabc2, ngene_info_s2_b),
|
|
|
- NGENE_ID(0x18c3, 0xabc3, ngene_info_s2_b),
|
|
|
{0}
|
|
|
};
|
|
|
|