diff options
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-alsa.c | 63 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-cards.c | 222 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-core.c | 11 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-dvb.c | 222 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-i2c.c | 1 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 76 | ||||
-rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 8 |
7 files changed, 536 insertions, 67 deletions
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c index 4abf5c03a74..ffb0f647a86 100644 --- a/drivers/media/video/saa7134/saa7134-alsa.c +++ b/drivers/media/video/saa7134/saa7134-alsa.c @@ -1,10 +1,6 @@ /* * SAA713x ALSA support for V4L * - * - * Caveats: - * - Volume doesn't work (it's always at max) - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2 @@ -614,13 +610,18 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) snd_card_saa7134_pcm_t *pcm; snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream); struct saa7134_dev *dev = saa7134->dev; - int err; + int amux, err; mutex_lock(&dev->dmasound.lock); dev->dmasound.read_count = 0; dev->dmasound.read_offset = 0; + amux = dev->input->amux; + if ((amux < 1) || (amux > 3)) + amux = 1; + dev->dmasound.input = amux - 1; + mutex_unlock(&dev->dmasound.lock); pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); @@ -713,6 +714,8 @@ static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol, struct snd_ctl_elem_value * ucontrol) { snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol); + struct saa7134_dev *dev = chip->dev; + int change, addr = kcontrol->private_value; int left, right; @@ -727,10 +730,52 @@ static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol, if (right > 20) right = 20; spin_lock_irq(&chip->mixer_lock); - change = chip->mixer_volume[addr][0] != left || - chip->mixer_volume[addr][1] != right; - chip->mixer_volume[addr][0] = left; - chip->mixer_volume[addr][1] = right; + change = 0; + if (chip->mixer_volume[addr][0] != left) { + change = 1; + right = left; + } + if (chip->mixer_volume[addr][1] != right) { + change = 1; + left = right; + } + if (change) { + switch (dev->pci->device) { + case PCI_DEVICE_ID_PHILIPS_SAA7134: + switch (addr) { + case MIXER_ADDR_TVTUNER: + left = 20; + break; + case MIXER_ADDR_LINE1: + saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x10, + (left > 10) ? 0x00 : 0x10); + break; + case MIXER_ADDR_LINE2: + saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20, + (left > 10) ? 0x00 : 0x20); + break; + } + break; + case PCI_DEVICE_ID_PHILIPS_SAA7133: + case PCI_DEVICE_ID_PHILIPS_SAA7135: + switch (addr) { + case MIXER_ADDR_TVTUNER: + left = 20; + break; + case MIXER_ADDR_LINE1: + saa_andorb(0x0594, 0x10, + (left > 10) ? 0x00 : 0x10); + break; + case MIXER_ADDR_LINE2: + saa_andorb(0x0594, 0x20, + (left > 10) ? 0x00 : 0x20); + break; + } + break; + } + chip->mixer_volume[addr][0] = left; + chip->mixer_volume[addr][1] = right; + } spin_unlock_irq(&chip->mixer_lock); return change; } diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 51f0cfdcb68..4dead84aff4 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2462,14 +2462,17 @@ struct saa7134_board saa7134_boards[] = { .vmux = 1, .amux = TV, .tv = 1, + .gpio = 0x0000000, },{ .name = name_comp1, .vmux = 3, .amux = LINE2, + .gpio = 0x0200000, },{ .name = name_svideo, .vmux = 8, .amux = LINE2, + .gpio = 0x0200000, }}, .radio = { .name = name_radio, @@ -3022,6 +3025,158 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE1, }, }, + [SAA7134_BOARD_PINNACLE_PCTV_310i] = { + .name = "Pinnacle PCTV 310i", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .gpiomask = 0x000200000, + .inputs = {{ + .name = name_tv, + .vmux = 4, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE2, + },{ + .name = name_comp2, + .vmux = 0, + .amux = LINE2, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + }}, + .radio = { + .name = name_radio, + .amux = TV, + .gpio = 0x0200000, + }, + }, + [SAA7134_BOARD_AVERMEDIA_STUDIO_507] = { + /* Mikhail Fedotov <mo_fedotov@mail.ru> */ + .name = "Avermedia AVerTV Studio 507", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_FM1256_IH3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .gpiomask = 0x03, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + .gpio = 0x00, + },{ + .name = name_comp1, + .vmux = 0, + .amux = LINE2, + .gpio = 0x00, + },{ + .name = name_comp2, + .vmux = 3, + .amux = LINE2, + .gpio = 0x00, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + .gpio = 0x00, + }}, + .radio = { + .name = name_radio, + .amux = LINE2, + .gpio = 0x01, + }, + .mute = { + .name = name_mute, + .amux = LINE1, + .gpio = 0x00, + }, + }, + [SAA7134_BOARD_VIDEOMATE_DVBT_200A] = { + /* Francis Barber <fedora@barber-family.id.au> */ + .name = "Compro Videomate DVB-T200A", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE, + .mpeg = SAA7134_MPEG_DVB, + .inputs = {{ + .name = name_tv, + .vmux = 3, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 1, + .amux = LINE2, + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, + }}, + }, + [SAA7134_BOARD_HAUPPAUGE_HVR1110] = { + /* Thomas Genty <tomlohave@gmail.com> */ + .name = "Hauppauge WinTV-HVR1110 DVB-T/Hybrid", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 3, + .amux = LINE2, /* FIXME: audio doesn't work on svideo/composite */ + },{ + .name = name_svideo, + .vmux = 8, + .amux = LINE2, /* FIXME: audio doesn't work on svideo/composite */ + }}, + .radio = { + .name = name_radio, + .amux = TV, + }, + }, + [SAA7134_BOARD_CINERGY_HT_PCMCIA] = { + .name = "Terratec Cinergy HT PCMCIA", + .audio_clock = 0x00187de7, + .tuner_type = TUNER_PHILIPS_TDA8290, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .inputs = {{ + .name = name_tv, + .vmux = 1, + .amux = TV, + .tv = 1, + },{ + .name = name_comp1, + .vmux = 0, + .amux = LINE1, + },{ + .name = name_svideo, + .vmux = 6, + .amux = LINE1, + }}, + }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -3631,6 +3786,36 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x4860, .driver_data = SAA7134_BOARD_ASUS_EUROPA2_HYBRID, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x11bd, + .subdevice = 0x002f, + .driver_data = SAA7134_BOARD_PINNACLE_PCTV_310i, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1461, /* Avermedia Technologies Inc */ + .subdevice = 0x9715, + .driver_data = SAA7134_BOARD_AVERMEDIA_STUDIO_507, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x1043, + .subdevice = 0x4876, + .driver_data = SAA7134_BOARD_ASUSTeK_P7131_DUAL, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x0070, + .subdevice = 0x6701, + .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7133, + .subvendor = 0x153b, + .subdevice = 0x1172, + .driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA, + },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, @@ -3717,6 +3902,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_307: + case SAA7134_BOARD_AVERMEDIA_STUDIO_507: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: case SAA7134_BOARD_AVERMEDIA_777: /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ @@ -3725,6 +3911,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_VIDEOMATE_DVBT_200: + case SAA7134_BOARD_VIDEOMATE_DVBT_200A: case SAA7134_BOARD_MANLI_MTV001: case SAA7134_BOARD_MANLI_MTV002: case SAA7134_BOARD_BEHOLD_409FM: @@ -3793,7 +3980,9 @@ int saa7134_board_init1(struct saa7134_dev *dev) break; /* i2c remotes */ case SAA7134_BOARD_PINNACLE_PCTV_110i: + case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_UPMOST_PURPLE_TV: + case SAA7134_BOARD_HAUPPAUGE_HVR1110: dev->has_remote = SAA7134_REMOTE_I2C; break; case SAA7134_BOARD_AVERMEDIA_A169_B: @@ -3924,9 +4113,11 @@ int saa7134_board_init2(struct saa7134_dev *dev) } break; case SAA7134_BOARD_PHILIPS_TIGER: + case SAA7134_BOARD_PINNACLE_PCTV_310i: case SAA7134_BOARD_TEVION_DVBT_220RF: case SAA7134_BOARD_ASUSTeK_P7131_DUAL: case SAA7134_BOARD_MEDION_MD8800_QUADRO: + case SAA7134_BOARD_HAUPPAUGE_HVR1110: /* this is a hybrid board, initialize to analog mode * and configure firmware eeprom address */ @@ -3952,6 +4143,14 @@ int saa7134_board_init2(struct saa7134_dev *dev) i2c_transfer(&dev->i2c_adap, &msg, 1); } break; + case SAA7134_BOARD_CINERGY_HT_PCMCIA: + /* make the tda10046 find its eeprom */ + { + u8 data[] = { 0x3c, 0x33, 0x60}; + struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; + i2c_transfer(&dev->i2c_adap, &msg, 1); + } + break; case SAA7134_BOARD_KWORLD_ATSC110: { /* enable tuner */ @@ -3964,6 +4163,29 @@ int saa7134_board_init2(struct saa7134_dev *dev) dev->name, i); } break; + case SAA7134_BOARD_VIDEOMATE_DVBT_200: + case SAA7134_BOARD_VIDEOMATE_DVBT_200A: + /* The T200 and the T200A share the same pci id. Consequently, + * we are going to query eeprom to try to find out which one we + * are actually looking at. */ + + /* Don't do this if the board was specifically selected with an + * insmod option or if we have the default configuration T200*/ + if(!dev->autodetected || (dev->eedata[0x41] == 0xd0)) + break; + if(dev->eedata[0x41] == 0x02) { + /* Reconfigure board as T200A */ + dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A; + dev->tuner_type = saa7134_boards[dev->board].tuner_type; + dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; + printk(KERN_INFO "%s: Reconfigured board as %s\n", + dev->name, saa7134_boards[dev->board].name); + } else { + printk(KERN_WARNING "%s: Unexpected tuner type info: %x in eeprom\n", + dev->name, dev->eedata[0x41]); + break; + } + break; } return 0; } diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c index 5c9e63dfbea..ed038fff3b4 100644 --- a/drivers/media/video/saa7134/saa7134-core.c +++ b/drivers/media/video/saa7134/saa7134-core.c @@ -889,15 +889,16 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, must_configure_manually(); dev->board = SAA7134_BOARD_UNKNOWN; } + dev->autodetected = card[dev->nr] != dev->board; dev->tuner_type = saa7134_boards[dev->board].tuner_type; dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf; if (UNSET != tuner[dev->nr]) dev->tuner_type = tuner[dev->nr]; - printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - dev->name,pci_dev->subsystem_vendor, - pci_dev->subsystem_device,saa7134_boards[dev->board].name, - dev->board, card[dev->nr] == dev->board ? - "insmod option" : "autodetected"); + printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", + dev->name,pci_dev->subsystem_vendor, + pci_dev->subsystem_device,saa7134_boards[dev->board].name, + dev->board, dev->autodetected ? + "autodetected" : "insmod option"); /* get mmio */ if (!request_mem_region(pci_resource_start(pci_dev,0), diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 6b61d9b2fcb..fa833987909 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c @@ -50,6 +50,10 @@ static unsigned int antenna_pwr = 0; module_param(antenna_pwr, int, 0444); MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)"); +static int use_frontent = 0; +module_param(use_frontent, int, 0644); +MODULE_PARM_DESC(use_frontent,"for cards with multiple frontends (0: terrestrial, 1: satellite)"); + /* ------------------------------------------------------------------ */ static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on) { @@ -293,7 +297,7 @@ static int philips_tu1216_tuner_60_set_params(struct dvb_frontend *fe, struct dv return philips_tda6651_pll_set(0x60, fe, params); } -static int philips_tu1216_request_firmware(struct dvb_frontend *fe, +static int philips_tda1004x_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name) { struct saa7134_dev *dev = fe->dvb->priv; @@ -308,7 +312,7 @@ static struct tda1004x_config philips_tu1216_60_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tu1216_request_firmware, + .request_firmware = philips_tda1004x_request_firmware, }; /* ------------------------------------------------------------------ */ @@ -331,12 +335,12 @@ static struct tda1004x_config philips_tu1216_61_config = { .xtal_freq = TDA10046_XTAL_4M, .agc_config = TDA10046_AGC_DEFAULT, .if_freq = TDA10046_FREQ_3617, - .request_firmware = philips_tu1216_request_firmware, + .request_firmware = philips_tda1004x_request_firmware, }; /* ------------------------------------------------------------------ */ -static int philips_europa_tuner_init(struct dvb_frontend *fe) +static int philips_td1316_tuner_init(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; static u8 msg[] = { 0x0b, 0xf5, 0x86, 0xab }; @@ -347,18 +351,8 @@ static int philips_europa_tuner_init(struct dvb_frontend *fe) fe->ops.i2c_gate_ctrl(fe, 1); if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) return -EIO; - msleep(1); - - /* switch the board to dvb mode */ - init_msg.addr = 0x43; - init_msg.len = 0x02; - msg[0] = 0x00; - msg[1] = 0x40; if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) - return -EIO; - + fe->ops.i2c_gate_ctrl(fe, 0); return 0; } @@ -367,6 +361,22 @@ static int philips_td1316_tuner_set_params(struct dvb_frontend *fe, struct dvb_f return philips_tda6651_pll_set(0x61, fe, params); } +static int philips_europa_tuner_init(struct dvb_frontend *fe) +{ + struct saa7134_dev *dev = fe->dvb->priv; + static u8 msg[] = { 0x00, 0x40}; + struct i2c_msg init_msg = {.addr = 0x43,.flags = 0,.buf = msg,.len = sizeof(msg) }; + + + if (philips_td1316_tuner_init(fe)) + return -EIO; + msleep(1); + if (i2c_transfer(&dev->i2c_adap, &init_msg, 1) != 1) + return -EIO; + + return 0; +} + static int philips_europa_tuner_sleep(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; @@ -671,7 +681,7 @@ static struct tda1004x_config tda827x_lifeview_config = { .invert = 1, .invert_oclk = 0, .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X, + .agc_config = TDA10046_AGC_TDA827X_GP11, .if_freq = TDA10046_FREQ_045, .request_firmware = NULL, }; @@ -812,32 +822,40 @@ static int philips_tda827xa_tuner_sleep(u8 addr, struct dvb_frontend *fe) if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); i2c_transfer(&dev->i2c_adap, &tuner_msg, 1); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); return 0; } /* ------------------------------------------------------------------ */ -static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +static int tda8290_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) { - int ret; struct saa7134_dev *dev = fe->dvb->priv; static u8 tda8290_close[] = { 0x21, 0xc0}; static u8 tda8290_open[] = { 0x21, 0x80}; struct i2c_msg tda8290_msg = {.addr = 0x4b,.flags = 0, .len = 2}; - - /* close tda8290 i2c bridge */ - tda8290_msg.buf = tda8290_close; - ret = i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); - if (ret != 1) + if (enable) { + tda8290_msg.buf = tda8290_close; + } else { + tda8290_msg.buf = tda8290_open; + } + if (i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1) != 1) return -EIO; msleep(20); + return 0; +} + +/* ------------------------------------------------------------------ */ + +static int philips_tiger_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +{ + int ret; + ret = philips_tda827xa_pll_set(0x61, fe, params); if (ret != 0) return ret; - /* open tda8290 i2c bridge */ - tda8290_msg.buf = tda8290_open; - i2c_transfer(&dev->i2c_adap, &tda8290_msg, 1); - return ret; + return 0; } static int philips_tiger_tuner_init(struct dvb_frontend *fe) @@ -867,13 +885,80 @@ static struct tda1004x_config philips_tiger_config = { .invert = 1, .invert_oclk = 0, .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X, + .agc_config = TDA10046_AGC_TDA827X_GP11, + .if_freq = TDA10046_FREQ_045, + .request_firmware = NULL, +}; +/* ------------------------------------------------------------------ */ + +static int cinergy_ht_tuner_init(struct dvb_frontend *fe) +{ + struct saa7134_dev *dev = fe->dvb->priv; + static u8 data[] = { 0x3c, 0x33, 0x62}; + struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; + + if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1) + return -EIO; + return 0; +} + +static int cinergy_ht_tuner_sleep(struct dvb_frontend *fe) +{ + struct saa7134_dev *dev = fe->dvb->priv; + static u8 data[] = { 0x3c, 0x33, 0x60}; + struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)}; + + i2c_transfer(&dev->i2c_adap, &msg, 1); + philips_tda827xa_tuner_sleep( 0x61, fe); + return 0; +} + +static struct tda1004x_config cinergy_ht_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X_GP01, .if_freq = TDA10046_FREQ_045, .request_firmware = NULL, }; /* ------------------------------------------------------------------ */ +static struct tda1004x_config pinnacle_pctv_310i_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X_GP11, + .if_freq = TDA10046_FREQ_045, + .request_firmware = philips_tda1004x_request_firmware, +}; + +/* ------------------------------------------------------------------ */ + +static struct tda1004x_config hauppauge_hvr_1110_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X_GP11, + .if_freq = TDA10046_FREQ_045, + .request_firmware = philips_tda1004x_request_firmware, +}; + +/* ------------------------------------------------------------------ */ + +static struct tda1004x_config asus_p7131_dual_config = { + .demod_address = 0x08, + .invert = 1, + .invert_oclk = 0, + .xtal_freq = TDA10046_XTAL_16M, + .agc_config = TDA10046_AGC_TDA827X_GP11, + .if_freq = TDA10046_FREQ_045, + .request_firmware = philips_tda1004x_request_firmware, +}; + static int asus_p7131_dual_tuner_init(struct dvb_frontend *fe) { struct saa7134_dev *dev = fe->dvb->priv; @@ -921,7 +1006,7 @@ static struct tda1004x_config lifeview_trio_config = { .invert = 1, .invert_oclk = 0, .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X_GPL, + .agc_config = TDA10046_AGC_TDA827X_GP00, .if_freq = TDA10046_FREQ_045, .request_firmware = NULL, }; @@ -958,7 +1043,7 @@ static struct tda1004x_config ads_tech_duo_config = { .invert = 1, .invert_oclk = 0, .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X_GPL, + .agc_config = TDA10046_AGC_TDA827X_GP00, .if_freq = TDA10046_FREQ_045, .request_firmware = NULL, }; @@ -983,7 +1068,7 @@ static struct tda1004x_config tevion_dvbt220rf_config = { .invert = 1, .invert_oclk = 0, .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X, + .agc_config = TDA10046_AGC_TDA827X_GP11, .if_freq = TDA10046_FREQ_045, .request_firmware = NULL, }; @@ -1028,7 +1113,7 @@ static struct tda1004x_config md8800_dvbt_config = { .invert = 1, .invert_oclk = 0, .xtal_freq = TDA10046_XTAL_16M, - .agc_config = TDA10046_AGC_TDA827X, + .agc_config = TDA10046_AGC_TDA827X_GP11, .if_freq = TDA10046_FREQ_045, .request_firmware = NULL, }; @@ -1168,6 +1253,29 @@ static int dvb_init(struct saa7134_dev *dev) &philips_tiger_config, &dev->i2c_adap); if (dev->dvb.frontend) { + dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; + dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; + dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; + } + break; + case SAA7134_BOARD_PINNACLE_PCTV_310i: + dev->dvb.frontend = dvb_attach(tda10046_attach, + &pinnacle_pctv_310i_config, + &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; + dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; + dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; + } + break; + case SAA7134_BOARD_HAUPPAUGE_HVR1110: + dev->dvb.frontend = dvb_attach(tda10046_attach, + &hauppauge_hvr_1110_config, + &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; dev->dvb.frontend->ops.tuner_ops.init = philips_tiger_tuner_init; dev->dvb.frontend->ops.tuner_ops.sleep = philips_tiger_tuner_sleep; dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; @@ -1175,9 +1283,10 @@ static int dvb_init(struct saa7134_dev *dev) break; case SAA7134_BOARD_ASUSTeK_P7131_DUAL: dev->dvb.frontend = dvb_attach(tda10046_attach, - &philips_tiger_config, + &asus_p7131_dual_config, &dev->i2c_adap); if (dev->dvb.frontend) { + dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; dev->dvb.frontend->ops.tuner_ops.init = asus_p7131_dual_tuner_init; dev->dvb.frontend->ops.tuner_ops.sleep = asus_p7131_dual_tuner_sleep; dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; @@ -1194,12 +1303,27 @@ static int dvb_init(struct saa7134_dev *dev) } break; case SAA7134_BOARD_FLYDVB_TRIO: - dev->dvb.frontend = dvb_attach(tda10046_attach, - &lifeview_trio_config, - &dev->i2c_adap); - if (dev->dvb.frontend) { - dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep; - dev->dvb.frontend->ops.tuner_ops.set_params = lifeview_trio_tuner_set_params; + if(! use_frontent) { //terrestrial + dev->dvb.frontend = dvb_attach(tda10046_attach, + &lifeview_trio_config, + &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.tuner_ops.sleep = lifeview_trio_tuner_sleep; + dev->dvb.frontend->ops.tuner_ops.set_params = + lifeview_trio_tuner_set_params; + } + } else { //satellite + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); + if (dev->dvb.frontend) { + if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63, + &dev->i2c_adap, 0) == NULL) { + printk("%s: Lifeview Trio, No tda826x found!\n", __FUNCTION__); + } + if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, + 0x08, 0, 0) == NULL) { + printk("%s: Lifeview Trio, No ISL6421 found!\n", __FUNCTION__); + } + } } break; case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331: @@ -1281,7 +1405,27 @@ static int dvb_init(struct saa7134_dev *dev) dev->dvb.frontend->ops.tuner_ops.set_params = philips_fmd1216_tuner_set_params; } break; + case SAA7134_BOARD_VIDEOMATE_DVBT_200A: + dev->dvb.frontend = dvb_attach(tda10046_attach, + &philips_europa_config, + &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params; + } + break; + case SAA7134_BOARD_CINERGY_HT_PCMCIA: + dev->dvb.frontend = dvb_attach(tda10046_attach, + &cinergy_ht_config, + &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl; + dev->dvb.frontend->ops.tuner_ops.init = cinergy_ht_tuner_init; + dev->dvb.frontend->ops.tuner_ops.sleep = cinergy_ht_tuner_sleep; + dev->dvb.frontend->ops.tuner_ops.set_params = philips_tiger_tuner_set_params; + } + break; default: printk("%s: Huh? unknown DVB card?\n",dev->name); break; diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c index 6162550c413..6f9fe86fed9 100644 --- a/drivers/media/video/saa7134/saa7134-i2c.c +++ b/drivers/media/video/saa7134/saa7134-i2c.c @@ -341,6 +341,7 @@ static int attach_inform(struct i2c_client *client) switch (client->addr) { case 0x7a: case 0x47: + case 0x71: { struct IR_i2c *ir = i2c_get_clientdata(client); d1printk("%s i2c IR detected (%s).\n", diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index dee83552e68..60b38defd9b 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c @@ -112,6 +112,27 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) return 1; } +static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) +{ + unsigned char buf[5], cod4, code3, code4; + + /* poll IR chip */ + if (5 != i2c_master_recv(&ir->c,buf,5)) + return -EIO; + + cod4 = buf[4]; + code4 = (cod4 >> 2); + code3 = buf[3]; + if (code3 == 0) + /* no key pressed */ + return 0; + + /* return key */ + *ir_key = code4; + *ir_raw = code4; + return 1; +} + void saa7134_input_irq(struct saa7134_dev *dev) { struct saa7134_ir *ir = dev->remote; @@ -131,6 +152,23 @@ static void saa7134_input_timer(unsigned long data) mod_timer(&ir->timer, timeout); } +static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir) +{ + if (ir->polling) { + init_timer(&ir->timer); + ir->timer.function = saa7134_input_timer; + ir->timer.data = (unsigned long)dev; + ir->timer.expires = jiffies + HZ; + add_timer(&ir->timer); + } +} + +static void saa7134_ir_stop(struct saa7134_dev *dev) +{ + if (dev->remote->polling) + del_timer_sync(&dev->remote->timer); +} + int saa7134_input_init1(struct saa7134_dev *dev) { struct saa7134_ir *ir; @@ -141,6 +179,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) u32 mask_keyup = 0; int polling = 0; int ir_type = IR_TYPE_OTHER; + int err; if (dev->has_remote != SAA7134_REMOTE_GPIO) return -ENODEV; @@ -184,6 +223,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_307: case SAA7134_BOARD_AVERMEDIA_STUDIO_305: case SAA7134_BOARD_AVERMEDIA_STUDIO_307: + case SAA7134_BOARD_AVERMEDIA_STUDIO_507: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: ir_codes = ir_codes_avermedia; mask_keycode = 0x0007C8; @@ -266,9 +306,8 @@ int saa7134_input_init1(struct saa7134_dev *dev) ir = kzalloc(sizeof(*ir), GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) { - kfree(ir); - input_free_device(input_dev); - return -ENOMEM; + err = -ENOMEM; + goto err_out_free; } ir->dev = input_dev; @@ -299,18 +338,22 @@ int saa7134_input_init1(struct saa7134_dev *dev) } input_dev->cdev.dev = &dev->pci->dev; - /* all done */ dev->remote = ir; - if (ir->polling) { - init_timer(&ir->timer); - ir->timer.function = saa7134_input_timer; - ir->timer.data = (unsigned long)dev; - ir->timer.expires = jiffies + HZ; - add_timer(&ir->timer); - } + saa7134_ir_start(dev, ir); + + err = input_register_device(ir->dev); + if (err) + goto err_out_stop; - input_register_device(ir->dev); return 0; + + err_out_stop: + saa7134_ir_stop(dev); + dev->remote = NULL; + err_out_free: + input_free_device(input_dev); + kfree(ir); + return err; } void saa7134_input_fini(struct saa7134_dev *dev) @@ -318,8 +361,7 @@ void saa7134_input_fini(struct saa7134_dev *dev) if (NULL == dev->remote) return; - if (dev->remote->polling) - del_timer_sync(&dev->remote->timer); + saa7134_ir_stop(dev); input_unregister_device(dev->remote->dev); kfree(dev->remote); dev->remote = NULL; @@ -335,6 +377,7 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) switch (dev->board) { case SAA7134_BOARD_PINNACLE_PCTV_110i: + case SAA7134_BOARD_PINNACLE_PCTV_310i: snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV"); if (pinnacle_remote == 0) { ir->get_key = get_key_pinnacle_color; @@ -349,6 +392,11 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir) ir->get_key = get_key_purpletv; ir->ir_codes = ir_codes_purpletv; break; + case SAA7134_BOARD_HAUPPAUGE_HVR1110: + snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110"); + ir->get_key = get_key_hvr1110; + ir->ir_codes = ir_codes_hauppauge_new; + break; default: dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board); break; diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index 7cf96b43025..e88ad7b40c4 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h @@ -227,6 +227,11 @@ struct saa7134_format { #define SAA7134_BOARD_PROTEUS_2309 98 #define SAA7134_BOARD_AVERMEDIA_A16AR 99 #define SAA7134_BOARD_ASUS_EUROPA2_HYBRID 100 +#define SAA7134_BOARD_PINNACLE_PCTV_310i 101 +#define SAA7134_BOARD_AVERMEDIA_STUDIO_507 102 +#define SAA7134_BOARD_VIDEOMATE_DVBT_200A 103 +#define SAA7134_BOARD_HAUPPAUGE_HVR1110 104 +#define SAA7134_BOARD_CINERGY_HT_PCMCIA 105 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 @@ -446,6 +451,9 @@ struct saa7134_dev { struct v4l2_prio_state prio; #endif + /* insmod option/autodetected */ + int autodetected; + /* various device info */ unsigned int resources; struct video_device *video_dev; |