]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/media/video/tuner-core.c
V4L/DVB (5563a): Add experimental support for tea5761 tuner
[mirror_ubuntu-bionic-kernel.git] / drivers / media / video / tuner-core.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2 *
3 * i2c tv tuner chip device driver
4 * core core, i.e. kernel interfaces, registering and so on
5 */
6
7#include <linux/module.h>
8#include <linux/moduleparam.h>
9#include <linux/kernel.h>
1da177e4
LT
10#include <linux/string.h>
11#include <linux/timer.h>
12#include <linux/delay.h>
13#include <linux/errno.h>
14#include <linux/slab.h>
15#include <linux/poll.h>
16#include <linux/i2c.h>
17#include <linux/types.h>
18#include <linux/videodev.h>
19#include <linux/init.h>
20
21#include <media/tuner.h>
5e453dc7 22#include <media/v4l2-common.h>
1da177e4
LT
23
24#define UNSET (-1U)
25
26/* standard i2c insmod options */
27static unsigned short normal_i2c[] = {
8573a9e6
MCC
28#ifdef CONFIG_TUNER_5761
29 0x10,
30#endif
de48eebc 31 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
f5bec396
MCC
32 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
33 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
1da177e4
LT
34 I2C_CLIENT_END
35};
f7ce3cc6 36
1da177e4
LT
37I2C_CLIENT_INSMOD;
38
39/* insmod options used at init time => read/only */
f7ce3cc6 40static unsigned int addr = 0;
c5287ba1 41static unsigned int no_autodetect = 0;
fd3113e8 42static unsigned int show_i2c = 0;
fd3113e8 43
1da177e4 44/* insmod options used at runtime => read/write */
f9195ded 45int tuner_debug = 0;
1da177e4 46
f7ce3cc6 47static unsigned int tv_range[2] = { 44, 958 };
1da177e4
LT
48static unsigned int radio_range[2] = { 65, 108 };
49
7e578191
MCC
50static char pal[] = "--";
51static char secam[] = "--";
52static char ntsc[] = "-";
53
f9195ded 54
7e578191
MCC
55module_param(addr, int, 0444);
56module_param(no_autodetect, int, 0444);
57module_param(show_i2c, int, 0444);
f9195ded 58module_param_named(debug,tuner_debug, int, 0644);
7e578191
MCC
59module_param_string(pal, pal, sizeof(pal), 0644);
60module_param_string(secam, secam, sizeof(secam), 0644);
61module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
f7ce3cc6 62module_param_array(tv_range, int, NULL, 0644);
1da177e4
LT
63module_param_array(radio_range, int, NULL, 0644);
64
65MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
66MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
67MODULE_LICENSE("GPL");
68
1da177e4
LT
69static struct i2c_driver driver;
70static struct i2c_client client_template;
71
72/* ---------------------------------------------------------------------- */
73
56fc08ca 74/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
1da177e4
LT
75static void set_tv_freq(struct i2c_client *c, unsigned int freq)
76{
77 struct tuner *t = i2c_get_clientdata(c);
78
79 if (t->type == UNSET) {
f7ce3cc6 80 tuner_warn ("tuner type not set\n");
1da177e4
LT
81 return;
82 }
27487d44 83 if (NULL == t->set_tv_freq) {
f7ce3cc6 84 tuner_warn ("Tuner has no way to set tv freq\n");
1da177e4
LT
85 return;
86 }
f7ce3cc6
MCC
87 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
88 tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
89 freq / 16, freq % 16 * 100 / 16, tv_range[0],
90 tv_range[1]);
27487d44
HV
91 /* V4L2 spec: if the freq is not possible then the closest
92 possible value should be selected */
93 if (freq < tv_range[0] * 16)
94 freq = tv_range[0] * 16;
95 else
96 freq = tv_range[1] * 16;
1da177e4 97 }
27487d44 98 t->set_tv_freq(c, freq);
1da177e4
LT
99}
100
101static void set_radio_freq(struct i2c_client *c, unsigned int freq)
102{
103 struct tuner *t = i2c_get_clientdata(c);
104
105 if (t->type == UNSET) {
f7ce3cc6 106 tuner_warn ("tuner type not set\n");
1da177e4
LT
107 return;
108 }
27487d44 109 if (NULL == t->set_radio_freq) {
f7ce3cc6 110 tuner_warn ("tuner has no way to set radio frequency\n");
1da177e4
LT
111 return;
112 }
27487d44 113 if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
f7ce3cc6
MCC
114 tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
115 freq / 16000, freq % 16000 * 100 / 16000,
116 radio_range[0], radio_range[1]);
27487d44
HV
117 /* V4L2 spec: if the freq is not possible then the closest
118 possible value should be selected */
119 if (freq < radio_range[0] * 16000)
120 freq = radio_range[0] * 16000;
121 else
122 freq = radio_range[1] * 16000;
1da177e4 123 }
586b0cab 124
27487d44 125 t->set_radio_freq(c, freq);
1da177e4
LT
126}
127
128static void set_freq(struct i2c_client *c, unsigned long freq)
129{
130 struct tuner *t = i2c_get_clientdata(c);
131
132 switch (t->mode) {
133 case V4L2_TUNER_RADIO:
134 tuner_dbg("radio freq set to %lu.%02lu\n",
f7ce3cc6
MCC
135 freq / 16000, freq % 16000 * 100 / 16000);
136 set_radio_freq(c, freq);
27487d44 137 t->radio_freq = freq;
1da177e4
LT
138 break;
139 case V4L2_TUNER_ANALOG_TV:
140 case V4L2_TUNER_DIGITAL_TV:
141 tuner_dbg("tv freq set to %lu.%02lu\n",
f7ce3cc6 142 freq / 16, freq % 16 * 100 / 16);
1da177e4 143 set_tv_freq(c, freq);
27487d44 144 t->tv_freq = freq;
1da177e4
LT
145 break;
146 }
1da177e4
LT
147}
148
f7ce3cc6 149static void set_type(struct i2c_client *c, unsigned int type,
de956c1e 150 unsigned int new_mode_mask, unsigned int new_config,
cfeb8839 151 int (*tuner_callback) (void *dev, int command,int arg))
1da177e4
LT
152{
153 struct tuner *t = i2c_get_clientdata(c);
586b0cab 154 unsigned char buffer[4];
1da177e4 155
f7ce3cc6
MCC
156 if (type == UNSET || type == TUNER_ABSENT) {
157 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
1da177e4 158 return;
f7ce3cc6
MCC
159 }
160
161 if (type >= tuner_count) {
162 tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count);
1da177e4 163 return;
f7ce3cc6 164 }
1da177e4 165
80f90fba
HH
166 t->type = type;
167 t->config = new_config;
168 if (tuner_callback != NULL) {
169 tuner_dbg("defining GPIO callback\n");
170 t->tuner_callback = tuner_callback;
171 }
172
f7ce3cc6 173 /* This code detects calls by card attach_inform */
1da177e4 174 if (NULL == t->i2c.dev.driver) {
f7ce3cc6
MCC
175 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
176
1da177e4
LT
177 return;
178 }
56fc08ca 179
1da177e4
LT
180 switch (t->type) {
181 case TUNER_MT2032:
182 microtune_init(c);
183 break;
184 case TUNER_PHILIPS_TDA8290:
185 tda8290_init(c);
186 break;
586b0cab 187 case TUNER_TEA5767:
f7ce3cc6
MCC
188 if (tea5767_tuner_init(c) == EINVAL) {
189 t->type = TUNER_ABSENT;
190 t->mode_mask = T_UNINITIALIZED;
191 return;
192 }
193 t->mode_mask = T_RADIO;
586b0cab 194 break;
8573a9e6
MCC
195#ifdef CONFIG_TUNER_5761
196 case TUNER_TEA5761:
197 if (tea5761_tuner_init(c) == EINVAL) {
198 t->type = TUNER_ABSENT;
199 t->mode_mask = T_UNINITIALIZED;
200 return -ENODEV;
201 }
202 t->mode_mask = T_RADIO;
203 break;
204#endif
586b0cab
MCC
205 case TUNER_PHILIPS_FMD1216ME_MK3:
206 buffer[0] = 0x0b;
207 buffer[1] = 0xdc;
208 buffer[2] = 0x9c;
209 buffer[3] = 0x60;
f7ce3cc6 210 i2c_master_send(c, buffer, 4);
586b0cab
MCC
211 mdelay(1);
212 buffer[2] = 0x86;
213 buffer[3] = 0x54;
f7ce3cc6 214 i2c_master_send(c, buffer, 4);
586b0cab
MCC
215 default_tuner_init(c);
216 break;
93df3413
HH
217 case TUNER_PHILIPS_TD1316:
218 buffer[0] = 0x0b;
219 buffer[1] = 0xdc;
220 buffer[2] = 0x86;
221 buffer[3] = 0xa4;
222 i2c_master_send(c,buffer,4);
223 default_tuner_init(c);
ac272ed7 224 break;
15396236
MCC
225 case TUNER_TDA9887:
226 tda9887_tuner_init(c);
227 break;
1da177e4
LT
228 default:
229 default_tuner_init(c);
230 break;
231 }
f7ce3cc6
MCC
232
233 if (t->mode_mask == T_UNINITIALIZED)
234 t->mode_mask = new_mode_mask;
235
27487d44 236 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq);
f7ce3cc6 237 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
604f28e2 238 c->adapter->name, c->driver->driver.name, c->addr << 1, type,
f7ce3cc6 239 t->mode_mask);
1da177e4
LT
240}
241
f7ce3cc6
MCC
242/*
243 * This function apply tuner config to tuner specified
244 * by tun_setup structure. I addr is unset, then admin status
245 * and tun addr status is more precise then current status,
246 * it's applied. Otherwise status and type are applied only to
247 * tuner with exactly the same addr.
248*/
249
250static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
251{
252 struct tuner *t = i2c_get_clientdata(c);
253
15396236
MCC
254 tuner_dbg("set addr for type %i\n", t->type);
255
de956c1e
HH
256 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
257 (t->mode_mask & tun_setup->mode_mask))) ||
258 (tun_setup->addr == c->addr)) {
259 set_type(c, tun_setup->type, tun_setup->mode_mask,
cfeb8839 260 tun_setup->config, tun_setup->tuner_callback);
f7ce3cc6
MCC
261 }
262}
56fc08ca 263
f7ce3cc6 264static inline int check_mode(struct tuner *t, char *cmd)
56fc08ca 265{
793cf9e6
MCC
266 if ((1 << t->mode & t->mode_mask) == 0) {
267 return EINVAL;
268 }
269
270 switch (t->mode) {
271 case V4L2_TUNER_RADIO:
272 tuner_dbg("Cmd %s accepted for radio\n", cmd);
273 break;
274 case V4L2_TUNER_ANALOG_TV:
275 tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
276 break;
277 case V4L2_TUNER_DIGITAL_TV:
278 tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
279 break;
56fc08ca 280 }
793cf9e6 281 return 0;
56fc08ca 282}
56fc08ca 283
f7ce3cc6 284/* get more precise norm info from insmod option */
1da177e4
LT
285static int tuner_fixup_std(struct tuner *t)
286{
287 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
1da177e4 288 switch (pal[0]) {
e71ced1a
HV
289 case '6':
290 tuner_dbg ("insmod fixup: PAL => PAL-60\n");
291 t->std = V4L2_STD_PAL_60;
292 break;
1da177e4
LT
293 case 'b':
294 case 'B':
295 case 'g':
296 case 'G':
f7ce3cc6 297 tuner_dbg ("insmod fixup: PAL => PAL-BG\n");
1da177e4
LT
298 t->std = V4L2_STD_PAL_BG;
299 break;
300 case 'i':
301 case 'I':
f7ce3cc6 302 tuner_dbg ("insmod fixup: PAL => PAL-I\n");
1da177e4
LT
303 t->std = V4L2_STD_PAL_I;
304 break;
305 case 'd':
306 case 'D':
307 case 'k':
308 case 'K':
f7ce3cc6 309 tuner_dbg ("insmod fixup: PAL => PAL-DK\n");
1da177e4
LT
310 t->std = V4L2_STD_PAL_DK;
311 break;
f7ce3cc6
MCC
312 case 'M':
313 case 'm':
314 tuner_dbg ("insmod fixup: PAL => PAL-M\n");
315 t->std = V4L2_STD_PAL_M;
316 break;
317 case 'N':
318 case 'n':
7e578191
MCC
319 if (pal[1] == 'c' || pal[1] == 'C') {
320 tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
321 t->std = V4L2_STD_PAL_Nc;
322 } else {
323 tuner_dbg ("insmod fixup: PAL => PAL-N\n");
324 t->std = V4L2_STD_PAL_N;
325 }
f7ce3cc6 326 break;
21d4df37
MCC
327 case '-':
328 /* default parameter, do nothing */
329 break;
330 default:
331 tuner_warn ("pal= argument not recognised\n");
332 break;
1da177e4
LT
333 }
334 }
f7ce3cc6
MCC
335 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
336 switch (secam[0]) {
7e578191
MCC
337 case 'b':
338 case 'B':
339 case 'g':
340 case 'G':
341 case 'h':
342 case 'H':
343 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
344 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
345 break;
f7ce3cc6
MCC
346 case 'd':
347 case 'D':
348 case 'k':
349 case 'K':
350 tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n");
351 t->std = V4L2_STD_SECAM_DK;
352 break;
353 case 'l':
354 case 'L':
800d3c6f
MCC
355 if ((secam[1]=='C')||(secam[1]=='c')) {
356 tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n");
357 t->std = V4L2_STD_SECAM_LC;
358 } else {
359 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
360 t->std = V4L2_STD_SECAM_L;
361 }
f7ce3cc6 362 break;
21d4df37
MCC
363 case '-':
364 /* default parameter, do nothing */
365 break;
366 default:
367 tuner_warn ("secam= argument not recognised\n");
368 break;
f7ce3cc6
MCC
369 }
370 }
371
7e578191
MCC
372 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
373 switch (ntsc[0]) {
374 case 'm':
375 case 'M':
376 tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
377 t->std = V4L2_STD_NTSC_M;
378 break;
379 case 'j':
380 case 'J':
381 tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
382 t->std = V4L2_STD_NTSC_M_JP;
383 break;
d97a11e0
HV
384 case 'k':
385 case 'K':
386 tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
387 t->std = V4L2_STD_NTSC_M_KR;
388 break;
7e578191
MCC
389 case '-':
390 /* default parameter, do nothing */
391 break;
392 default:
393 tuner_info("ntsc= argument not recognised\n");
394 break;
395 }
396 }
1da177e4
LT
397 return 0;
398}
399
7e578191
MCC
400static void tuner_status(struct i2c_client *client)
401{
402 struct tuner *t = i2c_get_clientdata(client);
403 unsigned long freq, freq_fraction;
404 const char *p;
405
406 switch (t->mode) {
407 case V4L2_TUNER_RADIO: p = "radio"; break;
408 case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break;
409 case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break;
410 default: p = "undefined"; break;
411 }
412 if (t->mode == V4L2_TUNER_RADIO) {
27487d44
HV
413 freq = t->radio_freq / 16000;
414 freq_fraction = (t->radio_freq % 16000) * 100 / 16000;
7e578191 415 } else {
27487d44
HV
416 freq = t->tv_freq / 16;
417 freq_fraction = (t->tv_freq % 16) * 100 / 16;
7e578191
MCC
418 }
419 tuner_info("Tuner mode: %s\n", p);
420 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
4ae5c2e5 421 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
8a4b275f
HV
422 if (t->mode != V4L2_TUNER_RADIO)
423 return;
424 if (t->has_signal) {
425 tuner_info("Signal strength: %d\n", t->has_signal(client));
426 }
427 if (t->is_stereo) {
428 tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
7e578191
MCC
429 }
430}
8a4b275f 431
1da177e4
LT
432/* ---------------------------------------------------------------------- */
433
ba8fc399 434/* static vars: used only in tuner_attach and tuner_probe */
f7ce3cc6
MCC
435static unsigned default_mode_mask;
436
437/* During client attach, set_type is called by adapter's attach_inform callback.
438 set_type must then be completed by tuner_attach.
439 */
1da177e4
LT
440static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
441{
442 struct tuner *t;
443
f7ce3cc6
MCC
444 client_template.adapter = adap;
445 client_template.addr = addr;
1da177e4 446
7408187d 447 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
f7ce3cc6
MCC
448 if (NULL == t)
449 return -ENOMEM;
f7ce3cc6 450 memcpy(&t->i2c, &client_template, sizeof(struct i2c_client));
1da177e4 451 i2c_set_clientdata(&t->i2c, t);
f7ce3cc6
MCC
452 t->type = UNSET;
453 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
454 t->audmode = V4L2_TUNER_MODE_STEREO;
455 t->mode_mask = T_UNINITIALIZED;
15396236 456 t->tuner_status = tuner_status;
f7ce3cc6 457
fd3113e8
MCC
458 if (show_i2c) {
459 unsigned char buffer[16];
460 int i,rc;
461
462 memset(buffer, 0, sizeof(buffer));
463 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
67678360 464 tuner_info("I2C RECV = ");
fd3113e8
MCC
465 for (i=0;i<rc;i++)
466 printk("%02x ",buffer[i]);
467 printk("\n");
468 }
c28089a6
MH
469 /* HACK: This test were added to avoid tuner to probe tda9840 and tea6415c on the MXB card */
470 if (adap->id == I2C_HW_SAA7146 && addr < 0x4a)
471 return -ENODEV;
472
257c645d 473 /* autodetection code based on the i2c addr */
c5287ba1 474 if (!no_autodetect) {
13dd38d0 475 switch (addr) {
8573a9e6
MCC
476#ifdef CONFIG_TUNER_5761
477 case 0x10:
478 if (tea5761_autodetection(&t->i2c) != EINVAL) {
479 t->type = TUNER_TEA5761;
480 t->mode_mask = T_RADIO;
481 t->mode = T_STANDBY;
482 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
483 default_mode_mask &= ~T_RADIO;
484
485 goto register_client;
486 }
487 break;
488#endif
13dd38d0
MCC
489 case 0x42:
490 case 0x43:
491 case 0x4a:
95736034 492 case 0x4b:
67678360
MCC
493 /* If chip is not tda8290, don't register.
494 since it can be tda9887*/
15396236
MCC
495 if (tda8290_probe(&t->i2c) == 0) {
496 tuner_dbg("chip at addr %x is a tda8290\n", addr);
497 } else {
498 /* Default is being tda9887 */
499 t->type = TUNER_TDA9887;
500 t->mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
501 t->mode = T_STANDBY;
502 goto register_client;
13dd38d0 503 }
07345f5d
HH
504 break;
505 case 0x60:
506 if (tea5767_autodetection(&t->i2c) != EINVAL) {
507 t->type = TUNER_TEA5767;
508 t->mode_mask = T_RADIO;
509 t->mode = T_STANDBY;
27487d44 510 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
07345f5d 511 default_mode_mask &= ~T_RADIO;
13dd38d0 512
07345f5d
HH
513 goto register_client;
514 }
515 break;
f7ce3cc6
MCC
516 }
517 }
1da177e4 518
f7ce3cc6
MCC
519 /* Initializes only the first adapter found */
520 if (default_mode_mask != T_UNINITIALIZED) {
521 tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask);
522 t->mode_mask = default_mode_mask;
27487d44
HV
523 t->tv_freq = 400 * 16; /* Sets freq to VHF High */
524 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
f7ce3cc6
MCC
525 default_mode_mask = T_UNINITIALIZED;
526 }
56fc08ca 527
f7ce3cc6 528 /* Should be just before return */
67678360
MCC
529register_client:
530 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
f7ce3cc6 531 i2c_attach_client (&t->i2c);
cfeb8839 532 set_type (&t->i2c,t->type, t->mode_mask, t->config, t->tuner_callback);
1da177e4
LT
533 return 0;
534}
535
536static int tuner_probe(struct i2c_adapter *adap)
537{
538 if (0 != addr) {
f5bec396
MCC
539 normal_i2c[0] = addr;
540 normal_i2c[1] = I2C_CLIENT_END;
1da177e4 541 }
1da177e4 542
f7ce3cc6 543 default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
391cd727 544
1da177e4
LT
545 if (adap->class & I2C_CLASS_TV_ANALOG)
546 return i2c_probe(adap, &addr_data, tuner_attach);
547 return 0;
548}
549
550static int tuner_detach(struct i2c_client *client)
551{
552 struct tuner *t = i2c_get_clientdata(client);
391cd727
MCC
553 int err;
554
f7ce3cc6 555 err = i2c_detach_client(&t->i2c);
391cd727 556 if (err) {
f7ce3cc6
MCC
557 tuner_warn
558 ("Client deregistration failed, client not detached.\n");
391cd727
MCC
559 return err;
560 }
1da177e4 561
1da177e4
LT
562 kfree(t);
563 return 0;
564}
565
f7ce3cc6
MCC
566/*
567 * Switch tuner to other mode. If tuner support both tv and radio,
568 * set another frequency to some value (This is needed for some pal
569 * tuners to avoid locking). Otherwise, just put second tuner in
570 * standby mode.
571 */
572
573static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
574{
4ac97914
MCC
575 if (mode == t->mode)
576 return 0;
577
578 t->mode = mode;
579
580 if (check_mode(t, cmd) == EINVAL) {
581 t->mode = T_STANDBY;
582 if (t->standby)
583 t->standby (client);
584 return EINVAL;
585 }
586 return 0;
f7ce3cc6
MCC
587}
588
589#define switch_v4l2() if (!t->using_v4l2) \
4ac97914
MCC
590 tuner_dbg("switching to v4l2\n"); \
591 t->using_v4l2 = 1;
f7ce3cc6
MCC
592
593static inline int check_v4l2(struct tuner *t)
594{
3bbe5a83
HV
595 /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
596 TV, v4l1 for radio), until that is fixed this code is disabled.
597 Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
598 first. */
f7ce3cc6
MCC
599 return 0;
600}
1da177e4 601
f7ce3cc6 602static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
1da177e4
LT
603{
604 struct tuner *t = i2c_get_clientdata(client);
1da177e4 605
f9195ded 606 if (tuner_debug>1)
5e453dc7
MK
607 v4l_i2c_print_ioctl(&(t->i2c),cmd);
608
f7ce3cc6 609 switch (cmd) {
1da177e4 610 /* --- configuration --- */
56fc08ca 611 case TUNER_SET_TYPE_ADDR:
de956c1e 612 tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
f7ce3cc6
MCC
613 ((struct tuner_setup *)arg)->type,
614 ((struct tuner_setup *)arg)->addr,
de956c1e
HH
615 ((struct tuner_setup *)arg)->mode_mask,
616 ((struct tuner_setup *)arg)->config);
f7ce3cc6
MCC
617
618 set_addr(client, (struct tuner_setup *)arg);
391cd727 619 break;
1da177e4 620 case AUDC_SET_RADIO:
27487d44
HV
621 if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
622 == EINVAL)
623 return 0;
624 if (t->radio_freq)
625 set_freq(client, t->radio_freq);
1da177e4 626 break;
793cf9e6 627 case TUNER_SET_STANDBY:
27487d44
HV
628 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
629 return 0;
15396236 630 t->mode = T_STANDBY;
27487d44
HV
631 if (t->standby)
632 t->standby (client);
633 break;
985bc96e 634#ifdef CONFIG_VIDEO_V4L1
fd3113e8
MCC
635 case VIDIOCSAUDIO:
636 if (check_mode(t, "VIDIOCSAUDIO") == EINVAL)
637 return 0;
638 if (check_v4l2(t) == EINVAL)
639 return 0;
640
641 /* Should be implemented, since bttv calls it */
642 tuner_dbg("VIDIOCSAUDIO not implemented.\n");
f7ce3cc6 643 break;
1da177e4 644 case VIDIOCSCHAN:
f7ce3cc6
MCC
645 {
646 static const v4l2_std_id map[] = {
647 [VIDEO_MODE_PAL] = V4L2_STD_PAL,
648 [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
649 [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
650 [4 /* bttv */ ] = V4L2_STD_PAL_M,
651 [5 /* bttv */ ] = V4L2_STD_PAL_N,
652 [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
653 };
654 struct video_channel *vc = arg;
655
656 if (check_v4l2(t) == EINVAL)
657 return 0;
658
659 if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL)
660 return 0;
661
662 if (vc->norm < ARRAY_SIZE(map))
663 t->std = map[vc->norm];
664 tuner_fixup_std(t);
27487d44
HV
665 if (t->tv_freq)
666 set_tv_freq(client, t->tv_freq);
f7ce3cc6
MCC
667 return 0;
668 }
1da177e4 669 case VIDIOCSFREQ:
f7ce3cc6
MCC
670 {
671 unsigned long *v = arg;
1da177e4 672
f7ce3cc6
MCC
673 if (check_mode(t, "VIDIOCSFREQ") == EINVAL)
674 return 0;
675 if (check_v4l2(t) == EINVAL)
676 return 0;
677
678 set_freq(client, *v);
679 return 0;
680 }
1da177e4 681 case VIDIOCGTUNER:
f7ce3cc6
MCC
682 {
683 struct video_tuner *vt = arg;
684
685 if (check_mode(t, "VIDIOCGTUNER") == EINVAL)
686 return 0;
687 if (check_v4l2(t) == EINVAL)
688 return 0;
689
690 if (V4L2_TUNER_RADIO == t->mode) {
691 if (t->has_signal)
692 vt->signal = t->has_signal(client);
693 if (t->is_stereo) {
694 if (t->is_stereo(client))
695 vt->flags |=
696 VIDEO_TUNER_STEREO_ON;
697 else
698 vt->flags &=
699 ~VIDEO_TUNER_STEREO_ON;
700 }
701 vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
586b0cab 702
f7ce3cc6
MCC
703 vt->rangelow = radio_range[0] * 16000;
704 vt->rangehigh = radio_range[1] * 16000;
586b0cab 705
f7ce3cc6
MCC
706 } else {
707 vt->rangelow = tv_range[0] * 16;
708 vt->rangehigh = tv_range[1] * 16;
709 }
56fc08ca 710
f7ce3cc6
MCC
711 return 0;
712 }
1da177e4 713 case VIDIOCGAUDIO:
f7ce3cc6
MCC
714 {
715 struct video_audio *va = arg;
716
717 if (check_mode(t, "VIDIOCGAUDIO") == EINVAL)
718 return 0;
719 if (check_v4l2(t) == EINVAL)
720 return 0;
721
722 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
723 va->mode = t->is_stereo(client)
724 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
725 return 0;
726 }
985bc96e
MCC
727#endif
728 case TDA9887_SET_CONFIG:
729 if (t->type == TUNER_TDA9887) {
730 int *i = arg;
1da177e4 731
985bc96e
MCC
732 t->tda9887_config = *i;
733 set_freq(client, t->tv_freq);
734 }
735 break;
736 /* --- v4l ioctls --- */
737 /* take care: bttv does userspace copying, we'll get a
738 kernel pointer here... */
1da177e4 739 case VIDIOC_S_STD:
f7ce3cc6
MCC
740 {
741 v4l2_std_id *id = arg;
1da177e4 742
f7ce3cc6
MCC
743 if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
744 == EINVAL)
745 return 0;
56fc08ca 746
f7ce3cc6
MCC
747 switch_v4l2();
748
749 t->std = *id;
750 tuner_fixup_std(t);
27487d44
HV
751 if (t->tv_freq)
752 set_freq(client, t->tv_freq);
f7ce3cc6
MCC
753 break;
754 }
1da177e4 755 case VIDIOC_S_FREQUENCY:
f7ce3cc6
MCC
756 {
757 struct v4l2_frequency *f = arg;
758
4f725cb3
HV
759 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
760 == EINVAL)
761 return 0;
f7ce3cc6 762 switch_v4l2();
27487d44 763 set_freq(client,f->frequency);
c184ca36 764
f7ce3cc6
MCC
765 break;
766 }
767 case VIDIOC_G_FREQUENCY:
768 {
769 struct v4l2_frequency *f = arg;
770
771 if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL)
772 return 0;
773 switch_v4l2();
774 f->type = t->mode;
27487d44
HV
775 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
776 t->radio_freq : t->tv_freq;
f7ce3cc6
MCC
777 break;
778 }
1da177e4 779 case VIDIOC_G_TUNER:
f7ce3cc6
MCC
780 {
781 struct v4l2_tuner *tuner = arg;
782
783 if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL)
784 return 0;
785 switch_v4l2();
786
8a4b275f 787 tuner->type = t->mode;
15396236
MCC
788 if (t->get_afc)
789 tuner->afc=t->get_afc(client);
ab4cecf9
HV
790 if (t->mode == V4L2_TUNER_ANALOG_TV)
791 tuner->capability |= V4L2_TUNER_CAP_NORM;
8a4b275f 792 if (t->mode != V4L2_TUNER_RADIO) {
f7ce3cc6
MCC
793 tuner->rangelow = tv_range[0] * 16;
794 tuner->rangehigh = tv_range[1] * 16;
8a4b275f
HV
795 break;
796 }
797
798 /* radio mode */
799 if (t->has_signal)
800 tuner->signal = t->has_signal(client);
801
802 tuner->rxsubchans =
803 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
804 if (t->is_stereo) {
805 tuner->rxsubchans = t->is_stereo(client) ?
806 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
56fc08ca 807 }
8a4b275f
HV
808
809 tuner->capability |=
810 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
811 tuner->audmode = t->audmode;
812 tuner->rangelow = radio_range[0] * 16000;
813 tuner->rangehigh = radio_range[1] * 16000;
f7ce3cc6
MCC
814 break;
815 }
816 case VIDIOC_S_TUNER:
817 {
818 struct v4l2_tuner *tuner = arg;
819
820 if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL)
821 return 0;
822
823 switch_v4l2();
824
8a4b275f
HV
825 /* do nothing unless we're a radio tuner */
826 if (t->mode != V4L2_TUNER_RADIO)
827 break;
828 t->audmode = tuner->audmode;
829 set_radio_freq(client, t->radio_freq);
f7ce3cc6 830 break;
56fc08ca 831 }
cd43c3f6 832 case VIDIOC_LOG_STATUS:
15396236
MCC
833 if (t->tuner_status)
834 t->tuner_status(client);
cd43c3f6 835 break;
1da177e4
LT
836 }
837
838 return 0;
839}
840
21b48a70 841static int tuner_suspend(struct i2c_client *c, pm_message_t state)
1da177e4 842{
f7ce3cc6 843 struct tuner *t = i2c_get_clientdata (c);
1da177e4 844
f7ce3cc6 845 tuner_dbg ("suspend\n");
1da177e4
LT
846 /* FIXME: power down ??? */
847 return 0;
848}
849
21b48a70 850static int tuner_resume(struct i2c_client *c)
1da177e4 851{
f7ce3cc6 852 struct tuner *t = i2c_get_clientdata (c);
1da177e4 853
f7ce3cc6 854 tuner_dbg ("resume\n");
27487d44
HV
855 if (V4L2_TUNER_RADIO == t->mode) {
856 if (t->radio_freq)
857 set_freq(c, t->radio_freq);
858 } else {
859 if (t->tv_freq)
860 set_freq(c, t->tv_freq);
861 }
1da177e4
LT
862 return 0;
863}
864
865/* ----------------------------------------------------------------------- */
866
867static struct i2c_driver driver = {
f7ce3cc6 868 .id = I2C_DRIVERID_TUNER,
f7ce3cc6
MCC
869 .attach_adapter = tuner_probe,
870 .detach_client = tuner_detach,
871 .command = tuner_command,
21b48a70
JD
872 .suspend = tuner_suspend,
873 .resume = tuner_resume,
1da177e4 874 .driver = {
cab462f7 875 .name = "tuner",
cab462f7 876 },
1da177e4 877};
f7ce3cc6 878static struct i2c_client client_template = {
fae91e72 879 .name = "(tuner unset)",
f7ce3cc6 880 .driver = &driver,
1da177e4
LT
881};
882
883static int __init tuner_init_module(void)
884{
885 return i2c_add_driver(&driver);
886}
887
888static void __exit tuner_cleanup_module(void)
889{
890 i2c_del_driver(&driver);
891}
892
893module_init(tuner_init_module);
894module_exit(tuner_cleanup_module);
895
896/*
897 * Overrides for Emacs so that we follow Linus's tabbing style.
898 * ---------------------------------------------------------------------------
899 * Local variables:
900 * c-basic-offset: 8
901 * End:
902 */