aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2008-04-29 02:54:19 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-29 17:41:42 -0400
commita07c8779fd212dcbad886a2824ef5f8b42cd5a06 (patch)
treecabdff372f14dcb24673e3d675affd53564e9a10 /drivers/media/video
parent4407a463dd6afc892aedfbdc4237c42136d9f848 (diff)
V4L/DVB (7789): tuner: remove static dependencies on analog tuner sub-modules
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/tuner-core.c118
1 files changed, 75 insertions, 43 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 6d4b9217ec3e..578414efdb1a 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -33,6 +33,46 @@
33 33
34#define PREFIX t->i2c->driver->driver.name 34#define PREFIX t->i2c->driver->driver.name
35 35
36/** This macro allows us to probe dynamically, avoiding static links */
37#ifdef CONFIG_DVB_CORE_ATTACH
38#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
39 int __r = -EINVAL; \
40 typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
41 if (__a) { \
42 __r = (int) __a(ARGS); \
43 } else { \
44 printk(KERN_ERR "TUNER: Unable to find " \
45 "symbol "#FUNCTION"()\n"); \
46 } \
47 symbol_put(FUNCTION); \
48 __r; \
49})
50
51static void tuner_detach(struct dvb_frontend *fe)
52{
53 if (fe->ops.tuner_ops.release) {
54 fe->ops.tuner_ops.release(fe);
55 symbol_put_addr(fe->ops.tuner_ops.release);
56 }
57 if (fe->ops.analog_ops.release) {
58 fe->ops.analog_ops.release(fe);
59 symbol_put_addr(fe->ops.analog_ops.release);
60 }
61}
62#else
63#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
64 FUNCTION(ARGS); \
65})
66
67static void tuner_detach(struct dvb_frontend *fe)
68{
69 if (fe->ops.tuner_ops.release)
70 fe->ops.tuner_ops.release(fe);
71 if (fe->ops.analog_ops.release)
72 fe->ops.analog_ops.release(fe);
73}
74#endif
75
36struct tuner { 76struct tuner {
37 /* device */ 77 /* device */
38 struct dvb_frontend fe; 78 struct dvb_frontend fe;
@@ -139,22 +179,6 @@ static void fe_set_params(struct dvb_frontend *fe,
139 fe_tuner_ops->set_analog_params(fe, params); 179 fe_tuner_ops->set_analog_params(fe, params);
140} 180}
141 181
142static void fe_release(struct dvb_frontend *fe)
143{
144 if (fe->ops.tuner_ops.release)
145 fe->ops.tuner_ops.release(fe);
146
147 /* DO NOT kfree(fe->analog_demod_priv)
148 *
149 * If we are in this function, analog_demod_priv contains a pointer
150 * to struct tuner *t. This will be kfree'd in tuner_detach().
151 *
152 * Otherwise, fe->ops.analog_demod_ops->release will
153 * handle the cleanup for analog demodulator modules.
154 */
155 fe->analog_demod_priv = NULL;
156}
157
158static void fe_standby(struct dvb_frontend *fe) 182static void fe_standby(struct dvb_frontend *fe)
159{ 183{
160 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops; 184 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
@@ -191,7 +215,6 @@ static void tuner_status(struct dvb_frontend *fe);
191static struct analog_demod_ops tuner_core_ops = { 215static struct analog_demod_ops tuner_core_ops = {
192 .set_params = fe_set_params, 216 .set_params = fe_set_params,
193 .standby = fe_standby, 217 .standby = fe_standby,
194 .release = fe_release,
195 .has_signal = fe_has_signal, 218 .has_signal = fe_has_signal,
196 .set_config = fe_set_config, 219 .set_config = fe_set_config,
197 .tuner_status = tuner_status 220 .tuner_status = tuner_status
@@ -323,7 +346,8 @@ static void attach_tda829x(struct tuner *t)
323 .lna_cfg = t->config, 346 .lna_cfg = t->config,
324 .tuner_callback = t->tuner_callback, 347 .tuner_callback = t->tuner_callback,
325 }; 348 };
326 tda829x_attach(&t->fe, t->i2c->adapter, t->i2c->addr, &cfg); 349 dvb_attach(tda829x_attach,
350 &t->fe, t->i2c->adapter, t->i2c->addr, &cfg);
327} 351}
328 352
329static struct xc5000_config xc5000_cfg; 353static struct xc5000_config xc5000_cfg;
@@ -356,12 +380,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
356 } 380 }
357 381
358 /* discard private data, in case set_type() was previously called */ 382 /* discard private data, in case set_type() was previously called */
359 if (analog_ops->release) 383 tuner_detach(&t->fe);
360 analog_ops->release(&t->fe); 384 t->fe.analog_demod_priv = NULL;
361 385
362 switch (t->type) { 386 switch (t->type) {
363 case TUNER_MT2032: 387 case TUNER_MT2032:
364 microtune_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 388 dvb_attach(microtune_attach,
389 &t->fe, t->i2c->adapter, t->i2c->addr);
365 break; 390 break;
366 case TUNER_PHILIPS_TDA8290: 391 case TUNER_PHILIPS_TDA8290:
367 { 392 {
@@ -369,12 +394,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
369 break; 394 break;
370 } 395 }
371 case TUNER_TEA5767: 396 case TUNER_TEA5767:
372 if (!tea5767_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) 397 if (!dvb_attach(tea5767_attach, &t->fe,
398 t->i2c->adapter, t->i2c->addr))
373 goto attach_failed; 399 goto attach_failed;
374 t->mode_mask = T_RADIO; 400 t->mode_mask = T_RADIO;
375 break; 401 break;
376 case TUNER_TEA5761: 402 case TUNER_TEA5761:
377 if (!tea5761_attach(&t->fe, t->i2c->adapter, t->i2c->addr)) 403 if (!dvb_attach(tea5761_attach, &t->fe,
404 t->i2c->adapter, t->i2c->addr))
378 goto attach_failed; 405 goto attach_failed;
379 t->mode_mask = T_RADIO; 406 t->mode_mask = T_RADIO;
380 break; 407 break;
@@ -388,8 +415,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
388 buffer[2] = 0x86; 415 buffer[2] = 0x86;
389 buffer[3] = 0x54; 416 buffer[3] = 0x54;
390 i2c_master_send(c, buffer, 4); 417 i2c_master_send(c, buffer, 4);
391 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, t->i2c->addr, 418 if (!dvb_attach(simple_tuner_attach, &t->fe,
392 t->type)) 419 t->i2c->adapter, t->i2c->addr, t->type))
393 goto attach_failed; 420 goto attach_failed;
394 break; 421 break;
395 case TUNER_PHILIPS_TD1316: 422 case TUNER_PHILIPS_TD1316:
@@ -397,9 +424,9 @@ static void set_type(struct i2c_client *c, unsigned int type,
397 buffer[1] = 0xdc; 424 buffer[1] = 0xdc;
398 buffer[2] = 0x86; 425 buffer[2] = 0x86;
399 buffer[3] = 0xa4; 426 buffer[3] = 0xa4;
400 i2c_master_send(c,buffer,4); 427 i2c_master_send(c, buffer, 4);
401 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, 428 if (!dvb_attach(simple_tuner_attach, &t->fe,
402 t->i2c->addr, t->type)) 429 t->i2c->adapter, t->i2c->addr, t->type))
403 goto attach_failed; 430 goto attach_failed;
404 break; 431 break;
405 case TUNER_XC2028: 432 case TUNER_XC2028:
@@ -409,12 +436,13 @@ static void set_type(struct i2c_client *c, unsigned int type,
409 .i2c_addr = t->i2c->addr, 436 .i2c_addr = t->i2c->addr,
410 .callback = t->tuner_callback, 437 .callback = t->tuner_callback,
411 }; 438 };
412 if (!xc2028_attach(&t->fe, &cfg)) 439 if (!dvb_attach(xc2028_attach, &t->fe, &cfg))
413 goto attach_failed; 440 goto attach_failed;
414 break; 441 break;
415 } 442 }
416 case TUNER_TDA9887: 443 case TUNER_TDA9887:
417 tda9887_attach(&t->fe, t->i2c->adapter, t->i2c->addr); 444 dvb_attach(tda9887_attach,
445 &t->fe, t->i2c->adapter, t->i2c->addr);
418 break; 446 break;
419 case TUNER_XC5000: 447 case TUNER_XC5000:
420 { 448 {
@@ -424,7 +452,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
424 xc5000_cfg.if_khz = 5380; 452 xc5000_cfg.if_khz = 5380;
425 xc5000_cfg.priv = c->adapter->algo_data; 453 xc5000_cfg.priv = c->adapter->algo_data;
426 xc5000_cfg.tuner_callback = t->tuner_callback; 454 xc5000_cfg.tuner_callback = t->tuner_callback;
427 if (!xc5000_attach(&t->fe, t->i2c->adapter, &xc5000_cfg)) 455 if (!dvb_attach(xc5000_attach,
456 &t->fe, t->i2c->adapter, &xc5000_cfg))
428 goto attach_failed; 457 goto attach_failed;
429 458
430 xc_tuner_ops = &t->fe.ops.tuner_ops; 459 xc_tuner_ops = &t->fe.ops.tuner_ops;
@@ -433,8 +462,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
433 break; 462 break;
434 } 463 }
435 default: 464 default:
436 if (!simple_tuner_attach(&t->fe, t->i2c->adapter, 465 if (!dvb_attach(simple_tuner_attach, &t->fe,
437 t->i2c->addr, t->type)) 466 t->i2c->adapter, t->i2c->addr, t->type))
438 goto attach_failed; 467 goto attach_failed;
439 468
440 break; 469 break;
@@ -442,12 +471,14 @@ static void set_type(struct i2c_client *c, unsigned int type,
442 471
443 if ((NULL == analog_ops->set_params) && 472 if ((NULL == analog_ops->set_params) &&
444 (fe_tuner_ops->set_analog_params)) { 473 (fe_tuner_ops->set_analog_params)) {
474
445 strlcpy(t->i2c->name, fe_tuner_ops->info.name, 475 strlcpy(t->i2c->name, fe_tuner_ops->info.name,
446 sizeof(t->i2c->name)); 476 sizeof(t->i2c->name));
447 477
448 t->fe.analog_demod_priv = t; 478 t->fe.analog_demod_priv = t;
449 memcpy(analog_ops, &tuner_core_ops, 479 memcpy(analog_ops, &tuner_core_ops,
450 sizeof(struct analog_demod_ops)); 480 sizeof(struct analog_demod_ops));
481
451 } else { 482 } else {
452 strlcpy(t->i2c->name, analog_ops->info.name, 483 strlcpy(t->i2c->name, analog_ops->info.name,
453 sizeof(t->i2c->name)); 484 sizeof(t->i2c->name));
@@ -645,8 +676,8 @@ static void tuner_status(struct dvb_frontend *fe)
645{ 676{
646 struct tuner *t = fe->analog_demod_priv; 677 struct tuner *t = fe->analog_demod_priv;
647 unsigned long freq, freq_fraction; 678 unsigned long freq, freq_fraction;
648 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 679 struct dvb_tuner_ops *fe_tuner_ops = &fe->ops.tuner_ops;
649 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 680 struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
650 const char *p; 681 const char *p;
651 682
652 switch (t->mode) { 683 switch (t->mode) {
@@ -1113,8 +1144,9 @@ static int tuner_probe(struct i2c_client *client)
1113 if (!no_autodetect) { 1144 if (!no_autodetect) {
1114 switch (client->addr) { 1145 switch (client->addr) {
1115 case 0x10: 1146 case 0x10:
1116 if (tea5761_autodetection(t->i2c->adapter, 1147 if (tuner_symbol_probe(tea5761_autodetection,
1117 t->i2c->addr) >= 0) { 1148 t->i2c->adapter,
1149 t->i2c->addr) >= 0) {
1118 t->type = TUNER_TEA5761; 1150 t->type = TUNER_TEA5761;
1119 t->mode_mask = T_RADIO; 1151 t->mode_mask = T_RADIO;
1120 t->mode = T_STANDBY; 1152 t->mode = T_STANDBY;
@@ -1133,8 +1165,8 @@ static int tuner_probe(struct i2c_client *client)
1133 case 0x4b: 1165 case 0x4b:
1134 /* If chip is not tda8290, don't register. 1166 /* If chip is not tda8290, don't register.
1135 since it can be tda9887*/ 1167 since it can be tda9887*/
1136 if (tda829x_probe(t->i2c->adapter, 1168 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
1137 t->i2c->addr) == 0) { 1169 t->i2c->addr) == 0) {
1138 tuner_dbg("tda829x detected\n"); 1170 tuner_dbg("tda829x detected\n");
1139 } else { 1171 } else {
1140 /* Default is being tda9887 */ 1172 /* Default is being tda9887 */
@@ -1146,7 +1178,8 @@ static int tuner_probe(struct i2c_client *client)
1146 } 1178 }
1147 break; 1179 break;
1148 case 0x60: 1180 case 0x60:
1149 if (tea5767_autodetection(t->i2c->adapter, t->i2c->addr) 1181 if (tuner_symbol_probe(tea5767_autodetection,
1182 t->i2c->adapter, t->i2c->addr)
1150 != EINVAL) { 1183 != EINVAL) {
1151 t->type = TUNER_TEA5767; 1184 t->type = TUNER_TEA5767;
1152 t->mode_mask = T_RADIO; 1185 t->mode_mask = T_RADIO;
@@ -1235,10 +1268,9 @@ static int tuner_legacy_probe(struct i2c_adapter *adap)
1235static int tuner_remove(struct i2c_client *client) 1268static int tuner_remove(struct i2c_client *client)
1236{ 1269{
1237 struct tuner *t = i2c_get_clientdata(client); 1270 struct tuner *t = i2c_get_clientdata(client);
1238 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
1239 1271
1240 if (analog_ops->release) 1272 tuner_detach(&t->fe);
1241 analog_ops->release(&t->fe); 1273 t->fe.analog_demod_priv = NULL;
1242 1274
1243 list_del(&t->list); 1275 list_del(&t->list);
1244 kfree(t); 1276 kfree(t);