idea on how to break the static dependencies on demodulator modules

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

 



Hi, Manu and I were just discussing this, and we think we have come up with an 
idea. See the attached patch.

Note: this is just an idea - it needs completed. The patch is just 
illustrative - it won't tune or anything.

Anyway: if you look at the frontend_init() code. Instead of calling the attach 
methods (eg. stv0299_attach()) directly, we instead define something like the 
macros I have added (e.g. STV0299_ATTACH).

These use symbol_get() to dynamically get the address of the XXX_attach() 
method and, if found, call it. Otherwise they fake a NULL return, and the 
normal frontend failure code comes into effect.

This method (suprisingly!) seems to work really well - dmesg for my test card 
in this machine when I modprobed the modified budget-ci module:

saa7146: register extension 'budget_ci dvb'.
ACPI: PCI Interrupt 0000:05:06.0[A] -> Link [APC1] -> GSI 16 (level, low) -> 
IRQ 66
saa7146: found saa7146 @ mem ffffc20010d04000 (revision 1, irq 66) 
(0x13c2,0x100f).
saa7146 (0): dma buffer size 192512
DVB: registering new adapter (TT-Budget/WinTV-NOVA-CI PCI).
adapter has MAC addr = 00:d0:5c:21:10:f5
input: Budget-CI dvb ir receiver saa7146 (0) as /class/input/input6
DVB: registering frontend 0 (ST STV0299 DVB-S)...

The only DVB modules loaded are however:
budget_ci
budget_core
saa7146
ttpci_eeprom
stv0299
dvb_core

Can anyone see anything fundamentally wrong with doing it this way? Due to the 
frontend refactoring a while back, we already have these nice tables of 
function pointers everywhere anyway.

We do have a few static function calls to deal with - I just hacked 'em out in 
the patch. With the PLL refactoring (see my other post) more of these are 
going away anyway, so the few remaining ones can be dealt with in some neater 
manner.
diff -r 2b05b5271ae1 linux/drivers/media/dvb/ttpci/budget-ci.c
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c	Thu Apr 13 12:29:04 2006 -0400
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c	Tue Apr 18 00:19:36 2006 +0100
@@ -590,6 +590,7 @@ static u8 philips_su1278_tt_inittab[] = 
 
 static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
 {
+/*
 	stv0299_writereg(fe, 0x0e, 0x44);
 	if (srate >= 10000000) {
 		stv0299_writereg(fe, 0x13, 0x97);
@@ -616,6 +617,7 @@ static int philips_su1278_tt_set_symbol_
 	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
 	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
 	stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
+*/
 
 	return 0;
 }
