[linux-dvb] Driver for Medion MD7134 Cardbus and PCI, Part 2 of 3

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, again

This is the 2nd part of my patches for the MD7134 hybrid card.
This part is the changes in the SAA7134 driver:
- Introduce the hybrid version of this card
- A patch in saa7134-core.c to remain compatibiliy to the
   analog version of the card
- Modifications in saa7134-video.c to switch between analog
   and digital mode
- Introduce the FMD1216ME hybrid tuner
- Additional i2c client calls to support reinitialization
   of the tuner (the FMD needs this) and for the FM radio mode
   of the tda9887

You experienced guys out there:
Please have a careful look especially at the client calls,
I am new to this game.

Have fun
   Hartmut Hackmann


 >-------------------- snip -----------------------<
diff -uprNw video4linux.orig/ChangeLog video4linux/ChangeLog
--- video4linux.orig/ChangeLog	2005-04-26 11:07:03.000000000 +0200
+++ video4linux/ChangeLog	2005-04-30 02:08:57.000000000 +0200
@@ -1,14 +1,79 @@
-2005-04-26 11:01  kraxel
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)

-	* README.patches:
+	* Makefile

-	- update README.patches
+	- added driver for TDA10046

-2005-04-04 00:14  kraxel
+	* tda1004x.c tda1004x.h

-	* README.patches:
+	- added config options and code for
+	  + 16 MHZ crystal
+	  + different IF frequencies
+	  + different AGC controls
+	  + boot the DSP from on board EEPROM

-	- Final commit: add README.patches
+	- be more relaxed with different firmware revisions
+	
+	- code cleanup, rely less on default settings
+
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* saa7134-cards.c saa7134.c saa7134-dvb-c
+	
+	- introduced / modified support for Medion MD7134 / Philips TOUGH reference design
+
+
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* saa7134-core.c
+	
+	- distinguish DVB-T and analog only version of the MD7134 board
+	
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* saa7134-oss.c
+
+    - fixed DMA memory allocation and setup
+	
+	- fixed odd / even buffer assignment
+	
+2005-04-29 Hartmut Hackmann (actually Gerd Knorr)
+
+	* saa7134-ts.c
+	
+	- fixed odd / even buffer assignment
+
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* saa7134-tvaudio.c
+
+    - fixed audio clock switching for oss sound streaming
+	
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* saa7134-video.c
+
+    - reinitialize (MD7134) hybrid tuner for analog TV
+	  (if prior operation was DVB-T)
+	
+	- at exit, ensure that planar mode is off, otherwise
+	  DVB-T will not work
+	
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* tda9887.c audiochip.h
+
+    - added i2c client call for FM radio with FMD1216 tuner	
+	
+2005-04-29 Hartmut Hackmann (hartmut.hackmann@xxxxxxxxxxx)
+
+	* tuner-core.c tuner-simple.c tuner.h
+
+    - added support for Philips FMD1216ME tuner
+	
+	- allow run time change of tuner type (for MD7134)
+	
+	- added i2c client call to reinitialize tuner

  2005-03-10 11:07  kraxel

diff -uprNw video4linux.orig/Makefile video4linux/Makefile
--- video4linux.orig/Makefile	2005-02-21 15:07:00.000000000 +0100
+++ video4linux/Makefile	2005-03-21 00:30:22.000000000 +0100
@@ -40,7 +40,7 @@ obj-$(CONFIG_VIDEO_TUNER)	+= tuner.o tda
  obj-$(CONFIG_VIDEO_TVAUDIO)	+= msp3400.o tvaudio.o tvmixer.o

  obj-$(CONFIG_VIDEO_CX88_DVB)	+= video-buf-dvb.o cx88-dvb.o cx22702.o dvb-pll.o or51132.o
-obj-$(CONFIG_VIDEO_SAA7134_DVB) += video-buf-dvb.o saa7134-dvb.o mt352.o
+obj-$(CONFIG_VIDEO_SAA7134_DVB) += video-buf-dvb.o saa7134-dvb.o mt352.o  tda1004x.o

  # 2.6-only stuff
  ifeq ($(VERSION).$(PATCHLEVEL),2.6)
