AVerMedia Cardbus Plus E501R

From LinuxTVWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Итак, стал я недавно обладателем сего чудного девайса =)
Ноутбук Benq Joybook 2100-r32. Debian unstable. Ядро 2.6.17.

Быстрый старт

Добавить опцию загрузки модуля saa7134:

options saa7134 card=46 tuner=12

В этом случае девайс определиться как AverMedia Cardbus E500.

Если Вы используете alsa, то не забудьте загрузить модуль saa7134-alsa, если oss - saa7134-oss.

Для того, чтобы поиметь звук в таких программах как tvtime нужно использовать SOX-redirect:

sox -c 2 -s -w -r 32000 -t ossdsp /dev/dsp2 -t ossdsp -w -r 32000 /dev/dsp

Без лишних телодвижений можно получить звук в mplayer'е, например вот так (для alsa):

mplayer -vo xv -ao alsa -tv driver=v4l2:device=/dev/video0:width=720:height=576:normid=1:chanlist=russia:\
immediatemode=0:alsa:adevice=hw.1,0:audiorate=32000:channels=<list_of_channels> tv://

Тестировал сей девайс, на версии ядра 2.6.16.34, работает все замечательно:

options saa7134 card=46 tuner=12 alsa=1
options tda9887 secam=d
install saa7134 /sbin/modprobe tda9887; /sbin/modprobe --ignore-install saa7134; /sbin/modprobe saa7134-alsa && /usr/sbin/alsactl restore >/dev/null 2>&1 || :
remove saa7134-alsa { /usr/sbin/alsactl store >/dev/null 2>&1 || : ; }; /sbin/modprobe -r --ignore-remove saa7134-alsa

все что перечислено ниже можно пропустить.


Делаем все как надо ;)

Редактируем драйвер ядра ;) В saa7134.h добавляем определение новой карточки:

#define SAA7134_BOARD_AVERMEDIA_CARDBUS_PLUS 85

Далее редактируем saa7134-card.c, добавляем определение устройства в структуру saa7134_boards:

        [SAA7134_BOARD_AVERMEDIA_CARDBUS_PLUS] = {
                /* hayova@gmail.com */
                .name           = "AVerMedia Cardbus Plus",
                .audio_clock    = 0x187de7,
                .tuner_type     = TUNER_ALPS_TSBE5_PAL,
                .radio_type     = TUNER_TEA5767,
                .tuner_addr     = 0x61,
                .radio_addr     = 0x60,
                .tda9887_conf   = TDA9887_PRESENT,
                .gpiomask       = 0x0C400003,
                .inputs         = {{
                        .name = name_tv,
                        .vmux = 1,
                        .amux = TV,
                        .tv   = 1,
                        .gpio = 0x0C400001,
                },{
                        .name = name_comp1,
                        .vmux = 3,
                        .amux = LINE1,
                        .gpio = 0x0C400002,
                },{
                        .name = name_svideo,
                        .vmux = 6,
                        .amux = LINE1,
                        .gpio = 0x0C400002,
                }},
                .radio = {
                        .name = name_radio,
                        .amux = LINE2,
                        .gpio = 0x04400001,
                },

В том же файле вносим изменения в структуру saa7134_pci_tbl:

		/* AVerMedia CardBus Plus */
		.vendor       = PCI_VENDOR_ID_PHILIPS,
		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
		.subvendor    = 0x1461, /* Avermedia Technologies Inc */
		.subdevice    = 0xb7e9,
		.driver_data  = SAA7134_BOARD_AVERMEDIA_CARDBUS_PLUS,
	},{

И добавляем инициализацию устройства в функцию saa7134_board_init1:

	case SAA7134_BOARD_AVERMEDIA_CARDBUS_PLUS:
		/* power-up tuner chip */
		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x0C440003, 0x0C440003);
		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0C400000, 0x0C400000);
		dev->has_remote = SAA7134_REMOTE_GPIO;
		msleep(1);
		break;

В файле saa7134-input.c вносим изменения в функцию saa7134_input_init1:

	case SAA7134_BOARD_AVERMEDIA_CARDBUS_PLUS:
		ir_codes     = ir_codes_gotview7135;
		mask_keycode = 0x0007C8;
		mask_keydown = 0x000010;
		polling      = 50; // ms
		break;

Далее к saa7134-tvaudio.c применяем следующий патч (решает проблему со звуком в SECAM):

--- linux-2.6.18-rc1-mm1-build/drivers/media/video/saa7134/saa7134-tvaudio.c.old	2006-05-13 23:29:35.000000000 +0400
+++ linux-2.6.18-rc1-mm1-build/drivers/media/video/saa7134/saa7134-tvaudio.c	2006-07-12 04:22:01.000000000 +0400
@@ -50,6 +50,14 @@
 module_param(audio_clock_tweak, int, 0644);
 MODULE_PARM_DESC(audio_clock_tweak, "Audio clock tick fine tuning for cards with audio crystal that's slightly off (range [-1024 .. 1024])");
 
