2 * i2c tv tuner chip device driver
3 * controls all those simple 4-control-bytes style tuners.
5 * This "tuner-simple" module was split apart from the original "tuner" module.
7 #include <linux/delay.h>
9 #include <linux/videodev.h>
10 #include <media/tuner.h>
11 #include <media/v4l2-common.h>
12 #include <media/tuner-types.h>
13 #include "tuner-i2c.h"
14 #include "tuner-simple.h"
17 module_param(debug
, int, 0644);
18 MODULE_PARM_DESC(debug
, "enable verbose debug messages");
20 #define PREFIX "tuner-simple"
22 static int offset
= 0;
23 module_param(offset
, int, 0664);
24 MODULE_PARM_DESC(offset
,"Allows to specify an offset for tuner");
26 /* ---------------------------------------------------------------------- */
28 /* tv standard selection for Temic 4046 FM5
29 this value takes the low bits of control byte 2
30 from datasheet Rev.01, Feb.00
32 picture IF 38.9 38.9 38.9 33.95 38.9
33 sound 1 33.4 32.9 32.4 40.45 32.4
35 NICAM 33.05 32.348 33.05 33.05
37 #define TEMIC_SET_PAL_I 0x05
38 #define TEMIC_SET_PAL_DK 0x09
39 #define TEMIC_SET_PAL_L 0x0a // SECAM ?
40 #define TEMIC_SET_PAL_L2 0x0b // change IF !
41 #define TEMIC_SET_PAL_BG 0x0c
43 /* tv tuner system standard selection for Philips FQ1216ME
44 this value takes the low bits of control byte 2
45 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
47 picture carrier 38.90 38.90 38.90 38.90 33.95
48 colour 34.47 34.47 34.47 34.47 38.38
49 sound 1 33.40 32.40 32.90 32.40 40.45
51 NICAM 33.05 33.05 32.35 33.05 39.80
53 #define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
54 #define PHILIPS_SET_PAL_BGDK 0x09
55 #define PHILIPS_SET_PAL_L2 0x0a
56 #define PHILIPS_SET_PAL_L 0x0b
58 /* system switching for Philips FI1216MF MK2
59 from datasheet "1996 Jul 09",
61 picture carrier 38.90 38.90 33.95
62 colour 34.47 34.37 38.38
63 sound 1 33.40 32.40 40.45
65 NICAM 33.05 33.05 39.80
67 #define PHILIPS_MF_SET_STD_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
68 #define PHILIPS_MF_SET_STD_L 0x03 /* Used on Secam France */
69 #define PHILIPS_MF_SET_STD_LC 0x02 /* Used on SECAM L' */
73 #define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */
74 #define TUNER_RATIO_SELECT_50 0x00
75 #define TUNER_RATIO_SELECT_32 0x02
76 #define TUNER_RATIO_SELECT_166 0x04
77 #define TUNER_RATIO_SELECT_62 0x06
79 #define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */
83 #define TUNER_POR 0x80
85 #define TUNER_MODE 0x38
86 #define TUNER_AFC 0x07
87 #define TUNER_SIGNAL 0x07
88 #define TUNER_STEREO 0x10
90 #define TUNER_PLL_LOCKED 0x40
91 #define TUNER_STEREO_MK3 0x04
93 struct tuner_simple_priv
{
95 struct tuner_i2c_props i2c_props
;
98 struct tunertype
*tun
;
103 /* ---------------------------------------------------------------------- */
105 static int tuner_read_status(struct dvb_frontend
*fe
)
107 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
110 if (1 != tuner_i2c_xfer_recv(&priv
->i2c_props
,&byte
,1))
116 static inline int tuner_signal(const int status
)
118 return (status
& TUNER_SIGNAL
) << 13;
121 static inline int tuner_stereo(const int type
, const int status
)
124 case TUNER_PHILIPS_FM1216ME_MK3
:
125 case TUNER_PHILIPS_FM1236_MK3
:
126 case TUNER_PHILIPS_FM1256_IH3
:
127 case TUNER_LG_NTSC_TAPE
:
128 return ((status
& TUNER_SIGNAL
) == TUNER_STEREO_MK3
);
130 return status
& TUNER_STEREO
;
134 static inline int tuner_islocked(const int status
)
136 return (status
& TUNER_FL
);
139 static inline int tuner_afcstatus(const int status
)
141 return (status
& TUNER_AFC
) - 2;
145 static int simple_get_status(struct dvb_frontend
*fe
, u32
*status
)
147 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
148 int tuner_status
= tuner_read_status(fe
);
152 if (tuner_islocked(tuner_status
))
153 *status
= TUNER_STATUS_LOCKED
;
154 if (tuner_stereo(priv
->type
, tuner_status
))
155 *status
|= TUNER_STATUS_STEREO
;
157 tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status
));
162 static int simple_get_rf_strength(struct dvb_frontend
*fe
, u16
*strength
)
164 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
165 int signal
= tuner_signal(tuner_read_status(fe
));
169 tuner_dbg("Signal strength: %d\n", signal
);
174 /* ---------------------------------------------------------------------- */
176 static int simple_set_tv_freq(struct dvb_frontend
*fe
,
177 struct analog_parameters
*params
)
179 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
180 u8 config
, cb
, tuneraddr
;
182 struct tunertype
*tun
;
184 int rc
, IFPCoff
, i
, j
;
185 enum param_type desired_type
;
186 struct tuner_params
*t_params
;
190 /* IFPCoff = Video Intermediate Frequency - Vif:
191 940 =16*58.75 NTSC/J (Japan)
192 732 =16*45.75 M/N STD
193 704 =16*44 ATSC (at DVB code)
195 622.4=16*38.90 B/G D/K I, L STD
196 592 =16*37.00 D China
197 590 =16.36.875 B Australia
198 543.2=16*33.95 L' STD
199 171.2=16*10.70 FM Radio (at set_radio_freq)
202 if (params
->std
== V4L2_STD_NTSC_M_JP
) {
204 desired_type
= TUNER_PARAM_TYPE_NTSC
;
205 } else if ((params
->std
& V4L2_STD_MN
) &&
206 !(params
->std
& ~V4L2_STD_MN
)) {
208 desired_type
= TUNER_PARAM_TYPE_NTSC
;
209 } else if (params
->std
== V4L2_STD_SECAM_LC
) {
211 desired_type
= TUNER_PARAM_TYPE_SECAM
;
214 desired_type
= TUNER_PARAM_TYPE_PAL
;
217 for (j
= 0; j
< tun
->count
-1; j
++) {
218 if (desired_type
!= tun
->params
[j
].type
)
222 /* use default tuner_t_params if desired_type not available */
223 if (desired_type
!= tun
->params
[j
].type
) {
224 tuner_dbg("IFPCoff = %d: tuner_t_params undefined for tuner %d\n",
225 IFPCoff
, priv
->type
);
228 t_params
= &tun
->params
[j
];
230 for (i
= 0; i
< t_params
->count
; i
++) {
231 if (params
->frequency
> t_params
->ranges
[i
].limit
)
235 if (i
== t_params
->count
) {
236 tuner_dbg("TV frequency out of range (%d > %d)",
237 params
->frequency
, t_params
->ranges
[i
- 1].limit
);
238 params
->frequency
= t_params
->ranges
[--i
].limit
;
240 config
= t_params
->ranges
[i
].config
;
241 cb
= t_params
->ranges
[i
].cb
;
245 tuner_dbg("tv: param %d, range %d\n",j
,i
);
247 div
=params
->frequency
+ IFPCoff
+ offset
;
249 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
250 params
->frequency
/ 16, params
->frequency
% 16 * 100 / 16,
251 IFPCoff
/ 16, IFPCoff
% 16 * 100 / 16,
252 offset
/ 16, offset
% 16 * 100 / 16,
255 /* tv norm specific stuff for multi-norm tuners */
256 switch (priv
->type
) {
257 case TUNER_PHILIPS_SECAM
: // FI1216MF
258 /* 0x01 -> ??? no change ??? */
259 /* 0x02 -> PAL BDGHI / SECAM L */
260 /* 0x04 -> ??? PAL others / SECAM others ??? */
262 if (params
->std
& V4L2_STD_SECAM_L
) //also valid for V4L2_STD_SECAM
263 cb
|= PHILIPS_MF_SET_STD_L
;
264 else if (params
->std
& V4L2_STD_SECAM_LC
)
265 cb
|= PHILIPS_MF_SET_STD_LC
;
266 else /* V4L2_STD_B|V4L2_STD_GH */
267 cb
|= PHILIPS_MF_SET_STD_BG
;
270 case TUNER_TEMIC_4046FM5
:
273 if (params
->std
& V4L2_STD_PAL_BG
) {
274 cb
|= TEMIC_SET_PAL_BG
;
276 } else if (params
->std
& V4L2_STD_PAL_I
) {
277 cb
|= TEMIC_SET_PAL_I
;
279 } else if (params
->std
& V4L2_STD_PAL_DK
) {
280 cb
|= TEMIC_SET_PAL_DK
;
282 } else if (params
->std
& V4L2_STD_SECAM_L
) {
283 cb
|= TEMIC_SET_PAL_L
;
288 case TUNER_PHILIPS_FQ1216ME
:
291 if (params
->std
& (V4L2_STD_PAL_BG
|V4L2_STD_PAL_DK
)) {
292 cb
|= PHILIPS_SET_PAL_BGDK
;
294 } else if (params
->std
& V4L2_STD_PAL_I
) {
295 cb
|= PHILIPS_SET_PAL_I
;
297 } else if (params
->std
& V4L2_STD_SECAM_L
) {
298 cb
|= PHILIPS_SET_PAL_L
;
303 case TUNER_PHILIPS_ATSC
:
304 /* 0x00 -> ATSC antenna input 1 */
305 /* 0x01 -> ATSC antenna input 2 */
306 /* 0x02 -> NTSC antenna input 1 */
307 /* 0x03 -> NTSC antenna input 2 */
309 if (!(params
->std
& V4L2_STD_ATSC
))
314 case TUNER_MICROTUNE_4042FI5
:
315 /* Set the charge pump for fast tuning */
316 config
|= TUNER_CHARGE_PUMP
;
319 case TUNER_PHILIPS_TUV1236D
:
320 /* 0x40 -> ATSC antenna input 1 */
321 /* 0x48 -> ATSC antenna input 2 */
322 /* 0x00 -> NTSC antenna input 1 */
323 /* 0x08 -> NTSC antenna input 2 */
329 if (params
->std
& V4L2_STD_ATSC
) {
333 /* set to the correct mode (analog or digital) */
334 tuneraddr
= priv
->i2c_props
.addr
;
335 priv
->i2c_props
.addr
= 0x0a;
336 if (2 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,&buffer
[0],2)))
337 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc
);
338 if (2 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,&buffer
[2],2)))
339 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc
);
340 priv
->i2c_props
.addr
= tuneraddr
;
345 if (t_params
->cb_first_if_lower_freq
&& div
< priv
->last_div
) {
348 buffer
[2] = (div
>>8) & 0x7f;
349 buffer
[3] = div
& 0xff;
351 buffer
[0] = (div
>>8) & 0x7f;
352 buffer
[1] = div
& 0xff;
356 priv
->last_div
= div
;
357 if (t_params
->has_tda9887
) {
358 struct v4l2_priv_tun_config tda9887_cfg
;
360 int is_secam_l
= (params
->std
& (V4L2_STD_SECAM_L
| V4L2_STD_SECAM_LC
)) &&
361 !(params
->std
& ~(V4L2_STD_SECAM_L
| V4L2_STD_SECAM_LC
));
363 tda9887_cfg
.tuner
= TUNER_TDA9887
;
364 tda9887_cfg
.priv
= &config
;
366 if (params
->std
== V4L2_STD_SECAM_LC
) {
367 if (t_params
->port1_active
^ t_params
->port1_invert_for_secam_lc
)
368 config
|= TDA9887_PORT1_ACTIVE
;
369 if (t_params
->port2_active
^ t_params
->port2_invert_for_secam_lc
)
370 config
|= TDA9887_PORT2_ACTIVE
;
373 if (t_params
->port1_active
)
374 config
|= TDA9887_PORT1_ACTIVE
;
375 if (t_params
->port2_active
)
376 config
|= TDA9887_PORT2_ACTIVE
;
378 if (t_params
->intercarrier_mode
)
379 config
|= TDA9887_INTERCARRIER
;
381 if (i
== 0 && t_params
->default_top_secam_low
)
382 config
|= TDA9887_TOP(t_params
->default_top_secam_low
);
383 else if (i
== 1 && t_params
->default_top_secam_mid
)
384 config
|= TDA9887_TOP(t_params
->default_top_secam_mid
);
385 else if (t_params
->default_top_secam_high
)
386 config
|= TDA9887_TOP(t_params
->default_top_secam_high
);
389 if (i
== 0 && t_params
->default_top_low
)
390 config
|= TDA9887_TOP(t_params
->default_top_low
);
391 else if (i
== 1 && t_params
->default_top_mid
)
392 config
|= TDA9887_TOP(t_params
->default_top_mid
);
393 else if (t_params
->default_top_high
)
394 config
|= TDA9887_TOP(t_params
->default_top_high
);
396 if (t_params
->default_pll_gating_18
)
397 config
|= TDA9887_GATING_18
;
398 i2c_clients_command(priv
->i2c_props
.adap
, TUNER_SET_CONFIG
,
401 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
402 buffer
[0],buffer
[1],buffer
[2],buffer
[3]);
404 if (4 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,4)))
405 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc
);
407 switch (priv
->type
) {
408 case TUNER_LG_TDVS_H06XF
:
409 /* Set the Auxiliary Byte. */
410 buffer
[0] = buffer
[2];
414 tuner_dbg("tv 0x%02x 0x%02x\n",buffer
[0],buffer
[1]);
416 if (2 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,2)))
417 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc
);
419 case TUNER_MICROTUNE_4042FI5
:
421 // FIXME - this may also work for other tuners
422 unsigned long timeout
= jiffies
+ msecs_to_jiffies(1);
425 /* Wait until the PLL locks */
427 if (time_after(jiffies
,timeout
))
429 if (1 != (rc
= tuner_i2c_xfer_recv(&priv
->i2c_props
,&status_byte
,1))) {
430 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc
);
433 if (status_byte
& TUNER_PLL_LOCKED
)
438 /* Set the charge pump for optimized phase noise figure */
439 config
&= ~TUNER_CHARGE_PUMP
;
440 buffer
[0] = (div
>>8) & 0x7f;
441 buffer
[1] = div
& 0xff;
444 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
445 buffer
[0],buffer
[1],buffer
[2],buffer
[3]);
447 if (4 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,4)))
448 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc
);
455 static int simple_set_radio_freq(struct dvb_frontend
*fe
,
456 struct analog_parameters
*params
)
458 struct tunertype
*tun
;
459 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
463 struct tuner_params
*t_params
;
464 unsigned int freq
= params
->frequency
;
468 for (j
= tun
->count
-1; j
> 0; j
--)
469 if (tun
->params
[j
].type
== TUNER_PARAM_TYPE_RADIO
)
471 /* default t_params (j=0) will be used if desired type wasn't found */
472 t_params
= &tun
->params
[j
];
474 /* Select Radio 1st IF used */
475 switch (t_params
->radio_if
) {
476 case 0: /* 10.7 MHz */
477 freq
+= (unsigned int)(10.7*16000);
479 case 1: /* 33.3 MHz */
480 freq
+= (unsigned int)(33.3*16000);
482 case 2: /* 41.3 MHz */
483 freq
+= (unsigned int)(41.3*16000);
486 tuner_warn("Unsupported radio_if value %d\n", t_params
->radio_if
);
490 /* Bandswitch byte */
491 switch (priv
->type
) {
492 case TUNER_TENA_9533_DI
:
493 case TUNER_YMEC_TVF_5533MF
:
494 tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n");
496 case TUNER_PHILIPS_FM1216ME_MK3
:
497 case TUNER_PHILIPS_FM1236_MK3
:
498 case TUNER_PHILIPS_FMD1216ME_MK3
:
499 case TUNER_LG_NTSC_TAPE
:
500 case TUNER_PHILIPS_FM1256_IH3
:
503 case TUNER_TNF_5335MF
:
506 case TUNER_LG_PAL_FM
:
509 case TUNER_THOMSON_DTT761X
:
512 case TUNER_MICROTUNE_4049FM5
:
518 buffer
[2] = (t_params
->ranges
[0].config
& ~TUNER_RATIO_MASK
) |
519 TUNER_RATIO_SELECT_50
; /* 50 kHz step */
521 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
522 freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
524 div
= (freq
+ 400) / 800;
526 if (t_params
->cb_first_if_lower_freq
&& div
< priv
->last_div
) {
527 buffer
[0] = buffer
[2];
528 buffer
[1] = buffer
[3];
529 buffer
[2] = (div
>>8) & 0x7f;
530 buffer
[3] = div
& 0xff;
532 buffer
[0] = (div
>>8) & 0x7f;
533 buffer
[1] = div
& 0xff;
536 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
537 buffer
[0],buffer
[1],buffer
[2],buffer
[3]);
538 priv
->last_div
= div
;
540 if (t_params
->has_tda9887
) {
542 struct v4l2_priv_tun_config tda9887_cfg
;
544 tda9887_cfg
.tuner
= TUNER_TDA9887
;
545 tda9887_cfg
.priv
= &config
;
547 if (t_params
->port1_active
&& !t_params
->port1_fm_high_sensitivity
)
548 config
|= TDA9887_PORT1_ACTIVE
;
549 if (t_params
->port2_active
&& !t_params
->port2_fm_high_sensitivity
)
550 config
|= TDA9887_PORT2_ACTIVE
;
551 if (t_params
->intercarrier_mode
)
552 config
|= TDA9887_INTERCARRIER
;
553 /* if (t_params->port1_set_for_fm_mono)
554 config &= ~TDA9887_PORT1_ACTIVE;*/
555 if (t_params
->fm_gain_normal
)
556 config
|= TDA9887_GAIN_NORMAL
;
557 if (t_params
->radio_if
== 2)
558 config
|= TDA9887_RIF_41_3
;
559 i2c_clients_command(priv
->i2c_props
.adap
, TUNER_SET_CONFIG
,
562 if (4 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,4)))
563 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc
);
568 static int simple_set_params(struct dvb_frontend
*fe
,
569 struct analog_parameters
*params
)
571 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
574 switch (params
->mode
) {
575 case V4L2_TUNER_RADIO
:
576 ret
= simple_set_radio_freq(fe
, params
);
577 priv
->frequency
= params
->frequency
* 125 / 2;
579 case V4L2_TUNER_ANALOG_TV
:
580 case V4L2_TUNER_DIGITAL_TV
:
581 ret
= simple_set_tv_freq(fe
, params
);
582 priv
->frequency
= params
->frequency
* 62500;
590 static int simple_release(struct dvb_frontend
*fe
)
592 kfree(fe
->tuner_priv
);
593 fe
->tuner_priv
= NULL
;
598 static int simple_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
600 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
601 *frequency
= priv
->frequency
;
605 static struct dvb_tuner_ops simple_tuner_ops
= {
606 .set_analog_params
= simple_set_params
,
607 .release
= simple_release
,
608 .get_frequency
= simple_get_frequency
,
609 .get_status
= simple_get_status
,
610 .get_rf_strength
= simple_get_rf_strength
,
613 struct dvb_frontend
*simple_tuner_attach(struct dvb_frontend
*fe
,
614 struct i2c_adapter
*i2c_adap
,
616 struct simple_tuner_config
*cfg
)
618 struct tuner_simple_priv
*priv
= NULL
;
620 priv
= kzalloc(sizeof(struct tuner_simple_priv
), GFP_KERNEL
);
623 fe
->tuner_priv
= priv
;
625 priv
->i2c_props
.addr
= i2c_addr
;
626 priv
->i2c_props
.adap
= i2c_adap
;
627 priv
->type
= cfg
->type
;
628 priv
->tun
= cfg
->tun
;
630 memcpy(&fe
->ops
.tuner_ops
, &simple_tuner_ops
, sizeof(struct dvb_tuner_ops
));
632 tuner_info("type set to %d (%s)\n", cfg
->type
, cfg
->tun
->name
);
634 strlcpy(fe
->ops
.tuner_ops
.info
.name
, cfg
->tun
->name
, sizeof(fe
->ops
.tuner_ops
.info
.name
));
640 EXPORT_SYMBOL_GPL(simple_tuner_attach
);
642 MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
643 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
644 MODULE_LICENSE("GPL");
647 * Overrides for Emacs so that we follow Linus's tabbing style.
648 * ---------------------------------------------------------------------------