linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Johannes Stezenbach <js@linuxtv.org>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org
Subject: [DVB patch 37/37] budget-av: CI fixes
Date: Sun, 08 May 2005 20:43:06 +0200	[thread overview]
Message-ID: <20050508184350.512000000@abc> (raw)
In-Reply-To: 20050508184229.957247000@abc

[-- Attachment #1: dvb-ttpci-budget-ca.patch --]
[-- Type: text/plain, Size: 12993 bytes --]

- remove enable_ci, ci interface is assumed to be present if the saa7113
  is not found.
- reduce the delay when checking for saa7113
- clean up the cam reset according to specifications
- turn off Vcc to the cam slot if cam is removed or fails reset
- remove cam reset in ciintf_init
- clean up printks (KERN_)
- move gpio setting into saa7113_init
- clean up unreadable frontend_init
(Kenneth Aafloy)

Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
---

 drivers/media/dvb/ttpci/budget-av.c |  216 +++++++++++++++++++-----------------
 1 files changed, 118 insertions(+), 98 deletions(-)

Index: linux-2.6.12-rc4/drivers/media/dvb/ttpci/budget-av.c
===================================================================
--- linux-2.6.12-rc4.orig/drivers/media/dvb/ttpci/budget-av.c	2005-05-08 18:12:25.000000000 +0200
+++ linux-2.6.12-rc4/drivers/media/dvb/ttpci/budget-av.c	2005-05-08 18:14:43.000000000 +0200
@@ -59,8 +59,12 @@ struct budget_av {
 	struct dvb_ca_en50221 ca;
 };
 
-static int enable_ci = 0;
-
+/* GPIO CI Connections:
+ * 0 - Vcc/Reset (Reset is controlled by capacitor)
+ * 1 - Attribute Memory
+ * 2 - Card Enable (Active Low)
+ * 3 - Card Detect
+ */
 
 /****************************************************************************
  * INITIALIZATION
@@ -188,22 +192,35 @@ static int ciintf_slot_reset(struct dvb_
 {
 	struct budget_av *budget_av = (struct budget_av *) ca->data;
 	struct saa7146_dev *saa = budget_av->budget.dev;
-	int max = 20;
+	int timeout = 50; // 5 seconds (4.4.6 Ready)
 
 	if (slot != 0)
 		return -EINVAL;
 
 	dprintk(1, "ciintf_slot_reset\n");
 
-	/* reset the card */
-	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
-	msleep(100);
-	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
 
-	while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
+	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
+	msleep(2);
+	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
+	msleep(20); /* 20 ms Vcc settling time */
+
+	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
+
+	/* This should have been based on pin 16 READY of the pcmcia port,
+	 * but AFAICS it is not routed to the saa7146 */
+	while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d)
 		msleep(100);
 
-	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
+	if (timeout <= 0)
+	{
+		printk(KERN_ERR "budget-av: cam reset failed (timeout).\n");
+		saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
+		saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
+		return -ETIMEDOUT;
+	}
+
 	return 0;
 }
 
