aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2007-08-27 20:22:20 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:07:35 -0400
commit910bb3e3c5a5d8ed5028846728efc6a375d200eb (patch)
treedae4791553084cd9a31b223be9f1aaf70c011be9 /drivers/media/video
parente18f9444bda60a67e6feef00c354f8de0cdaeba7 (diff)
V4L/DVB (6129): tda8290: convert from tuner sub-driver into dvb_frontend module
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Acked-by: Mike Isely <isely@pobox.com> Acked-by: Steven Toth <stoth@hauppauge.com> Acked-by: Patrick Boettcher <pb@linuxtv.org> Acked-by: Jarod Wilson <jwilson@redhat.com> Acked-by: Trent Piepho <xyzzy@speakeasy.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/tda8290.c367
-rw-r--r--drivers/media/video/tda8290.h35
-rw-r--r--drivers/media/video/tuner-core.c16
-rw-r--r--drivers/media/video/tuner-driver.h3
4 files changed, 270 insertions, 151 deletions
diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c
index beb4a7e1d286..ec731d6fbfb8 100644
--- a/drivers/media/video/tda8290.c
+++ b/drivers/media/video/tda8290.c
@@ -16,12 +16,21 @@
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software 17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 This "tda8290" module was split apart from the original "tuner" module.
19*/ 21*/
20 22
21#include <linux/i2c.h> 23#include <linux/i2c.h>
22#include <linux/delay.h> 24#include <linux/delay.h>
23#include <linux/videodev.h> 25#include <linux/videodev.h>
24#include "tuner-driver.h" 26#include "tuner-i2c.h"
27#include "tda8290.h"
28
29static int debug = 0;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "enable verbose debug messages");
32
33#define PREFIX "tda8290 "
25 34
26/* ---------------------------------------------------------------------- */ 35/* ---------------------------------------------------------------------- */
27 36
@@ -33,6 +42,11 @@ struct tda8290_priv {
33 unsigned char tda827x_addr; 42 unsigned char tda827x_addr;
34 unsigned char tda827x_ver; 43 unsigned char tda827x_ver;
35 unsigned int sgIF; 44 unsigned int sgIF;
45
46 u32 frequency;
47
48 unsigned int *lna_cfg;
49 int (*tuner_callback) (void *dev, int command,int arg);
36}; 50};
37 51
38/* ---------------------------------------------------------------------- */ 52/* ---------------------------------------------------------------------- */
@@ -81,19 +95,21 @@ static struct tda827x_data tda827x_analog[] = {
81 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */ 95 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} /* End */
82}; 96};
83 97
84static void tda827x_tune(struct tuner *t, u16 ifc, unsigned int freq) 98static void tda827x_set_analog_params(struct dvb_frontend *fe,
99 struct analog_parameters *params)
85{ 100{
86 unsigned char tuner_reg[8]; 101 unsigned char tuner_reg[8];
87 unsigned char reg2[2]; 102 unsigned char reg2[2];
88 u32 N; 103 u32 N;
89 int i; 104 int i;
90 struct tda8290_priv *priv = t->priv; 105 struct tda8290_priv *priv = fe->tuner_priv;
91 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0}; 106 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0};
107 unsigned int freq = params->frequency;
92 108
93 if (t->mode == V4L2_TUNER_RADIO) 109 if (params->mode == V4L2_TUNER_RADIO)
94 freq = freq / 1000; 110 freq = freq / 1000;
95 111
96 N = freq + ifc; 112 N = freq + priv->sgIF;
97 i = 0; 113 i = 0;
98 while (tda827x_analog[i].lomax < N) { 114 while (tda827x_analog[i].lomax < N) {
99 if(tda827x_analog[i + 1].lomax == 0) 115 if(tda827x_analog[i + 1].lomax == 0)
@@ -155,9 +171,9 @@ static void tda827x_tune(struct tuner *t, u16 ifc, unsigned int freq)
155 i2c_transfer(priv->i2c_props.adap, &msg, 1); 171 i2c_transfer(priv->i2c_props.adap, &msg, 1);
156} 172}
157 173
158static void tda827x_agcf(struct tuner *t) 174static void tda827x_agcf(struct dvb_frontend *fe)
159{ 175{
160 struct tda8290_priv *priv = t->priv; 176 struct tda8290_priv *priv = fe->tuner_priv;
161 unsigned char data[] = {0x80, 0x0c}; 177 unsigned char data[] = {0x80, 0x0c};
162 struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data, 178 struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data,
163 .flags = 0, .len = 2}; 179 .flags = 0, .len = 2};
@@ -204,57 +220,64 @@ static struct tda827xa_data tda827xa_analog[] = {
204 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */ 220 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} /* End */
205}; 221};
206 222
207static void tda827xa_lna_gain(struct tuner *t, int high) 223static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
224 struct analog_parameters *params)
208{ 225{
209 struct tda8290_priv *priv = t->priv; 226 struct tda8290_priv *priv = fe->tuner_priv;
210 unsigned char buf[] = {0x22, 0x01}; 227 unsigned char buf[] = {0x22, 0x01};
211 int arg; 228 int arg;
212 struct i2c_msg msg = {.addr = priv->i2c_props.addr, .flags = 0, .buf = buf, .len = sizeof(buf)}; 229 struct i2c_msg msg = {.addr = priv->i2c_props.addr, .flags = 0, .buf = buf, .len = sizeof(buf)};
213 if (t->config) { 230
231 if ((priv->lna_cfg == NULL) || (priv->tuner_callback == NULL))
232 return;
233
234 if (*priv->lna_cfg) {
214 if (high) 235 if (high)
215 tuner_dbg("setting LNA to high gain\n"); 236 tuner_dbg("setting LNA to high gain\n");
216 else 237 else
217 tuner_dbg("setting LNA to low gain\n"); 238 tuner_dbg("setting LNA to low gain\n");
218 } 239 }
219 switch (t->config) { 240 switch (*priv->lna_cfg) {
220 case 0: /* no LNA */ 241 case 0: /* no LNA */
221 break; 242 break;
222 case 1: /* switch is GPIO 0 of tda8290 */ 243 case 1: /* switch is GPIO 0 of tda8290 */
223 case 2: 244 case 2:
224 /* turn Vsync on */ 245 /* turn Vsync on */
225 if (t->std & V4L2_STD_MN) 246 if (params->std & V4L2_STD_MN)
226 arg = 1; 247 arg = 1;
227 else 248 else
228 arg = 0; 249 arg = 0;
229 if (t->tuner_callback) 250 if (priv->tuner_callback)
230 t->tuner_callback(priv->i2c_props.adap->algo_data, 1, arg); 251 priv->tuner_callback(priv->i2c_props.adap->algo_data, 1, arg);
231 buf[1] = high ? 0 : 1; 252 buf[1] = high ? 0 : 1;
232 if (t->config == 2) 253 if (*priv->lna_cfg == 2)
233 buf[1] = high ? 1 : 0; 254 buf[1] = high ? 1 : 0;
234 i2c_transfer(priv->i2c_props.adap, &msg, 1); 255 i2c_transfer(priv->i2c_props.adap, &msg, 1);
235 break; 256 break;
236 case 3: /* switch with GPIO of saa713x */ 257 case 3: /* switch with GPIO of saa713x */
237 if (t->tuner_callback) 258 if (priv->tuner_callback)
238 t->tuner_callback(priv->i2c_props.adap->algo_data, 0, high); 259 priv->tuner_callback(priv->i2c_props.adap->algo_data, 0, high);
239 break; 260 break;
240 } 261 }
241} 262}
242 263
243static void tda827xa_tune(struct tuner *t, u16 ifc, unsigned int freq) 264static void tda827xa_set_analog_params(struct dvb_frontend *fe,
265 struct analog_parameters *params)
244{ 266{
245 unsigned char tuner_reg[11]; 267 unsigned char tuner_reg[11];
246 u32 N; 268 u32 N;
247 int i; 269 int i;
248 struct tda8290_priv *priv = t->priv; 270 struct tda8290_priv *priv = fe->tuner_priv;
249 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0, .buf = tuner_reg}; 271 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags = 0, .buf = tuner_reg};
272 unsigned int freq = params->frequency;
250 273
251 tda827xa_lna_gain(t, 1); 274 tda827xa_lna_gain(fe, 1, params);
252 msleep(10); 275 msleep(10);
253 276
254 if (t->mode == V4L2_TUNER_RADIO) 277 if (params->mode == V4L2_TUNER_RADIO)
255 freq = freq / 1000; 278 freq = freq / 1000;
256 279
257 N = freq + ifc; 280 N = freq + priv->sgIF;
258 i = 0; 281 i = 0;
259 while (tda827xa_analog[i].lomax < N) { 282 while (tda827xa_analog[i].lomax < N) {
260 if(tda827xa_analog[i + 1].lomax == 0) 283 if(tda827xa_analog[i + 1].lomax == 0)
@@ -302,7 +325,7 @@ static void tda827xa_tune(struct tuner *t, u16 ifc, unsigned int freq)
302 tuner_reg[1] >>= 4; 325 tuner_reg[1] >>= 4;
303 tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]); 326 tuner_dbg("AGC2 gain is: %d\n", tuner_reg[1]);
304 if (tuner_reg[1] < 1) 327 if (tuner_reg[1] < 1)
305 tda827xa_lna_gain(t, 0); 328 tda827xa_lna_gain(fe, 0, params);
306 329
307 msleep(100); 330 msleep(100);
308 tuner_reg[0] = 0x60; 331 tuner_reg[0] = 0x60;
@@ -327,9 +350,9 @@ static void tda827xa_tune(struct tuner *t, u16 ifc, unsigned int freq)
327 i2c_transfer(priv->i2c_props.adap, &msg, 1); 350 i2c_transfer(priv->i2c_props.adap, &msg, 1);
328} 351}
329 352
330static void tda827xa_agcf(struct tuner *t) 353static void tda827xa_agcf(struct dvb_frontend *fe)
331{ 354{
332 struct tda8290_priv *priv = t->priv; 355 struct tda8290_priv *priv = fe->tuner_priv;
333 unsigned char data[] = {0x80, 0x2c}; 356 unsigned char data[] = {0x80, 0x2c};
334 struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data, 357 struct i2c_msg msg = {.addr = priv->tda827x_addr, .buf = data,
335 .flags = 0, .len = 2}; 358 .flags = 0, .len = 2};
@@ -338,9 +361,9 @@ static void tda827xa_agcf(struct tuner *t)
338 361
339/*---------------------------------------------------------------------*/ 362/*---------------------------------------------------------------------*/
340 363
341static void tda8290_i2c_bridge(struct tuner *t, int close) 364static void tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
342{ 365{
343 struct tda8290_priv *priv = t->priv; 366 struct tda8290_priv *priv = fe->tuner_priv;
344 367
345 unsigned char enable[2] = { 0x21, 0xC0 }; 368 unsigned char enable[2] = { 0x21, 0xC0 };
346 unsigned char disable[2] = { 0x21, 0x00 }; 369 unsigned char disable[2] = { 0x21, 0x00 };
@@ -358,9 +381,58 @@ static void tda8290_i2c_bridge(struct tuner *t, int close)
358 381
359/*---------------------------------------------------------------------*/ 382/*---------------------------------------------------------------------*/
360 383
361static int tda8290_tune(struct tuner *t, u16 ifc, unsigned int freq) 384static void set_audio(struct dvb_frontend *fe,
385 struct analog_parameters *params)
362{ 386{
363 struct tda8290_priv *priv = t->priv; 387 struct tda8290_priv *priv = fe->tuner_priv;
388 char* mode;
389
390 priv->tda827x_lpsel = 0;
391 if (params->std & V4L2_STD_MN) {
392 priv->sgIF = 92;
393 priv->tda8290_easy_mode = 0x01;
394 priv->tda827x_lpsel = 1;
395 mode = "MN";
396 } else if (params->std & V4L2_STD_B) {
397 priv->sgIF = 108;
398 priv->tda8290_easy_mode = 0x02;
399 mode = "B";
400 } else if (params->std & V4L2_STD_GH) {
401 priv->sgIF = 124;
402 priv->tda8290_easy_mode = 0x04;
403 mode = "GH";
404 } else if (params->std & V4L2_STD_PAL_I) {
405 priv->sgIF = 124;
406 priv->tda8290_easy_mode = 0x08;
407 mode = "I";
408 } else if (params->std & V4L2_STD_DK) {
409 priv->sgIF = 124;
410 priv->tda8290_easy_mode = 0x10;
411 mode = "DK";
412 } else if (params->std & V4L2_STD_SECAM_L) {
413 priv->sgIF = 124;
414 priv->tda8290_easy_mode = 0x20;
415 mode = "L";
416 } else if (params->std & V4L2_STD_SECAM_LC) {
417 priv->sgIF = 20;
418 priv->tda8290_easy_mode = 0x40;
419 mode = "LC";
420 } else {
421 priv->sgIF = 124;
422 priv->tda8290_easy_mode = 0x10;
423 mode = "xx";
424 }
425
426 if (params->mode == V4L2_TUNER_RADIO)
427 priv->sgIF = 88; /* if frequency is 5.5 MHz */
428
429 tuner_dbg("setting tda8290 to system %s\n", mode);
430}
431
432static int tda8290_set_params(struct dvb_frontend *fe,
433 struct analog_parameters *params)
434{
435 struct tda8290_priv *priv = fe->tuner_priv;
364 unsigned char soft_reset[] = { 0x00, 0x00 }; 436 unsigned char soft_reset[] = { 0x00, 0x00 };
365 unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode }; 437 unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode };
366 unsigned char expert_mode[] = { 0x01, 0x80 }; 438 unsigned char expert_mode[] = { 0x01, 0x80 };
@@ -383,7 +455,10 @@ static int tda8290_tune(struct tuner *t, u16 ifc, unsigned int freq)
383 pll_stat; 455 pll_stat;
384 int i; 456 int i;
385 457
386 tuner_dbg("tda827xa config is 0x%02x\n", t->config); 458 set_audio(fe, params);
459
460 if (priv->lna_cfg)
461 tuner_dbg("tda827xa config is 0x%02x\n", *priv->lna_cfg);
387 tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2); 462 tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
388 tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2); 463 tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
389 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2); 464 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
@@ -399,11 +474,11 @@ static int tda8290_tune(struct tuner *t, u16 ifc, unsigned int freq)
399 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2); 474 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
400 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2); 475 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
401 476
402 tda8290_i2c_bridge(t, 1); 477 tda8290_i2c_bridge(fe, 1);
403 if (priv->tda827x_ver != 0) 478 if (priv->tda827x_ver != 0)
404 tda827xa_tune(t, ifc, freq); 479 tda827xa_set_analog_params(fe, params);
405 else 480 else
406 tda827x_tune(t, ifc, freq); 481 tda827x_set_analog_params(fe, params);
407 for (i = 0; i < 3; i++) { 482 for (i = 0; i < 3; i++) {
408 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1); 483 tuner_i2c_xfer_send(&priv->i2c_props, &addr_pll_stat, 1);
409 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1); 484 tuner_i2c_xfer_recv(&priv->i2c_props, &pll_stat, 1);
@@ -433,9 +508,9 @@ static int tda8290_tune(struct tuner *t, u16 ifc, unsigned int freq)
433 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n", 508 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
434 agc_stat, pll_stat & 0x80); 509 agc_stat, pll_stat & 0x80);
435 if (priv->tda827x_ver != 0) 510 if (priv->tda827x_ver != 0)
436 tda827xa_agcf(t); 511 tda827xa_agcf(fe);
437 else 512 else
438 tda827x_agcf(t); 513 tda827x_agcf(fe);
439 msleep(100); 514 msleep(100);
440 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1); 515 tuner_i2c_xfer_send(&priv->i2c_props, &addr_agc_stat, 1);
441 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1); 516 tuner_i2c_xfer_recv(&priv->i2c_props, &agc_stat, 1);
@@ -464,120 +539,86 @@ static int tda8290_tune(struct tuner *t, u16 ifc, unsigned int freq)
464 } 539 }
465 } 540 }
466 541
467 tda8290_i2c_bridge(t, 0); 542 tda8290_i2c_bridge(fe, 0);
468 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2); 543 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
544
545 priv->frequency = (V4L2_TUNER_RADIO == params->mode) ?
546 params->frequency * 125 / 2 : params->frequency * 62500;
547
469 return 0; 548 return 0;
470} 549}
471 550
472/*---------------------------------------------------------------------*/ 551/*---------------------------------------------------------------------*/
473 552
474static void set_audio(struct tuner *t) 553static int tda8290_has_signal(struct dvb_frontend *fe)
475{ 554{
476 struct tda8290_priv *priv = t->priv; 555 struct tda8290_priv *priv = fe->tuner_priv;
477 char* mode;
478 556
479 priv->tda827x_lpsel = 0; 557 unsigned char i2c_get_afc[1] = { 0x1B };
480 if (t->std & V4L2_STD_MN) { 558 unsigned char afc = 0;
481 priv->sgIF = 92;
482 priv->tda8290_easy_mode = 0x01;
483 priv->tda827x_lpsel = 1;
484 mode = "MN";
485 } else if (t->std & V4L2_STD_B) {
486 priv->sgIF = 108;
487 priv->tda8290_easy_mode = 0x02;
488 mode = "B";
489 } else if (t->std & V4L2_STD_GH) {
490 priv->sgIF = 124;
491 priv->tda8290_easy_mode = 0x04;
492 mode = "GH";
493 } else if (t->std & V4L2_STD_PAL_I) {
494 priv->sgIF = 124;
495 priv->tda8290_easy_mode = 0x08;
496 mode = "I";
497 } else if (t->std & V4L2_STD_DK) {
498 priv->sgIF = 124;
499 priv->tda8290_easy_mode = 0x10;
500 mode = "DK";
501 } else if (t->std & V4L2_STD_SECAM_L) {
502 priv->sgIF = 124;
503 priv->tda8290_easy_mode = 0x20;
504 mode = "L";
505 } else if (t->std & V4L2_STD_SECAM_LC) {
506 priv->sgIF = 20;
507 priv->tda8290_easy_mode = 0x40;
508 mode = "LC";
509 } else {
510 priv->sgIF = 124;
511 priv->tda8290_easy_mode = 0x10;
512 mode = "xx";
513 }
514 tuner_dbg("setting tda8290 to system %s\n", mode);
515}
516
517static void set_tv_freq(struct tuner *t, unsigned int freq)
518{
519 struct tda8290_priv *priv = t->priv;
520 559
521 set_audio(t); 560 tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc));
522 tda8290_tune(t, priv->sgIF, freq); 561 tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1);
562 return (afc & 0x80)? 65535:0;
523} 563}
524 564
525static void set_radio_freq(struct tuner *t, unsigned int freq) 565static int tda8290_get_status(struct dvb_frontend *fe, u32 *status)
526{ 566{
527 /* if frequency is 5.5 MHz */ 567 struct tda8290_priv *priv = fe->tuner_priv;
528 tda8290_tune(t, 88, freq);
529}
530 568
531static int has_signal(struct tuner *t) 569 int signal = tda8290_has_signal(fe);
532{ 570 *status = 0;
533 struct tda8290_priv *priv = t->priv;
534 571
535 unsigned char i2c_get_afc[1] = { 0x1B }; 572 /* for now, report based on afc status */
536 unsigned char afc = 0; 573 if (signal)
574 *status = TUNER_STATUS_LOCKED;
537 575
538 tuner_i2c_xfer_send(&priv->i2c_props, i2c_get_afc, ARRAY_SIZE(i2c_get_afc)); 576 tuner_dbg("tda8290: AFC status: %d\n", signal);
539 tuner_i2c_xfer_recv(&priv->i2c_props, &afc, 1); 577
540 return (afc & 0x80)? 65535:0; 578 return 0;
541} 579}
542 580
543/*---------------------------------------------------------------------*/ 581/*---------------------------------------------------------------------*/
544 582
545static void standby(struct tuner *t) 583static int tda8290_standby(struct dvb_frontend *fe)
546{ 584{
547 struct tda8290_priv *priv = t->priv; 585 struct tda8290_priv *priv = fe->tuner_priv;
548 unsigned char cb1[] = { 0x30, 0xD0 }; 586 unsigned char cb1[] = { 0x30, 0xD0 };
549 unsigned char tda8290_standby[] = { 0x00, 0x02 }; 587 unsigned char tda8290_standby[] = { 0x00, 0x02 };
550 unsigned char tda8290_agc_tri[] = { 0x02, 0x20 }; 588 unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
551 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2}; 589 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
552 590
553 tda8290_i2c_bridge(t, 1); 591 tda8290_i2c_bridge(fe, 1);
554 if (priv->tda827x_ver != 0) 592 if (priv->tda827x_ver != 0)
555 cb1[1] = 0x90; 593 cb1[1] = 0x90;
556 i2c_transfer(priv->i2c_props.adap, &msg, 1); 594 i2c_transfer(priv->i2c_props.adap, &msg, 1);
557 tda8290_i2c_bridge(t, 0); 595 tda8290_i2c_bridge(fe, 0);
558 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2); 596 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
559 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2); 597 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
598
599 return 0;
560} 600}
561 601
562 602
563static void tda8290_init_if(struct tuner *t) 603static void tda8290_init_if(struct dvb_frontend *fe)
564{ 604{
565 struct tda8290_priv *priv = t->priv; 605 struct tda8290_priv *priv = fe->tuner_priv;
566 606
567 unsigned char set_VS[] = { 0x30, 0x6F }; 607 unsigned char set_VS[] = { 0x30, 0x6F };
568 unsigned char set_GP00_CF[] = { 0x20, 0x01 }; 608 unsigned char set_GP00_CF[] = { 0x20, 0x01 };
569 unsigned char set_GP01_CF[] = { 0x20, 0x0B }; 609 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
570 610
571 if ((t->config == 1) || (t->config == 2)) 611 if ((priv->lna_cfg) &&
612 ((*priv->lna_cfg == 1) || (*priv->lna_cfg == 2)))
572 tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2); 613 tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
573 else 614 else
574 tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2); 615 tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
575 tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2); 616 tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
576} 617}
577 618
578static void tda8290_init_tuner(struct tuner *t) 619static void tda8290_init_tuner(struct dvb_frontend *fe)
579{ 620{
580 struct tda8290_priv *priv = t->priv; 621 struct tda8290_priv *priv = fe->tuner_priv;
581 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf, 622 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
582 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; 623 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
583 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b, 624 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
@@ -587,28 +628,40 @@ static void tda8290_init_tuner(struct tuner *t)
587 if (priv->tda827x_ver != 0) 628 if (priv->tda827x_ver != 0)
588 msg.buf = tda8275a_init; 629 msg.buf = tda8275a_init;
589 630
590 tda8290_i2c_bridge(t, 1); 631 tda8290_i2c_bridge(fe, 1);
591 i2c_transfer(priv->i2c_props.adap, &msg, 1); 632 i2c_transfer(priv->i2c_props.adap, &msg, 1);
592 tda8290_i2c_bridge(t, 0); 633 tda8290_i2c_bridge(fe, 0);
593} 634}
594 635
595/*---------------------------------------------------------------------*/ 636/*---------------------------------------------------------------------*/
596 637
597static void tda8290_release(struct tuner *t) 638static int tda8290_release(struct dvb_frontend *fe)
598{ 639{
599 kfree(t->priv); 640 kfree(fe->tuner_priv);
600 t->priv = NULL; 641 fe->tuner_priv = NULL;
642
643 return 0;
601} 644}
602 645
603static struct tuner_operations tda8290_tuner_ops = { 646static int tda8290_get_frequency(struct dvb_frontend *fe, u32 *frequency)
604 .set_tv_freq = set_tv_freq, 647{
605 .set_radio_freq = set_radio_freq, 648 struct tda8290_priv *priv = fe->tuner_priv;
606 .has_signal = has_signal, 649 *frequency = priv->frequency;
607 .standby = standby, 650 return 0;
608 .release = tda8290_release, 651}
652
653static struct dvb_tuner_ops tda8290_tuner_ops = {
654 .sleep = tda8290_standby,
655 .set_analog_params = tda8290_set_params,
656 .release = tda8290_release,
657 .get_frequency = tda8290_get_frequency,
658 .get_status = tda8290_get_status,
609}; 659};
610 660
611int tda8290_init(struct tuner *t) 661struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
662 struct i2c_adapter* i2c_adap,
663 u8 i2c_addr,
664 struct tda8290_config *cfg)
612{ 665{
613 struct tda8290_priv *priv = NULL; 666 struct tda8290_priv *priv = NULL;
614 u8 data; 667 u8 data;
@@ -618,13 +671,17 @@ int tda8290_init(struct tuner *t)
618 671
619 priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); 672 priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
620 if (priv == NULL) 673 if (priv == NULL)
621 return -ENOMEM; 674 return NULL;
622 t->priv = priv; 675 fe->tuner_priv = priv;
623 676
624 priv->i2c_props.addr = t->i2c.addr; 677 priv->i2c_props.addr = i2c_addr;
625 priv->i2c_props.adap = t->i2c.adapter; 678 priv->i2c_props.adap = i2c_adap;
679 if (cfg) {
680 priv->lna_cfg = cfg->lna_cfg;
681 priv->tuner_callback = cfg->tuner_callback;
682 }
626 683
627 tda8290_i2c_bridge(t, 1); 684 tda8290_i2c_bridge(fe, 1);
628 /* probe for tuner chip */ 685 /* probe for tuner chip */
629 tuners_found = 0; 686 tuners_found = 0;
630 tuner_addrs = 0; 687 tuner_addrs = 0;
@@ -640,7 +697,7 @@ int tda8290_init(struct tuner *t)
640 behind the bridge and we choose the highest address that doesn't 697 behind the bridge and we choose the highest address that doesn't
641 give a response now 698 give a response now
642 */ 699 */
643 tda8290_i2c_bridge(t, 0); 700 tda8290_i2c_bridge(fe, 0);
644 if(tuners_found > 1) 701 if(tuners_found > 1)
645 for (i = 0; i < tuners_found; i++) { 702 for (i = 0; i < tuners_found; i++) {
646 msg.addr = tuner_addrs & 0xff; 703 msg.addr = tuner_addrs & 0xff;
@@ -652,41 +709,52 @@ int tda8290_init(struct tuner *t)
652 } 709 }
653 if (tuner_addrs == 0) { 710 if (tuner_addrs == 0) {
654 tuner_addrs = 0x61; 711 tuner_addrs = 0x61;
655 tuner_info ("could not clearly identify tuner address, defaulting to %x\n", 712 tuner_info("could not clearly identify tuner address, defaulting to %x\n",
656 tuner_addrs); 713 tuner_addrs);
657 } else { 714 } else {
658 tuner_addrs = tuner_addrs & 0xff; 715 tuner_addrs = tuner_addrs & 0xff;
659 tuner_info ("setting tuner address to %x\n", tuner_addrs); 716 tuner_info("setting tuner address to %x\n", tuner_addrs);
660 } 717 }
661 priv->tda827x_addr = tuner_addrs; 718 priv->tda827x_addr = tuner_addrs;
662 msg.addr = tuner_addrs; 719 msg.addr = tuner_addrs;
663 720
664 tda8290_i2c_bridge(t, 1); 721 tda8290_i2c_bridge(fe, 1);
665 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1); 722 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
666 if( ret != 1) 723 if( ret != 1)
667 tuner_warn ("TDA827x access failed!\n"); 724 tuner_warn("TDA827x access failed!\n");
725
726 memcpy(&fe->ops.tuner_ops, &tda8290_tuner_ops,
727 sizeof(struct dvb_tuner_ops));
728
668 if ((data & 0x3c) == 0) { 729 if ((data & 0x3c) == 0) {
669 strlcpy(t->i2c.name, "tda8290+75", sizeof(t->i2c.name)); 730 strlcpy(fe->ops.tuner_ops.info.name, "tda8290+75",
731 sizeof(fe->ops.tuner_ops.info.name));
732 fe->ops.tuner_ops.info.frequency_min = 55000000;
733 fe->ops.tuner_ops.info.frequency_max = 860000000;
734 fe->ops.tuner_ops.info.frequency_step = 250000;
670 priv->tda827x_ver = 0; 735 priv->tda827x_ver = 0;
671 } else { 736 } else {
672 strlcpy(t->i2c.name, "tda8290+75a", sizeof(t->i2c.name)); 737 strlcpy(fe->ops.tuner_ops.info.name, "tda8290+75a",
738 sizeof(fe->ops.tuner_ops.info.name));
739 fe->ops.tuner_ops.info.frequency_min = 44000000;
740 fe->ops.tuner_ops.info.frequency_max = 906000000;
741 fe->ops.tuner_ops.info.frequency_step = 62500;
673 priv->tda827x_ver = 2; 742 priv->tda827x_ver = 2;
674 } 743 }
675 tuner_info("type set to %s\n", t->i2c.name);
676
677 memcpy(&t->ops, &tda8290_tuner_ops, sizeof(struct tuner_operations));
678 744
679 priv->tda827x_lpsel = 0; 745 priv->tda827x_lpsel = 0;
680 t->mode = V4L2_TUNER_ANALOG_TV;
681 746
682 tda8290_init_tuner(t); 747 tda8290_init_tuner(fe);
683 tda8290_init_if(t); 748 tda8290_init_if(fe);
684 return 0; 749 return fe;
685} 750}
686 751
687int tda8290_probe(struct tuner *t) 752int tda8290_probe(struct i2c_adapter* i2c_adap, u8 i2c_addr)
688{ 753{
689 struct i2c_client *c = &t->i2c; 754 struct tuner_i2c_props i2c_props = {
755 .adap = i2c_adap,
756 .addr = i2c_addr
757 };
690 758
691 unsigned char soft_reset[] = { 0x00, 0x00 }; 759 unsigned char soft_reset[] = { 0x00, 0x00 };
692 unsigned char easy_mode_b[] = { 0x01, 0x02 }; 760 unsigned char easy_mode_b[] = { 0x01, 0x02 };
@@ -695,23 +763,30 @@ int tda8290_probe(struct tuner *t)
695 unsigned char addr_dto_lsb = 0x07; 763 unsigned char addr_dto_lsb = 0x07;
696 unsigned char data; 764 unsigned char data;
697 765
698 i2c_master_send(c, easy_mode_b, 2); 766 tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
699 i2c_master_send(c, soft_reset, 2); 767 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
700 i2c_master_send(c, &addr_dto_lsb, 1); 768 tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
701 i2c_master_recv(c, &data, 1); 769 tuner_i2c_xfer_recv(&i2c_props, &data, 1);
702 if (data == 0) { 770 if (data == 0) {
703 i2c_master_send(c, easy_mode_g, 2); 771 tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
704 i2c_master_send(c, soft_reset, 2); 772 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
705 i2c_master_send(c, &addr_dto_lsb, 1); 773 tuner_i2c_xfer_send(&i2c_props, &addr_dto_lsb, 1);
706 i2c_master_recv(c, &data, 1); 774 tuner_i2c_xfer_recv(&i2c_props, &data, 1);
707 if (data == 0x7b) { 775 if (data == 0x7b) {
708 return 0; 776 return 0;
709 } 777 }
710 } 778 }
711 i2c_master_send(c, restore_9886, 3); 779 tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
712 return -1; 780 return -1;
713} 781}
714 782
783EXPORT_SYMBOL_GPL(tda8290_probe);
784EXPORT_SYMBOL_GPL(tda8290_attach);
785
786MODULE_DESCRIPTION("Philips TDA8290 + TDA8275 / TDA8275a tuner driver");
787MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann");
788MODULE_LICENSE("GPL");
789
715/* 790/*
716 * Overrides for Emacs so that we follow Linus's tabbing style. 791 * Overrides for Emacs so that we follow Linus's tabbing style.
717 * --------------------------------------------------------------------------- 792 * ---------------------------------------------------------------------------
diff --git a/drivers/media/video/tda8290.h b/drivers/media/video/tda8290.h
new file mode 100644
index 000000000000..815ca1c78f80
--- /dev/null
+++ b/drivers/media/video/tda8290.h
@@ -0,0 +1,35 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TDA8290_H__
18#define __TDA8290_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23struct tda8290_config
24{
25 unsigned int *lna_cfg;
26 int (*tuner_callback) (void *dev, int command,int arg);
27};
28
29extern int tda8290_probe(struct i2c_adapter* i2c_adap, u8 i2c_addr);
30extern struct dvb_frontend *tda8290_attach(struct dvb_frontend *fe,
31 struct i2c_adapter* i2c_adap,
32 u8 i2c_addr,
33 struct tda8290_config *cfg);
34
35#endif /* __TDA8290_H__ */
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 183bbb9ba6ab..f37fe83b1995 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -19,6 +19,7 @@
19#include <media/tuner.h> 19#include <media/tuner.h>
20#include <media/v4l2-common.h> 20#include <media/v4l2-common.h>
21#include "tuner-driver.h" 21#include "tuner-driver.h"
22#include "tda8290.h"
22 23
23#define UNSET (-1U) 24#define UNSET (-1U)
24 25
@@ -200,6 +201,15 @@ static void tuner_i2c_address_check(struct tuner *t)
200 tuner_warn("====================== WARNING! ======================\n"); 201 tuner_warn("====================== WARNING! ======================\n");
201} 202}
202 203
204static void attach_tda8290(struct tuner *t)
205{
206 struct tda8290_config cfg = {
207 .lna_cfg = &t->config,
208 .tuner_callback = t->tuner_callback
209 };
210 tda8290_attach(&t->fe, t->i2c.adapter, t->i2c.addr, &cfg);
211}
212
203static void set_type(struct i2c_client *c, unsigned int type, 213static void set_type(struct i2c_client *c, unsigned int type,
204 unsigned int new_mode_mask, unsigned int new_config, 214 unsigned int new_mode_mask, unsigned int new_config,
205 int (*tuner_callback) (void *dev, int command,int arg)) 215 int (*tuner_callback) (void *dev, int command,int arg))
@@ -245,8 +255,10 @@ static void set_type(struct i2c_client *c, unsigned int type,
245 microtune_init(t); 255 microtune_init(t);
246 break; 256 break;
247 case TUNER_PHILIPS_TDA8290: 257 case TUNER_PHILIPS_TDA8290:
248 tda8290_init(t); 258 {
259 attach_tda8290(t);
249 break; 260 break;
261 }
250 case TUNER_TEA5767: 262 case TUNER_TEA5767:
251 if (tea5767_tuner_init(t) == EINVAL) { 263 if (tea5767_tuner_init(t) == EINVAL) {
252 t->type = TUNER_ABSENT; 264 t->type = TUNER_ABSENT;
@@ -575,7 +587,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
575 case 0x4b: 587 case 0x4b:
576 /* If chip is not tda8290, don't register. 588 /* If chip is not tda8290, don't register.
577 since it can be tda9887*/ 589 since it can be tda9887*/
578 if (tda8290_probe(t) == 0) { 590 if (tda8290_probe(t->i2c.adapter, t->i2c.addr) == 0) {
579 tuner_dbg("chip at addr %x is a tda8290\n", addr); 591 tuner_dbg("chip at addr %x is a tda8290\n", addr);
580 } else { 592 } else {
581 /* Default is being tda9887 */ 593 /* Default is being tda9887 */
diff --git a/drivers/media/video/tuner-driver.h b/drivers/media/video/tuner-driver.h
index d4c02b4abe71..05d5f8575673 100644
--- a/drivers/media/video/tuner-driver.h
+++ b/drivers/media/video/tuner-driver.h
@@ -78,9 +78,6 @@ extern int tda9887_tuner_init(struct tuner *t);
78 78
79extern int microtune_init(struct tuner *t); 79extern int microtune_init(struct tuner *t);
80 80
81extern int tda8290_init(struct tuner *t);
82extern int tda8290_probe(struct tuner *t);
83
84extern int tea5761_tuner_init(struct tuner *t); 81extern int tea5761_tuner_init(struct tuner *t);
85extern int tea5761_autodetection(struct tuner *t); 82extern int tea5761_autodetection(struct tuner *t);
86 83