+static char pal[] = "--";
+static char secam[] = "--";
+static char ntsc[] = "-";
+
+module_param_string(pal, pal, sizeof(pal), 0644);
+module_param_string(secam, secam, sizeof(secam), 0644);
+module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
+
 #define dprintk(fmt, arg...)	if (audio_debug) \
 	printk(KERN_DEBUG "%s/audio: " fmt, dev->name , ## arg)
 #define d2printk(fmt, arg...)	if (audio_debug > 1) \
@@ -93,61 +101,61 @@
 static struct saa7134_tvaudio tvaudio[] = {
 	{
 		.name          = "PAL-B/G FM-stereo",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_BG,
 		.mode          = TVAUDIO_FM_BG_STEREO,
 		.carr1         = 5500,
 		.carr2         = 5742,
 	},{
 		.name          = "PAL-D/K1 FM-stereo",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_DK,
 		.carr1         = 6500,
 		.carr2         = 6258,
 		.mode          = TVAUDIO_FM_BG_STEREO,
 	},{
 		.name          = "PAL-D/K2 FM-stereo",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_DK,
 		.carr1         = 6500,
 		.carr2         = 6742,
 		.mode          = TVAUDIO_FM_BG_STEREO,
 	},{
 		.name          = "PAL-D/K3 FM-stereo",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_DK,
 		.carr1         = 6500,
 		.carr2         = 5742,
 		.mode          = TVAUDIO_FM_BG_STEREO,
 	},{
 		.name          = "PAL-B/G NICAM",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_BG,
 		.carr1         = 5500,
 		.carr2         = 5850,
 		.mode          = TVAUDIO_NICAM_FM,
 	},{
 		.name          = "PAL-I NICAM",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_I,
 		.carr1         = 6000,
 		.carr2         = 6552,
 		.mode          = TVAUDIO_NICAM_FM,
 	},{
 		.name          = "PAL-D/K NICAM",
-		.std           = V4L2_STD_PAL,
+		.std           = V4L2_STD_PAL_DK,
 		.carr1         = 6500,
 		.carr2         = 5850,
 		.mode          = TVAUDIO_NICAM_FM,
 	},{
 		.name          = "SECAM-L NICAM",
-		.std           = V4L2_STD_SECAM,
+		.std           = V4L2_STD_SECAM_L,
 		.carr1         = 6500,
 		.carr2         = 5850,
 		.mode          = TVAUDIO_NICAM_AM,
 	},{
 		.name          = "SECAM-L MONO",
-		.std           = V4L2_STD_SECAM,
+		.std           = V4L2_STD_SECAM_L,
 		.carr1         = 6500,
 		.carr2         = -1,
 		.mode          = TVAUDIO_AM_MONO,
 	},{
 		.name          = "SECAM-D/K",
-		.std           = V4L2_STD_SECAM,
+		.std           = V4L2_STD_SECAM_DK,
 		.carr1         = 6500,
 		.carr2         = -1,
 		.mode          = TVAUDIO_FM_MONO,
@@ -514,6 +522,119 @@
 	return 0;
 }
 
+/* get more precise norm info from insmod option */
+static int saa7134_fixup_std(struct saa7134_dev *dev)
+{
+	struct saa7134_tvnorm *t = dev->tvnorm;
+	if ((t->id & V4L2_STD_PAL) == V4L2_STD_PAL) {
+		switch (pal[0]) {
+		case 'b':
+		case 'B':
+		case 'g':
+		case 'G':
+			dprintk ("insmod fixup: PAL => PAL-BG\n");
+			t->id = V4L2_STD_PAL_BG;
+			break;
+		case 'i':
+		case 'I':
+			dprintk ("insmod fixup: PAL => PAL-I\n");
+			t->id = V4L2_STD_PAL_I;
+			break;
+		case 'd':
+		case 'D':
+		case 'k':
+		case 'K':
+			dprintk ("insmod fixup: PAL => PAL-DK\n");
+			t->id = V4L2_STD_PAL_DK;
+			break;
+		case 'M':
+		case 'm':
+			dprintk ("insmod fixup: PAL => PAL-M\n");
+			t->id = V4L2_STD_PAL_M;
+			break;
+		case 'N':
+		case 'n':
+			if (pal[1] == 'c' || pal[1] == 'C') {
+				dprintk("insmod fixup: PAL => PAL-Nc\n");
+				t->id = V4L2_STD_PAL_Nc;
+			} else {
+				dprintk ("insmod fixup: PAL => PAL-N\n");
+				t->id = V4L2_STD_PAL_N;
+			}
+			break;
+		case '-':
+			/* default parameter, do nothing */
+			break;
+		default:
+			dprintk ("pal= argument not recognised\n");
+			break;
+		}
+	}
+	if ((t->id & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
+		switch (secam[0]) {
+		case 'b':
+		case 'B':
+		case 'g':
+		case 'G':
+		case 'h':
+		case 'H':
+			dprintk("insmod fixup: SECAM => SECAM-BGH\n");
+			t->id = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
+			break;
+		case 'd':
+		case 'D':
+		case 'k':
+		case 'K':
+			dprintk ("insmod fixup: SECAM => SECAM-DK\n");
+			t->id = V4L2_STD_SECAM_DK;
+			break;
+		case 'l':
+		case 'L':
+			if ((secam[1]=='C')||(secam[1]=='c')) {
+				dprintk ("insmod fixup: SECAM => SECAM-L'\n");
+				t->id = V4L2_STD_SECAM_LC;
+			} else {
+				dprintk ("insmod fixup: SECAM => SECAM-L\n");
+				t->id = V4L2_STD_SECAM_L;
+			}
+			break;
+		case '-':
+			/* default parameter, do nothing */
+			break;
+		default:
+			dprintk ("secam= argument not recognised\n");
+			break;
+		}
+	}
+
+	if ((t->id & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
+		switch (ntsc[0]) {
+		case 'm':
+		case 'M':
+			dprintk("insmod fixup: NTSC => NTSC-M\n");
+			t->id = V4L2_STD_NTSC_M;
+			break;
+		case 'j':
+		case 'J':
+			dprintk("insmod fixup: NTSC => NTSC_M_JP\n");
+			t->id = V4L2_STD_NTSC_M_JP;
+			break;
+		case 'k':
+		case 'K':
+			dprintk("insmod fixup: NTSC => NTSC_M_KR\n");
+			t->id = V4L2_STD_NTSC_M_KR;
+			break;
+		case '-':
+			/* default parameter, do nothing */
+			break;
+		default:
+			dprintk("ntsc= argument not recognised\n");
+			break;
+		}
+	}
+	return 0;
+}
+
 static int tvaudio_thread(void *data)
 {
 	struct saa7134_dev *dev = data;
@@ -605,6 +726,7 @@
 		saa7134_tvaudio_setmute(dev);
 
 		/* find the exact tv audio norm */
+		saa7134_fixup_std(dev);
 		for (audio = UNSET, i = 0; i < TVAUDIO; i++) {
 			if (dev->tvnorm->id != UNSET &&
 				!(dev->tvnorm->id & tvaudio[i].std))

Потом в файле tuner-core.c вносим изменения в функцию tuner_attach:

	if (!no_autodetect) {
		switch (addr) {
		case 0x42:
		case 0x43:
		case 0x4a:
		case 0x4b:
			/* If chip is not tda8290, don't register.
			   since it can be tda9887*/
			if (tda8290_probe(&t->i2c) == 0) {
				tuner_dbg("chip at addr %x is a tda8290\n", addr);
			} else {
				/* Default is being tda9887 */
				t->type = TUNER_TDA9887;
				t->mode_mask = T_ANALOG_TV;
				t->mode = T_STANDBY;
				goto register_client;
			}
			break;
		case 0x60:
			//if (tea5767_autodetection(&t->i2c) != EINVAL) {
				t->type = TUNER_TEA5767;
				t->mode_mask = T_RADIO;
				t->mode = T_STANDBY;
				t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
				default_mode_mask &= ~T_RADIO;

				goto register_client;
			//}
			break;
		
		case 0x61:
			t->type = TUNER_ALPS_TSBE5_PAL;
			t->mode_mask = T_ANALOG_TV;
			t->mode = T_STANDBY;

			goto register_client;
			
			break;
		}
	}

Проблемы

1. все также не работает радио и пульт :(

И еще, данные, полученные при установленной опции i2c_scan=1 модуля saa7134:

saa7134[0]: i2c scan: found device @ 0x80  [???] -- возможно IR (???)
saa7134[0]: i2c scan: found device @ 0x84  [???] -- некая разновидность TDA9887 (???)
saa7134[0]: i2c scan: found device @ 0xa0  [eeprom]
saa7134[0]: i2c scan: found device @ 0xc0  [tuner (analog)]  -- тюнер TEA5767
saa7134[0]: i2c scan: found device @ 0xc2  [???]  -- тюнер ALPS TSEZ1

Кроме того, я отписался на список рассылки v4l, там же можно найти больше логов, если кого-нибудь заинтересует.

Пожалуйста поправляйте/добавляйте.


--Hayova 13:09, 18 June 2006 (CEST)