diff -uprNw video4linux.orig/audiochip.h video4linux/audiochip.h
--- video4linux.orig/audiochip.h	2004-10-13 13:07:00.000000000 +0200
+++ video4linux/audiochip.h	2005-04-27 00:58:48.000000000 +0200
@@ -31,5 +31,5 @@

  /* misc stuff to pass around config info to i2c chips */
  #define AUDC_CONFIG_PINNACLE  _IOW('m',32,int)
-
+#define AUDC_CONFIG_PHILIPS_FMD _IO('m',33)
  #endif /* AUDIOCHIP_H */
diff -uprNw video4linux.orig/load_modules video4linux/load_modules
--- video4linux.orig/load_modules	1970-01-01 01:00:00.000000000 +0100
+++ video4linux/load_modules	2005-04-27 01:12:12.000000000 +0200
@@ -0,0 +1,16 @@
+modprobe i2c-core
+modprobe firmware_class
+insmod ./video-buf.ko
+modprobe dvb_core
+modprobe videodev
+insmod ./ir-common.ko
+insmod ./v4l1-compat.ko
+insmod ./v4l2-common.ko
+insmod ./tuner.ko tuner
+insmod ./tda9887.ko
+insmod ./tda1004x.ko
+insmod ./mt352.ko
+insmod ./video-buf-dvb.ko
+insmod ./saa7134.ko ts_nr_packets=128 oss=1
+insmod ./saa7134-dvb.ko
+
diff -uprNw video4linux.orig/rm_modules video4linux/rm_modules
--- video4linux.orig/rm_modules	1970-01-01 01:00:00.000000000 +0100
+++ video4linux/rm_modules	2005-03-23 23:33:35.000000000 +0100
@@ -0,0 +1,4 @@
+rmmod saa7134_dvb tda1004x tda9887 mt352
+rmmod tuner saa7134
+rmmod v4l2_common v4l1_compat ir_common videodev video_buf_dvb
+rmmod dvb_core video_buf
diff -uprNw video4linux.orig/saa7134-cards.c video4linux/saa7134-cards.c
--- video4linux.orig/saa7134-cards.c	2005-03-07 13:07:00.000000000 +0100
+++ video4linux/saa7134-cards.c	2005-04-30 01:19:21.000000000 +0200
@@ -474,9 +474,8 @@ struct saa7134_board saa7134_boards[] =
          },
  	[SAA7134_BOARD_MD7134] = {
  		.name           = "Medion 7134",
-		//.audio_clock    = 0x00200000,
  		.audio_clock    = 0x00187de7,
-		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
+		.tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
  		.tda9887_conf   = TDA9887_PRESENT,
  		.mpeg           = SAA7134_MPEG_DVB,
  		.inputs = {{
@@ -1546,6 +1545,30 @@ struct saa7134_board saa7134_boards[] =
  //			.gpio = 0x4000,
  		}},
  	},
+	[SAA7134_BOARD_PHILIPS_TOUGH] = {
+		.name           = "Philips TOUGH DVB-T reference design",
+		.tuner_type	= TUNER_ABSENT,
+		.audio_clock    = 0x00187de7,
+		.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   = 8,
+			.amux   = LINE1,
+		}},
+		.radio = {
+			.name   = name_radio,
+			.amux   = LINE2,
+		},
+	},
  };
  const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards);