@@ -742,17 +744,17 @@ static int philips_tdm1316l_pll_set(stru
 	// setup PLL filter and TDA9889
 	switch (params->u.ofdm.bandwidth) {
 	case BANDWIDTH_6_MHZ:
-		tda1004x_write_byte(fe, 0x0C, 0x14);
+//		tda1004x_write_byte(fe, 0x0C, 0x14);
 		filter = 0;
 		break;
 
 	case BANDWIDTH_7_MHZ:
-		tda1004x_write_byte(fe, 0x0C, 0x80);
+//		tda1004x_write_byte(fe, 0x0C, 0x80);
 		filter = 0;
 		break;
 
 	case BANDWIDTH_8_MHZ:
-		tda1004x_write_byte(fe, 0x0C, 0x14);
+//		tda1004x_write_byte(fe, 0x0C, 0x14);
 		filter = 1;
 		break;
 
@@ -857,13 +859,13 @@ static int dvbc_philips_tdm1316l_pll_set
 	tuner_buf[3] = (cp << 5) | (filter << 3) | band;
 	tuner_buf[4] = 0x80;
 
-	stv0297_enable_plli2c(fe);
+//	stv0297_enable_plli2c(fe);
 	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
 		return -EIO;
 
 	msleep(50);
 
-	stv0297_enable_plli2c(fe);
+//	stv0297_enable_plli2c(fe);
 	if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
 		return -EIO;
 
@@ -972,23 +974,52 @@ static struct stv0297_config dvbc_philip
 	.pll_set = dvbc_philips_tdm1316l_pll_set,
 };
 
-
-
+#define STV0299_ATTACH(RESULT, CONFIG, I2C_ADAP) \
+{ \
+	struct dvb_frontend* (*a)(const struct stv0299_config* config, struct i2c_adapter* i2c); \
+	request_module("stv0299"); \
+	a = symbol_get(stv0299_attach); \
+	if (a) RESULT = a(CONFIG, I2C_ADAP); \
+	else RESULT = NULL; \
+}
+
+#define STV0297_ATTACH(RESULT, CONFIG, I2C_ADAP) \
+{ \
+	struct dvb_frontend* (*a)(const struct stv0297_config* config, struct i2c_adapter* i2c); \
+	request_module("stv0297"); \
+	a = symbol_get(stv0297_attach); \
+	if (a) RESULT = a(CONFIG, I2C_ADAP); \
+	else RESULT = NULL; \
+}
+
+#define TDA10045_ATTACH(RESULT, CONFIG, I2C_ADAP) {\
+	struct dvb_frontend* (*a)(const struct tda1004x_config* config, struct i2c_adapter* i2c); \
+	request_module("tda1004x"); \
+	a = symbol_get(tda10045_attach); \
+	if (a) RESULT = a(CONFIG, I2C_ADAP); \
+	else RESULT = NULL; \
+}
+
+#define TDA10046_ATTACH(RESULT, CONFIG, I2C_ADAP) {\
+	struct dvb_frontend* (*a)(const struct tda1004x_config* config, struct i2c_adapter* i2c); \
+	request_module("tda1004x"); \
+	a = symbol_get(tda10046_attach); \
+	if (a) RESULT = a(CONFIG, I2C_ADAP); \
+	else RESULT = NULL; \
+}
 
 static void frontend_init(struct budget_ci *budget_ci)
 {
 	switch (budget_ci->budget.dev->pci->subsystem_device) {
 	case 0x100c:		// Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
-		budget_ci->budget.dvb_frontend =
-			stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
+		STV0299_ATTACH(budget_ci->budget.dvb_frontend, &alps_bsru6_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			break;
 		}
 		break;
 
 	case 0x100f:		// Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
-		budget_ci->budget.dvb_frontend =
-			stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
+		STV0299_ATTACH(budget_ci->budget.dvb_frontend, &philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			break;
 		}
@@ -996,8 +1027,7 @@ static void frontend_init(struct budget_
 
 	case 0x1010:		// TT DVB-C CI budget (stv0297/Philips tdm1316l(tda6651tt))
 		budget_ci->tuner_pll_address = 0x61;
-		budget_ci->budget.dvb_frontend =
-			stv0297_attach(&dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+		STV0297_ATTACH(budget_ci->budget.dvb_frontend, &dvbc_philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			break;
 		}
@@ -1005,8 +1035,7 @@ static void frontend_init(struct budget_
 
 	case 0x1011:		// Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
 		budget_ci->tuner_pll_address = 0x63;
-		budget_ci->budget.dvb_frontend =
-			tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+		TDA10045_ATTACH(budget_ci->budget.dvb_frontend, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			break;
 		}
@@ -1014,15 +1043,14 @@ static void frontend_init(struct budget_
 
 	case 0x1012:		// TT DVB-T CI budget (tda10046/Philips tdm1316l(tda6651tt))
 		budget_ci->tuner_pll_address = 0x60;
-		budget_ci->budget.dvb_frontend =
-			tda10046_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
+		TDA10046_ATTACH(budget_ci->budget.dvb_frontend, &philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			break;
 		}
 		break;
 
 	case 0x1017:		// TT S-1500 PCI
-		budget_ci->budget.dvb_frontend = stv0299_attach(&alps_bsbe1_config, &budget_ci->budget.i2c_adap);
+		STV0299_ATTACH(budget_ci->budget.dvb_frontend, &alps_bsbe1_config, &budget_ci->budget.i2c_adap);
 		if (budget_ci->budget.dvb_frontend) {
 			budget_ci->budget.dvb_frontend->ops->dishnetwork_send_legacy_command = NULL;
 			if (lnbp21_init(budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0)) {
_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

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

  Powered by Linux