@@ -240,7 +257,6 @@ static int ciintf_poll_slot_status(struc
 {
 	struct budget_av *budget_av = (struct budget_av *) ca->data;
 	struct saa7146_dev *saa = budget_av->budget.dev;
-	int cam = 0;
 
 	if (slot != 0)
 		return -EINVAL;
@@ -248,15 +264,21 @@ static int ciintf_poll_slot_status(struc
 	if (!budget_av->slot_status) {
 		saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 		udelay(1);
-		cam = saa7146_read(saa, PSR) & MASK_06;
-		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
-
-		if (cam)
+		if (saa7146_read(saa, PSR) & MASK_06)
+		{
+			printk(KERN_INFO "budget-av: cam inserted\n");
 			budget_av->slot_status = 1;
+		}
+		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 	} else if (!open) {
 		saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
 		if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT)
+		{
+			printk(KERN_INFO "budget-av: cam ejected\n");
+			saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
+			saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
 			budget_av->slot_status = 0;
+		}
 	}
 
 	if (budget_av->slot_status == 1)
@@ -272,17 +294,11 @@ static int ciintf_init(struct budget_av 
 
 	memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
 
-	/* setup GPIOs */
-	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
+	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
+	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
 	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
 	saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
 
-	/* Reset the card */
-	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
-	msleep(50);
-	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
-	msleep(100);
-
 	/* Enable DEBI pins */
 	saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
 
@@ -297,13 +313,14 @@ static int ciintf_init(struct budget_av 
 	budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
 	budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
 	budget_av->ca.data = budget_av;
+
 	if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
 					  &budget_av->ca, 0, 1)) != 0) {
-		printk("budget_av: CI interface detected, but initialisation failed.\n");
+		printk(KERN_ERR "budget-av: ci initialisation failed.\n");
 		goto error;
 	}
-	// success!
-	printk("ciintf_init: CI interface initialised\n");
+
+	printk(KERN_INFO "budget-av: ci interface initialised.\n");
 	budget_av->budget.ci_present = 1;
 	return 0;
 
@@ -361,8 +378,12 @@ static const u8 saa7113_tab[] = {
 static int saa7113_init(struct budget_av *budget_av)
 {
 	struct budget *budget = &budget_av->budget;
+	struct saa7146_dev *saa = budget->dev;
 	const u8 *data = saa7113_tab;
 
+	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
+	msleep(200);
+
 	if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
 		dprintk(1, "saa7113 not found on KNC card\n");
 		return -ENODEV;
@@ -697,82 +718,90 @@ static u8 read_pwm(struct budget_av *bud
 	return pwm;
 }
 
+#define SUBID_DVBS_KNC1		0x0010
+#define SUBID_DVBS_KNC1_PLUS	0x0011
+#define SUBID_DVBS_TYPHOON	0x4f56
+#define SUBID_DVBS_CINERGY1200	0x1154
+
+#define SUBID_DVBC_KNC1		0x0020
+#define SUBID_DVBC_KNC1_PLUS	0x0021
+#define SUBID_DVBC_CINERGY1200	0x1156
+
+#define SUBID_DVBT_KNC1_PLUS	0x0031
+#define SUBID_DVBT_KNC1		0x0030
+#define SUBID_DVBT_CINERGY1200	0x1157
 
 static void frontend_init(struct budget_av *budget_av)
 {
-	switch (budget_av->budget.dev->pci->subsystem_device) {
-	case 0x0011:		// KNC1 DVB-S Plus budget with AV IN (stv0299/Philips SU1278(tsa5059))
-		saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend
-	case 0x4f56:		// Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
-	case 0x0010:		// KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059))
-		budget_av->budget.dvb_frontend =
-			stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap);
-		if (budget_av->budget.dvb_frontend != NULL) {
+	struct saa7146_dev * saa = budget_av->budget.dev;
+	struct dvb_frontend * fe = NULL;
+
+	switch (saa->pci->subsystem_device) {
+		case SUBID_DVBS_KNC1_PLUS:
+		case SUBID_DVBC_KNC1_PLUS:
+		case SUBID_DVBT_KNC1_PLUS:
+			// Enable / PowerON Frontend
+			saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
 			break;
-		}
+	}
+
+	switch (saa->pci->subsystem_device) {
+
+	case SUBID_DVBS_KNC1:
+	case SUBID_DVBS_KNC1_PLUS:
+	case SUBID_DVBS_TYPHOON:
+		fe = stv0299_attach(&typhoon_config,
+				    &budget_av->budget.i2c_adap);
 		break;
 
-	case 0x0021:		// KNC1 DVB-C Plus budget with AV IN (tda10021/Philips CU1216(tua6034))
-		saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend
-	case 0x0020:		// KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034))
-		budget_av->budget.dvb_frontend =
-			tda10021_attach(&philips_cu1216_config,
-					&budget_av->budget.i2c_adap, read_pwm(budget_av));
-		if (budget_av->budget.dvb_frontend != NULL) {
-			break;
-		}
+	case SUBID_DVBS_CINERGY1200:
+		fe = stv0299_attach(&cinergy_1200s_config,
+				    &budget_av->budget.i2c_adap);
 		break;
 
-	case 0x0031:		// KNC1 DVB-T Plus budget with AV IN (tda10046/Philips TU1216(tda6651tt))
-		saa7146_write(budget_av->budget.dev, GPIO_CTRL, 0x50000000); // Enable / PowerON Frontend
-	case 0x0030:		// KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt))
-		budget_av->budget.dvb_frontend =
-			tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
-		if (budget_av->budget.dvb_frontend != NULL) {
-			break;
-		}
+	case SUBID_DVBC_KNC1:
+	case SUBID_DVBC_KNC1_PLUS:
+		fe = tda10021_attach(&philips_cu1216_config,
+				     &budget_av->budget.i2c_adap,
+				     read_pwm(budget_av));
 		break;
 
-	case 0x1154:		// TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059))
-		budget_av->budget.dvb_frontend =
-			stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap);
-		if (budget_av->budget.dvb_frontend != NULL) {
-			break;
-		}
+	case SUBID_DVBT_KNC1:
+	case SUBID_DVBT_KNC1_PLUS:
+		fe = tda10046_attach(&philips_tu1216_config,
+				     &budget_av->budget.i2c_adap);
 		break;
 
-	case 0x1156:		// Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034))
-		budget_av->budget.dvb_frontend =
-			tda10021_attach(&philips_cu1216_config,
-					&budget_av->budget.i2c_adap, read_pwm(budget_av));
-		if (budget_av->budget.dvb_frontend) {
-			break;
-		}
+	case SUBID_DVBC_CINERGY1200:
+		fe = tda10021_attach(&philips_cu1216_config,
+				     &budget_av->budget.i2c_adap,
+				     read_pwm(budget_av));
 		break;
 
-	case 0x1157:		// Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt))
-		budget_av->budget.dvb_frontend =
-			tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap);
-		if (budget_av->budget.dvb_frontend) {
-			break;
-		}
+	case SUBID_DVBT_CINERGY1200:
+		fe = tda10046_attach(&philips_tu1216_config,
+				     &budget_av->budget.i2c_adap);
 		break;
 	}
 
-	if (budget_av->budget.dvb_frontend == NULL) {
-		printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
-		       budget_av->budget.dev->pci->vendor,
-		       budget_av->budget.dev->pci->device,
-		       budget_av->budget.dev->pci->subsystem_vendor,
-		       budget_av->budget.dev->pci->subsystem_device);
-	} else {
-		if (dvb_register_frontend
-		    (&budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) {
-			printk("budget-av: Frontend registration failed!\n");
-			if (budget_av->budget.dvb_frontend->ops->release)
-				budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
-			budget_av->budget.dvb_frontend = NULL;
-		}
+	if (fe == NULL) {
+		printk(KERN_ERR "budget-av: A frontend driver was not found "
+				"for device %04x/%04x subsystem %04x/%04x\n",
+		       saa->pci->vendor,
+		       saa->pci->device,
+		       saa->pci->subsystem_vendor,
+		       saa->pci->subsystem_device);
+		return;
+	}
+
+	budget_av->budget.dvb_frontend = fe;
+
+	if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
+				  budget_av->budget.dvb_frontend)) {
+		printk(KERN_ERR "budget-av: Frontend registration failed!\n");
+		if (budget_av->budget.dvb_frontend->ops->release)
+			budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend);
+		budget_av->budget.dvb_frontend = NULL;
 	}
 }
 