@@ -1840,6 +1863,12 @@ struct pci_device_id saa7134_pci_tbl[] =
  		.driver_data  = SAA7134_BOARD_FLYDVBTDUO,

   	},{
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+                .subvendor    = PCI_VENDOR_ID_PHILIPS,
+                .subdevice    = 0x2004,
+		.driver_data  = SAA7134_BOARD_PHILIPS_TOUGH,
+	},{
  		/* --- boards without eeprom + subsystem ID --- */
                  .vendor       = PCI_VENDOR_ID_PHILIPS,
                  .device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
diff -uprNw video4linux.orig/saa7134-core.c video4linux/saa7134-core.c
--- video4linux.orig/saa7134-core.c	2005-02-22 11:07:00.000000000 +0100
+++ video4linux/saa7134-core.c	2005-04-25 22:10:09.000000000 +0200
@@ -722,7 +722,6 @@ static int saa7134_hwinit1(struct saa713
  		   SAA7134_MAIN_CTRL_EVFE1 |
  		   SAA7134_MAIN_CTRL_EVFE2 |
  		   SAA7134_MAIN_CTRL_ESFE  |
-		   SAA7134_MAIN_CTRL_EBADC |
  		   SAA7134_MAIN_CTRL_EBDAC);

  	/* enable peripheral devices */
@@ -990,6 +989,22 @@ static int __devinit saa7134_initdev(str
  	msleep(100);
  	saa7134_i2c_register(dev);

+    /* Hac: if a card has variants, let's patch the data structures now */
+    if (dev->board == SAA7134_BOARD_MD7134) {
+		u8 buf;
+		int ret;
+		struct i2c_msg msg = { .addr=0x08, .flags=I2C_M_RD, .buf=&buf, .len = 1};
+		ret = i2c_transfer(&dev->i2c_adap, &msg, 1);
+		if (ret == 1) {
+			printk(KERN_INFO "%s: Board MD7134 has DVB-T\n", dev->name);
+		} else {
+			printk(KERN_INFO "%s: Board MD7134 is analog only\n", dev->name);
+			dev->tuner_type = TUNER_PHILIPS_FM1216ME_MK3;		
+			saa7134_boards[SAA7134_BOARD_MD7134].tuner_type = TUNER_PHILIPS_FM1216ME_MK3;			
+			saa7134_i2c_call_clients(dev,TUNER_SET_TYPE,&dev->tuner_type);
+		}
+	}		
+
  	/* initialize hardware #2 */
  	saa7134_board_init2(dev);
  	saa7134_hwinit2(dev);
diff -uprNw video4linux.orig/saa7134-dvb.c video4linux/saa7134-dvb.c
--- video4linux.orig/saa7134-dvb.c	2005-02-18 14:07:01.000000000 +0100
+++ video4linux/saa7134-dvb.c	2005-04-23 23:38:10.000000000 +0200
@@ -3,6 +3,9 @@
   *
   * (c) 2004 Gerd Knorr <kraxel@xxxxxxxxxxx> [SuSE Labs]
   *
+ *  Extended 3 / 2005 by Hartmut Hackmann to support various
+ *  cards with the tda10046 DVB-T channel decoder
+ *
   *  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; either version 2 of the License, or
@@ -141,44 +144,231 @@ static struct mt352_config pinnacle_300i

  /* ------------------------------------------------------------------ */

-static int medion_cardbus_init(struct dvb_frontend* fe)
+static int philips_tu1216_pll_init(struct dvb_frontend *fe)
  {
-	/* anything to do here ??? */
+	struct saa7134_dev *dev = fe->dvb->priv;
+	static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
+	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = 
sizeof(tu1216_init) };
+
+	// setup PLL configuration
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+	msleep(1);
+
  	return 0;
  }

-static int medion_cardbus_pll_set(struct dvb_frontend* fe,
-				  struct dvb_frontend_parameters* params)
+static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters 
*params)
  {
  	struct saa7134_dev *dev = fe->dvb->priv;
-	struct v4l2_frequency f;
+	u8 tuner_buf[4];
+	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
+			sizeof(tuner_buf) };
+	int tuner_frequency = 0;
+	u8 band, cp, filter;
+
+	// determine charge pump
+	tuner_frequency = params->frequency + 36166000;
+	if (tuner_frequency < 87000000)
+		return -EINVAL;
+	else if (tuner_frequency < 130000000)
+		cp = 3;
+	else if (tuner_frequency < 160000000)
+		cp = 5;
+	else if (tuner_frequency < 200000000)
+		cp = 6;
+	else if (tuner_frequency < 290000000)
+		cp = 3;
+	else if (tuner_frequency < 420000000)
+		cp = 5;
+	else if (tuner_frequency < 480000000)
+		cp = 6;
+	else if (tuner_frequency < 620000000)
+		cp = 3;
+	else if (tuner_frequency < 830000000)
+		cp = 5;
+	else if (tuner_frequency < 895000000)
+		cp = 7;
+	else
+		return -EINVAL;
+
+	// determine band
+	if (params->frequency < 49000000)
+		return -EINVAL;
+	else if (params->frequency < 161000000)
+		band = 1;
+	else if (params->frequency < 444000000)
+		band = 2;
+	else if (params->frequency < 861000000)
+		band = 4;
+	else
+		return -EINVAL;
+
+	// setup PLL filter
+	switch (params->u.ofdm.bandwidth) {
+	case BANDWIDTH_6_MHZ:
+		filter = 0;
+		break;

-	/*
-	 * this instructs tuner.o to set the frequency, the call will
-	 * end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
-	 * tda9887.o will see that as well.
-	 */
-	f.tuner     = 0;
-	f.type      = V4L2_TUNER_DIGITAL_TV;
-	f.frequency = params->frequency / 1000 * 16 / 1000;
-	saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+	case BANDWIDTH_7_MHZ:
+		filter = 0;
+		break;
+
+	case BANDWIDTH_8_MHZ:
+		filter = 1;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	// calculate divisor
+	// ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
+	tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
+
+	// setup tuner buffer
+	tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
+	tuner_buf[1] = tuner_frequency & 0xff;
+	tuner_buf[2] = 0xca;
+	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
+
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+
+	msleep(1);
  	return 0;
  }

