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
) {
359 int is_secam_l
= (params
->std
& (V4L2_STD_SECAM_L
| V4L2_STD_SECAM_LC
)) &&
360 !(params
->std
& ~(V4L2_STD_SECAM_L
| V4L2_STD_SECAM_LC
));
362 if (params
->std
== V4L2_STD_SECAM_LC
) {
363 if (t_params
->port1_active
^ t_params
->port1_invert_for_secam_lc
)
364 config
|= TDA9887_PORT1_ACTIVE
;
365 if (t_params
->port2_active
^ t_params
->port2_invert_for_secam_lc
)
366 config
|= TDA9887_PORT2_ACTIVE
;
369 if (t_params
->port1_active
)
370 config
|= TDA9887_PORT1_ACTIVE
;
371 if (t_params
->port2_active
)
372 config
|= TDA9887_PORT2_ACTIVE
;
374 if (t_params
->intercarrier_mode
)
375 config
|= TDA9887_INTERCARRIER
;
377 if (i
== 0 && t_params
->default_top_secam_low
)
378 config
|= TDA9887_TOP(t_params
->default_top_secam_low
);
379 else if (i
== 1 && t_params
->default_top_secam_mid
)
380 config
|= TDA9887_TOP(t_params
->default_top_secam_mid
);
381 else if (t_params
->default_top_secam_high
)
382 config
|= TDA9887_TOP(t_params
->default_top_secam_high
);
385 if (i
== 0 && t_params
->default_top_low
)
386 config
|= TDA9887_TOP(t_params
->default_top_low
);
387 else if (i
== 1 && t_params
->default_top_mid
)
388 config
|= TDA9887_TOP(t_params
->default_top_mid
);
389 else if (t_params
->default_top_high
)
390 config
|= TDA9887_TOP(t_params
->default_top_high
);
392 if (t_params
->default_pll_gating_18
)
393 config
|= TDA9887_GATING_18
;
394 i2c_clients_command(priv
->i2c_props
.adap
, TDA9887_SET_CONFIG
, &config
);
396 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
397 buffer
[0],buffer
[1],buffer
[2],buffer
[3]);
399 if (4 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,4)))
400 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc
);
402 switch (priv
->type
) {
403 case TUNER_LG_TDVS_H06XF
:
404 /* Set the Auxiliary Byte. */
405 buffer
[0] = buffer
[2];
409 tuner_dbg("tv 0x%02x 0x%02x\n",buffer
[0],buffer
[1]);
411 if (2 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,2)))
412 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc
);
414 case TUNER_MICROTUNE_4042FI5
:
416 // FIXME - this may also work for other tuners
417 unsigned long timeout
= jiffies
+ msecs_to_jiffies(1);
420 /* Wait until the PLL locks */
422 if (time_after(jiffies
,timeout
))
424 if (1 != (rc
= tuner_i2c_xfer_recv(&priv
->i2c_props
,&status_byte
,1))) {
425 tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc
);
428 if (status_byte
& TUNER_PLL_LOCKED
)
433 /* Set the charge pump for optimized phase noise figure */
434 config
&= ~TUNER_CHARGE_PUMP
;
435 buffer
[0] = (div
>>8) & 0x7f;
436 buffer
[1] = div
& 0xff;
439 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
440 buffer
[0],buffer
[1],buffer
[2],buffer
[3]);
442 if (4 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,4)))
443 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc
);
450 static int simple_set_radio_freq(struct dvb_frontend
*fe
,
451 struct analog_parameters
*params
)
453 struct tunertype
*tun
;
454 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
458 struct tuner_params
*t_params
;
459 unsigned int freq
= params
->frequency
;
463 for (j
= tun
->count
-1; j
> 0; j
--)
464 if (tun
->params
[j
].type
== TUNER_PARAM_TYPE_RADIO
)
466 /* default t_params (j=0) will be used if desired type wasn't found */
467 t_params
= &tun
->params
[j
];
469 /* Select Radio 1st IF used */
470 switch (t_params
->radio_if
) {
471 case 0: /* 10.7 MHz */
472 freq
+= (unsigned int)(10.7*16000);
474 case 1: /* 33.3 MHz */
475 freq
+= (unsigned int)(33.3*16000);
477 case 2: /* 41.3 MHz */
478 freq
+= (unsigned int)(41.3*16000);
481 tuner_warn("Unsupported radio_if value %d\n", t_params
->radio_if
);
485 /* Bandswitch byte */
486 switch (priv
->type
) {
487 case TUNER_TENA_9533_DI
:
488 case TUNER_YMEC_TVF_5533MF
:
489 tuner_dbg("This tuner doesn't have FM. Most cards have a TEA5767 for FM\n");
491 case TUNER_PHILIPS_FM1216ME_MK3
:
492 case TUNER_PHILIPS_FM1236_MK3
:
493 case TUNER_PHILIPS_FMD1216ME_MK3
:
494 case TUNER_LG_NTSC_TAPE
:
495 case TUNER_PHILIPS_FM1256_IH3
:
498 case TUNER_TNF_5335MF
:
501 case TUNER_LG_PAL_FM
:
504 case TUNER_THOMSON_DTT761X
:
507 case TUNER_MICROTUNE_4049FM5
:
513 buffer
[2] = (t_params
->ranges
[0].config
& ~TUNER_RATIO_MASK
) |
514 TUNER_RATIO_SELECT_50
; /* 50 kHz step */
516 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
517 freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
519 div
= (freq
+ 400) / 800;
521 if (t_params
->cb_first_if_lower_freq
&& div
< priv
->last_div
) {
522 buffer
[0] = buffer
[2];
523 buffer
[1] = buffer
[3];
524 buffer
[2] = (div
>>8) & 0x7f;
525 buffer
[3] = div
& 0xff;
527 buffer
[0] = (div
>>8) & 0x7f;
528 buffer
[1] = div
& 0xff;
531 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
532 buffer
[0],buffer
[1],buffer
[2],buffer
[3]);
533 priv
->last_div
= div
;
535 if (t_params
->has_tda9887
) {
537 if (t_params
->port1_active
&& !t_params
->port1_fm_high_sensitivity
)
538 config
|= TDA9887_PORT1_ACTIVE
;
539 if (t_params
->port2_active
&& !t_params
->port2_fm_high_sensitivity
)
540 config
|= TDA9887_PORT2_ACTIVE
;
541 if (t_params
->intercarrier_mode
)
542 config
|= TDA9887_INTERCARRIER
;
543 /* if (t_params->port1_set_for_fm_mono)
544 config &= ~TDA9887_PORT1_ACTIVE;*/
545 if (t_params
->fm_gain_normal
)
546 config
|= TDA9887_GAIN_NORMAL
;
547 if (t_params
->radio_if
== 2)
548 config
|= TDA9887_RIF_41_3
;
549 i2c_clients_command(priv
->i2c_props
.adap
, TDA9887_SET_CONFIG
, &config
);
551 if (4 != (rc
= tuner_i2c_xfer_send(&priv
->i2c_props
,buffer
,4)))
552 tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc
);
557 static int simple_set_params(struct dvb_frontend
*fe
,
558 struct analog_parameters
*params
)
560 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
563 switch (params
->mode
) {
564 case V4L2_TUNER_RADIO
:
565 ret
= simple_set_radio_freq(fe
, params
);
566 priv
->frequency
= params
->frequency
* 125 / 2;
568 case V4L2_TUNER_ANALOG_TV
:
569 case V4L2_TUNER_DIGITAL_TV
:
570 ret
= simple_set_tv_freq(fe
, params
);
571 priv
->frequency
= params
->frequency
* 62500;
579 static int simple_release(struct dvb_frontend
*fe
)
581 kfree(fe
->tuner_priv
);
582 fe
->tuner_priv
= NULL
;
587 static int simple_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
589 struct tuner_simple_priv
*priv
= fe
->tuner_priv
;
590 *frequency
= priv
->frequency
;
594 static struct dvb_tuner_ops simple_tuner_ops
= {
595 .set_analog_params
= simple_set_params
,
596 .release
= simple_release
,
597 .get_frequency
= simple_get_frequency
,
598 .get_status
= simple_get_status
,
599 .get_rf_strength
= simple_get_rf_strength
,
602 struct dvb_frontend
*simple_tuner_attach(struct dvb_frontend
*fe
,
603 struct i2c_adapter
*i2c_adap
,
605 struct simple_tuner_config
*cfg
)
607 struct tuner_simple_priv
*priv
= NULL
;
609 priv
= kzalloc(sizeof(struct tuner_simple_priv
), GFP_KERNEL
);
612 fe
->tuner_priv
= priv
;
614 priv
->i2c_props
.addr
= i2c_addr
;
615 priv
->i2c_props
.adap
= i2c_adap
;
616 priv
->type
= cfg
->type
;
617 priv
->tun
= cfg
->tun
;
619 memcpy(&fe
->ops
.tuner_ops
, &simple_tuner_ops
, sizeof(struct dvb_tuner_ops
));
621 tuner_info("type set to %d (%s)\n", cfg
->type
, cfg
->tun
->name
);
623 strlcpy(fe
->ops
.tuner_ops
.info
.name
, cfg
->tun
->name
, sizeof(fe
->ops
.tuner_ops
.info
.name
));
629 EXPORT_SYMBOL_GPL(simple_tuner_attach
);
631 MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
632 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
633 MODULE_LICENSE("GPL");
636 * Overrides for Emacs so that we follow Linus's tabbing style.
637 * ---------------------------------------------------------------------------