@@ -829,6 +858,7 @@ static int budget_av_attach(struct saa71
 
 	memset(budget_av, 0, sizeof(struct budget_av));
 
+	budget_av->has_saa7113 = 0;
 	budget_av->budget.ci_present = 0;
 
 	dev->ext_priv = budget_av;
@@ -843,10 +873,7 @@ static int budget_av_attach(struct saa71
 	saa7146_write(dev, DD1_INIT, 0x07000600);
 	saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
 
-	saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
-	msleep(500);
-
-	if (0 == saa7113_init(budget_av)) {
+	if (saa7113_init(budget_av) == 0) {
 		budget_av->has_saa7113 = 1;
 
 		if (0 != saa7146_vv_init(dev, &vv_data)) {
@@ -867,9 +894,7 @@ static int budget_av_attach(struct saa71
 
 		saa7113_setinput(budget_av, 0);
 	} else {
-		budget_av->has_saa7113 = 0;
-
-		saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
+		ciintf_init(budget_av);
 	}
 
 	/* fixme: find some sane values here... */
@@ -877,11 +902,11 @@ static int budget_av_attach(struct saa71
 
 	mac = budget_av->budget.dvb_adapter.proposed_mac;
 	if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
-		printk("KNC1-%d: Could not read MAC from KNC1 card\n",
+		printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
 		       budget_av->budget.dvb_adapter.num);
 		memset(mac, 0, 6);
 	} else {
-		printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
+		printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
 		       budget_av->budget.dvb_adapter.num,
 		       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 	}
@@ -889,9 +914,6 @@ static int budget_av_attach(struct saa71
 	budget_av->budget.dvb_adapter.priv = budget_av;
 	frontend_init(budget_av);
 
-	if (enable_ci)
-		ciintf_init(budget_av);
-
 	return 0;
 }
 
@@ -1024,5 +1046,3 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
 		   "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");
-module_param_named(enable_ci, enable_ci, int, 0644);
-MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off).");

--


  parent reply	other threads:[~2005-05-08 19:55 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-08 18:42 [DVB patch 00/37] DVB updates for 2.6.12-rc4 Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 01/37] support for TT/Hauppauge Nexus-S Rev 2.3 Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 02/37] saa7146: no need to initialize static/global variables to 0 Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 03/37] dvb_frontend: fix module param Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 04/37] av7110: audio out fix Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 05/37] add support for KNC-1 cards Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 06/37] remove unnecessary casts in dvb-core Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 07/37] make dvb_class static Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 08/37] dvb_net: handle IPv6 and LLC/SNAP Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 09/37] av7110: fix VIDEO_SET_DISPLAY_FORMAT Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 10/37] av7110: fix NTSC/PAL switching Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 11/37] av7110: fix comment Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 12/37] av7110: fix indentation Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 13/37] nxt6000: support frontend status reads Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 14/37] tda1004x: formatting cleanups Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 15/37] stv0299: fix FE_DISHNETWORK_SEND_LEGACY_CMD Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 16/37] remove unnecessary casts in frontends Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 17/37] dib3000: add NULL pointer check Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 18/37] ves1820: remove unnecessary msleep Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 19/37] mt352: embed struct mt352_config in mt352_state Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 20/37] tda1004x: dont use bitfields Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 21/37] tda1004x: allow N_I2C to be overridden by the card driver Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 22/37] tda10046: support for different firmware versions Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 23/37] dvb-pll.h: prevent multiple inclusion Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 24/37] make needlessly global code static or drop it Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 25/37] frontends: misc. minor cleanups Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 26/37] modified dvb_register_adapter() to avoid kmalloc/kfree Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 27/37] bt8xx: update documentation Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 28/37] DST: reorganize Twinhan DST driver to support CI Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 29/37] DST: add support for Twinhan 200103A Johannes Stezenbach
2005-05-08 18:42 ` [DVB patch 30/37] DST: fixed tuning problem Johannes Stezenbach
2005-05-08 18:43 ` [DVB patch 31/37] DST: fix for descrambling failure Johannes Stezenbach
2005-05-08 18:43 ` [DVB patch 32/37] DST: misc. fixes Johannes Stezenbach
2005-05-08 18:43 ` [DVB patch 33/37] bt8xx: updated documentation Johannes Stezenbach
2005-05-08 18:43 ` [DVB patch 34/37] DST: fix a bug in the module parameter Johannes Stezenbach
2005-05-08 18:43 ` [DVB patch 35/37] DST: fixed CI debug output Johannes Stezenbach
2005-05-08 18:43 ` [DVB patch 36/37] bt8xx: whitespace cleanup Johannes Stezenbach
2005-05-08 18:43 ` Johannes Stezenbach [this message]
2005-05-10  1:04 ` [DVB patch 00/37] DVB updates for 2.6.12-rc4 Andrew Morton
2005-05-10  8:52   ` Johannes Stezenbach
2005-05-10  9:16     ` Andrew Morton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050508184350.512000000@abc \
    --to=js@linuxtv.org \
    --cc=akpm@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).