-static int fe_request_firmware(struct dvb_frontend* fe,
+static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
  			       const struct firmware **fw, char* name)
  {
  	struct saa7134_dev *dev = fe->dvb->priv;
  	return request_firmware(fw, name, &dev->pci->dev);
  }
  	
-struct tda1004x_config medion_cardbus = {
-	.demod_address = 0x08,  /* not sure this is correct */
-	.invert        = 0,
+static struct tda1004x_config philips_tu1216_config = {
+
+	.demod_address = 0x8,
+	.invert = 1,
+	.invert_oclk = 1,
+	.xtal_freq     = TDA10046_XTAL_4M,
+	.agc_config    = TDA10046_AGC_DEFAULT,
+	.if_freq       = TDA10046_FREQ_DEFAULT,
+	.pll_init = philips_tu1216_pll_init,
+	.pll_set = philips_tu1216_pll_set,
+	.request_firmware = philips_tu1216_request_firmware,
+};
+
+/* ------------------------------------------------------------------ */
+
+
+static int philips_fmd1216_pll_init(struct dvb_frontend *fe)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+    // this message is to set up ATC and ALC
+	static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 };
+	struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = fmd1216_init,.len = 
sizeof(fmd1216_init) };
+
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+	msleep(1);
+
+	return 0;
+}
+
+static int philips_fmd1216_pll_set(struct dvb_frontend *fe, struct 
dvb_frontend_parameters *params)
+{
+	struct saa7134_dev *dev = fe->dvb->priv;
+	u8 tuner_buf[4];
+	struct i2c_msg tuner_msg = {.addr = 0x61,.flags = 0,.buf = tuner_buf,.len =
+			sizeof(tuner_buf) };
+	int tuner_frequency = 0;
+	int divider = 0;
+	u8 band, mode, cp;
+
+	// determine charge pump
+	tuner_frequency = params->frequency + 36130000;
+	if (tuner_frequency < 87000000)
+		return -EINVAL;
+    // low band
+	else if (tuner_frequency < 180000000) {
+		band = 1;
+		mode = 7;
+		cp   = 0;
+	} else if (tuner_frequency < 195000000) {
+		band = 1;
+		mode = 6;
+		cp   = 1;
+	// mid band	
+	} else if (tuner_frequency < 366000000) {
+	    if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 10;
+		} else {
+		    band = 2;
+		}
+		mode = 7;
+		cp   = 0;
+	} else if (tuner_frequency < 478000000) {
+	    if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 10;
+		} else {
+		    band = 2;
+		}
+		mode = 6;
+		cp   = 1;
+	// high band
+	} else if (tuner_frequency < 662000000) {
+	    if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 12;
+		} else {
+		    band = 4;
+		}
+		mode = 7;
+		cp   = 0;
+	} else if (tuner_frequency < 840000000) {
+	    if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 12;
+		} else {
+		    band = 4;
+		}
+		mode = 6;
+		cp   = 1;
+	} else {
+	    if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+			band = 12;
+		} else {
+		    band = 4;
+		}
+		mode = 7;
+		cp   = 1;
+	
+	}
+	// calculate divisor
+	// ((36166000 + Finput) / 166666) rounded!
+    divider = (tuner_frequency + 83333) / 166667;	
+
+	// setup tuner buffer
+	tuner_buf[0] = (divider >> 8) & 0x7f;
+	tuner_buf[1] = divider & 0xff;
+	tuner_buf[2] = 0x80 | (cp << 6) | (mode  << 3) | 4;
+	tuner_buf[3] = 0x40 | band;
+
+	if (i2c_transfer(&dev->i2c_adap, &tuner_msg, 1) != 1)
+		return -EIO;
+	return 0;
+}
+
+	
+static struct tda1004x_config medion_cardbus = {
+	.demod_address = 0x08,
+	.invert        = 1,
          .invert_oclk   = 0,
-        .pll_init      = medion_cardbus_init,
-        .pll_set       = medion_cardbus_pll_set,
-        .request_firmware = fe_request_firmware,
+	.xtal_freq     = TDA10046_XTAL_16M,
+	.agc_config    = TDA10046_AGC_IFO_AUTO_NEG,
+	.if_freq       = TDA10046_FREQ_3613,
+	.pll_init      = philips_fmd1216_pll_init,
+	.pll_set       = philips_fmd1216_pll_set,
+	.request_firmware = NULL,
  };

  /* ------------------------------------------------------------------ */
@@ -205,9 +395,10 @@ static int dvb_init(struct saa7134_dev *
  	case SAA7134_BOARD_MD7134:
  		dev->dvb.frontend = tda10046_attach(&medion_cardbus,
  						    &dev->i2c_adap);
-		if (NULL == dev->dvb.frontend)
-			printk("%s: Hmm, looks like this is the old MD7134 "
-			       "version without DVB-T support\n",dev->name);
+		break;
+	case SAA7134_BOARD_PHILIPS_TOUGH:
+		dev->dvb.frontend = tda10046_attach(&philips_tu1216_config,
+						    &dev->i2c_adap);
  		break;
  	default:
  		printk("%s: Huh? unknown DVB card?\n",dev->name);
@@ -227,8 +418,6 @@ static int dvb_fini(struct saa7134_dev *
  {
  	static int on  = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;

-	printk("%s: %s\n",dev->name,__FUNCTION__);
-
  	switch (dev->board) {
  	case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
  		/* otherwise we don't detect the tuner on next insmod */
diff -uprNw video4linux.orig/saa7134-ts.c video4linux/saa7134-ts.c
--- video4linux.orig/saa7134-ts.c	2005-02-03 11:27:01.000000000 +0100
+++ video4linux/saa7134-ts.c	2005-04-18 00:14:13.000000000 +0200
@@ -221,10 +221,10 @@ void saa7134_irq_ts_done(struct saa7134_
  	if (dev->ts_q.curr) {
  		field = dev->ts_q.curr->vb.field;
  		if (field == V4L2_FIELD_TOP) {
-			if ((status & 0x100000) != 0x000000)
+			if ((status & 0x100000) != 0x100000)
  				goto done;
  		} else {
-			if ((status & 0x100000) != 0x100000)
+			if ((status & 0x100000) != 0x000000)
  				goto done;
  		}
  		saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
diff -uprNw video4linux.orig/saa7134-video.c video4linux/saa7134-video.c
--- video4linux.orig/saa7134-video.c	2005-02-15 17:07:00.000000000 +0100
+++ video4linux/saa7134-video.c	2005-04-28 00:51:11.000000000 +0200
@@ -1218,7 +1218,6 @@ static int video_open(struct inode *inod
  	struct list_head *list;
  	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  	int radio = 0;
-
  	list_for_each(list,&saa7134_devlist) {
  		h = list_entry(list, struct saa7134_dev, devlist);
  		if (h->video_dev && (h->video_dev->minor == minor))
@@ -1235,6 +1234,12 @@ static int video_open(struct inode *inod
  	if (NULL == dev)
  		return -ENODEV;

+	if (dev->board == SAA7134_BOARD_MD7134) {
+	/* initialize the tuner for analog mode, necessary for some hybrid tuners.
+ 	   the tda9886 will be invisible in digital mode Hac: 04.05*/
+		saa7134_i2c_call_clients(dev, TUNER_SET_ANALOG, NULL);				
+	}
+
  	dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
  		v4l2_type_names[type]);

@@ -1270,6 +1275,8 @@ static int video_open(struct inode *inod
  	if (fh->radio) {
  		/* switch to radio mode */
  		saa7134_tvaudio_setinput(dev,&card(dev).radio);
+		if(dev->board == SAA7134_BOARD_MD7134)
+			saa7134_i2c_call_clients(dev,AUDC_CONFIG_PHILIPS_FMD, NULL);
  		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO,NULL);
  	} else {
  		/* switch to video/vbi mode */
@@ -1377,6 +1384,12 @@ static int video_release(struct inode *i
  		res_free(dev,fh,RESOURCE_VBI);
  	}

+	/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
+	saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
+	saa_andorb(SAA7134_OFMT_VIDEO_B, 0x1f, 0);
+	saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
+	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
+	
  	/* free stuff */
  	videobuf_mmap_free(&fh->cap);
  	videobuf_mmap_free(&fh->vbi);
diff -uprNw video4linux.orig/saa7134.h video4linux/saa7134.h
--- video4linux.orig/saa7134.h	2005-03-07 13:07:00.000000000 +0100
+++ video4linux/saa7134.h	2005-03-24 02:09:32.000000000 +0100
@@ -197,6 +197,7 @@ struct saa7134_format {
  #define SAA7135_BOARD_ASUSTeK_TVFM7135 53
  #define SAA7134_BOARD_FLYTVPLATINUM_FM 54
  #define SAA7134_BOARD_FLYDVBTDUO 55
+#define SAA7134_BOARD_PHILIPS_TOUGH 56

  #define SAA7134_MAXBOARDS 8
  #define SAA7134_INPUT_MAX 8
diff -uprNw video4linux.orig/tda9887.c video4linux/tda9887.c
--- video4linux.orig/tda9887.c	2005-02-04 13:07:00.000000000 +0100
+++ video4linux/tda9887.c	2005-04-28 00:11:34.000000000 +0200
@@ -61,6 +61,7 @@ struct tda9887 {
  	unsigned int       radio;
  	unsigned int       config;
  	unsigned int       pinnacle_id;
+	unsigned int       philips_fmd_id;
  	unsigned int       using_v4l2;
  };

@@ -231,6 +232,13 @@ static struct tvnorm radio = {
  		  cRadioIF_38_90 ),
  };

+static struct tvnorm radio_philips_fmd = {
+	.name = "radio",
+	.b    = ( cFmRadio | cQSS | cAutoMuteFmActive),
+	.c    = ( cAudioGain6 | cDeemphasis50 | cDeemphasisOFF | 0x1f),
+	.e    = ( cGating_36 | cTunerGainLow | cRadioIF_38_90 | cAudioIF_5_5 ),
+};
+
  /* ---------------------------------------------------------------------- */

  static void dump_read_message(unsigned char *buf)
@@ -363,6 +371,9 @@ static int tda9887_set_tvnorm(struct tda
  	int i;

  	if (t->radio) {
+		if (t-> philips_fmd_id)
+			norm = &radio_philips_fmd;
+		else	
  		norm = &radio;
  	} else {
  		for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
@@ -559,6 +570,10 @@ static int tda9887_configure(struct tda9
  	if (UNSET != t->pinnacle_id) {
  		tda9887_set_pinnacle(t,buf);
  	}
+	if ((t->radio) && (t->philips_fmd_id)) {
+		buf[1] &= ~cOutputPort1Inactive;
+		buf[1] &= ~cOutputPort2Inactive;
+	}
  	tda9887_set_config(t,buf);
  	tda9887_set_insmod(t,buf);

@@ -609,6 +624,7 @@ static int tda9887_attach(struct i2c_ada
  	t->client      = client_template;
  	t->std         = 0;
  	t->pinnacle_id = UNSET;
+	t->philips_fmd_id = 0;
          i2c_set_clientdata(&t->client, t);
          i2c_attach_client(&t->client);

@@ -675,6 +691,9 @@ tda9887_command(struct i2c_client *clien
  		tda9887_configure(t);
  		break;
  	}
+	case AUDC_CONFIG_PHILIPS_FMD:
+		t->philips_fmd_id = 1;
+		break;
  	case TDA9887_SET_CONFIG:
  	{
  		int *i = arg;
diff -uprNw video4linux.orig/tuner-core.c video4linux/tuner-core.c
--- video4linux.orig/tuner-core.c	2005-02-15 17:07:00.000000000 +0100
+++ video4linux/tuner-core.c	2005-04-26 00:59:10.000000000 +0200
@@ -149,8 +149,8 @@ static void set_type(struct i2c_client *
  		t->type = type;
  		return;
  	}
-	if (t->initialized)
-		/* run only once */
+	if ((t->initialized) && (t->type == type))
+		/* run only once except type change  Hac 04/05*/
  		return;

  	t->initialized = 1;
@@ -289,7 +289,9 @@ tuner_command(struct i2c_client *client,
  			break;
  		}
                  break;
-
+	case TUNER_SET_ANALOG:
+		default_tuner_init2(client);
+		break;
  	/* --- v4l ioctls --- */
  	/* take care: bttv does userspace copying, we'll get a
  	   kernel pointer here... */
diff -uprNw video4linux.orig/tuner-simple.c video4linux/tuner-simple.c
--- video4linux.orig/tuner-simple.c	2005-03-08 10:07:01.000000000 +0100
+++ video4linux/tuner-simple.c	2005-04-26 01:21:12.000000000 +0200
@@ -212,6 +212,8 @@ static struct tunertype tuners[] = {
            16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 },
          { "Philips FQ1236A MK4", Philips, NTSC,
            16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+	{ "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL,
+	  16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 },

  };
  unsigned const int tuner_count = ARRAY_SIZE(tuners);
@@ -427,6 +429,7 @@ static void default_set_radio_freq(struc
  	switch (t->type) {
  	case TUNER_PHILIPS_FM1216ME_MK3:
  	case TUNER_PHILIPS_FM1236_MK3:
+	case TUNER_PHILIPS_FMD1216ME_MK3:
  		buffer[3] = 0x19;
  		break;
  	case TUNER_PHILIPS_FM1256_IH3:
@@ -463,9 +466,29 @@ int default_tuner_init(struct i2c_client
  	t->radio_freq = default_set_radio_freq;
  	t->has_signal = tuner_signal;
  	t->is_stereo  = tuner_stereo;
+	default_tuner_init2(c);
  	return 0;
  }

+void default_tuner_init2(struct i2c_client *c)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	unsigned char buffer[4];
+
+	switch (t->type) {
+	case TUNER_PHILIPS_FMD1216ME_MK3:
+		buffer[0] = 0x0b;
+		buffer[1] = 0xdc;
+		buffer[2] = 0x9c;
+		buffer[3] = 0x60;
+        i2c_master_send(c,buffer,4);
+		mdelay(1);
+		buffer[2] = 0x86;
+		buffer[3] = 0x54;
+        i2c_master_send(c,buffer,4);
+		break;
+	}		
+}
  /*
   * Overrides for Emacs so that we follow Linus's tabbing style.
   * ---------------------------------------------------------------------------
diff -uprNw video4linux.orig/tuner.h video4linux/tuner.h
--- video4linux.orig/tuner.h	2005-03-08 10:07:01.000000000 +0100
+++ video4linux/tuner.h	2005-04-26 01:04:53.000000000 +0200
@@ -97,6 +97,7 @@

  #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */
  #define TUNER_PHILIPS_FQ1236A_MK4 57   /* Hauppauge PVR-500MCE NTSC */
+#define TUNER_PHILIPS_FMD1216ME_MK3 58

  #define NOTUNER 0
  #define PAL     1	/* PAL_BG */
@@ -121,6 +122,7 @@

  #define TUNER_SET_TYPE               _IOW('t',1,int)    /* set tuner type */
  #define TUNER_SET_TVFREQ             _IOW('t',2,int)    /* set tv freq */
+#define TUNER_SET_ANALOG             _IO('t',6)         /* reinitialize analog tuner */

  #define  TDA9887_SET_CONFIG          _IOW('t',5,int)
  /* tv card specific */
@@ -178,6 +180,7 @@ extern unsigned const int tuner_count;
  extern int microtune_init(struct i2c_client *c);
  extern int tda8290_init(struct i2c_client *c);
  extern int default_tuner_init(struct i2c_client *c);
+extern void default_tuner_init2(struct i2c_client *c);

  #define tuner_warn(fmt, arg...) \
  	dev_printk(KERN_WARNING , &t->i2c.dev , fmt , ## arg)



[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux