[PATCH] W1: possible cleanups
[linux-2.6/verdex.git] / drivers / media / video / tuner-core.c
blob1013b4de89a278c21ebf017a452e7cf73716b226
1 /*
3 * i2c tv tuner chip device driver
4 * core core, i.e. kernel interfaces, registering and so on
5 */
7 #include <linux/module.h>
8 #include <linux/moduleparam.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/string.h>
12 #include <linux/timer.h>
13 #include <linux/delay.h>
14 #include <linux/errno.h>
15 #include <linux/slab.h>
16 #include <linux/poll.h>
17 #include <linux/i2c.h>
18 #include <linux/types.h>
19 #include <linux/videodev.h>
20 #include <linux/init.h>
22 #include <media/tuner.h>
23 #include <media/v4l2-common.h>
25 #define UNSET (-1U)
27 /* standard i2c insmod options */
28 static unsigned short normal_i2c[] = {
29 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
30 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
31 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
32 I2C_CLIENT_END
35 I2C_CLIENT_INSMOD;
37 /* insmod options used at init time => read/only */
38 static unsigned int addr = 0;
39 static unsigned int no_autodetect = 0;
40 static unsigned int show_i2c = 0;
42 /* insmod options used at runtime => read/write */
43 static unsigned int tuner_debug_old = 0;
44 int tuner_debug = 0;
46 static unsigned int tv_range[2] = { 44, 958 };
47 static unsigned int radio_range[2] = { 65, 108 };
49 static char pal[] = "--";
50 static char secam[] = "--";
51 static char ntsc[] = "-";
54 module_param(addr, int, 0444);
55 module_param(no_autodetect, int, 0444);
56 module_param(show_i2c, int, 0444);
57 /* Note: tuner_debug is deprecated and will be removed in 2.6.17 */
58 module_param_named(tuner_debug,tuner_debug_old, int, 0444);
59 module_param_named(debug,tuner_debug, int, 0644);
60 module_param_string(pal, pal, sizeof(pal), 0644);
61 module_param_string(secam, secam, sizeof(secam), 0644);
62 module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
63 module_param_array(tv_range, int, NULL, 0644);
64 module_param_array(radio_range, int, NULL, 0644);
66 MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
67 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
68 MODULE_LICENSE("GPL");
70 static struct i2c_driver driver;
71 static struct i2c_client client_template;
73 /* ---------------------------------------------------------------------- */
75 /* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */
76 static void set_tv_freq(struct i2c_client *c, unsigned int freq)
78 struct tuner *t = i2c_get_clientdata(c);
80 if (t->type == UNSET) {
81 tuner_warn ("tuner type not set\n");
82 return;
84 if (NULL == t->set_tv_freq) {
85 tuner_warn ("Tuner has no way to set tv freq\n");
86 return;
88 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
89 tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
90 freq / 16, freq % 16 * 100 / 16, tv_range[0],
91 tv_range[1]);
92 /* V4L2 spec: if the freq is not possible then the closest
93 possible value should be selected */
94 if (freq < tv_range[0] * 16)
95 freq = tv_range[0] * 16;
96 else
97 freq = tv_range[1] * 16;
99 t->set_tv_freq(c, freq);
102 static void set_radio_freq(struct i2c_client *c, unsigned int freq)
104 struct tuner *t = i2c_get_clientdata(c);
106 if (t->type == UNSET) {
107 tuner_warn ("tuner type not set\n");
108 return;
110 if (NULL == t->set_radio_freq) {
111 tuner_warn ("tuner has no way to set radio frequency\n");
112 return;
114 if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
115 tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
116 freq / 16000, freq % 16000 * 100 / 16000,
117 radio_range[0], radio_range[1]);
118 /* V4L2 spec: if the freq is not possible then the closest
119 possible value should be selected */
120 if (freq < radio_range[0] * 16000)
121 freq = radio_range[0] * 16000;
122 else
123 freq = radio_range[1] * 16000;
126 t->set_radio_freq(c, freq);
129 static void set_freq(struct i2c_client *c, unsigned long freq)
131 struct tuner *t = i2c_get_clientdata(c);
133 switch (t->mode) {
134 case V4L2_TUNER_RADIO:
135 tuner_dbg("radio freq set to %lu.%02lu\n",
136 freq / 16000, freq % 16000 * 100 / 16000);
137 set_radio_freq(c, freq);
138 t->radio_freq = freq;
139 break;
140 case V4L2_TUNER_ANALOG_TV:
141 case V4L2_TUNER_DIGITAL_TV:
142 tuner_dbg("tv freq set to %lu.%02lu\n",
143 freq / 16, freq % 16 * 100 / 16);
144 set_tv_freq(c, freq);
145 t->tv_freq = freq;
146 break;
150 static void set_type(struct i2c_client *c, unsigned int type,
151 unsigned int new_mode_mask)
153 struct tuner *t = i2c_get_clientdata(c);
154 unsigned char buffer[4];
156 if (type == UNSET || type == TUNER_ABSENT) {
157 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr);
158 return;
161 if (type >= tuner_count) {
162 tuner_warn ("tuner 0x%02x: Tuner count greater than %d\n",c->addr,tuner_count);
163 return;
166 /* This code detects calls by card attach_inform */
167 if (NULL == t->i2c.dev.driver) {
168 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
170 t->type=type;
171 return;
174 t->type = type;
175 switch (t->type) {
176 case TUNER_MT2032:
177 microtune_init(c);
178 break;
179 case TUNER_PHILIPS_TDA8290:
180 tda8290_init(c);
181 break;
182 case TUNER_TEA5767:
183 if (tea5767_tuner_init(c) == EINVAL) {
184 t->type = TUNER_ABSENT;
185 t->mode_mask = T_UNINITIALIZED;
186 return;
188 t->mode_mask = T_RADIO;
189 break;
190 case TUNER_PHILIPS_FMD1216ME_MK3:
191 buffer[0] = 0x0b;
192 buffer[1] = 0xdc;
193 buffer[2] = 0x9c;
194 buffer[3] = 0x60;
195 i2c_master_send(c, buffer, 4);
196 mdelay(1);
197 buffer[2] = 0x86;
198 buffer[3] = 0x54;
199 i2c_master_send(c, buffer, 4);
200 default_tuner_init(c);
201 break;
202 case TUNER_LG_TDVS_H062F:
203 /* Set the Auxiliary Byte. */
204 buffer[2] &= ~0x20;
205 buffer[2] |= 0x18;
206 buffer[3] = 0x20;
207 i2c_master_send(c, buffer, 4);
208 default_tuner_init(c);
209 break;
210 case TUNER_PHILIPS_TD1316:
211 buffer[0] = 0x0b;
212 buffer[1] = 0xdc;
213 buffer[2] = 0x86;
214 buffer[3] = 0xa4;
215 i2c_master_send(c,buffer,4);
216 default_tuner_init(c);
217 break;
218 default:
219 default_tuner_init(c);
220 break;
223 if (t->mode_mask == T_UNINITIALIZED)
224 t->mode_mask = new_mode_mask;
226 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? t->radio_freq : t->tv_freq);
227 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
228 c->adapter->name, c->driver->driver.name, c->addr << 1, type,
229 t->mode_mask);
233 * This function apply tuner config to tuner specified
234 * by tun_setup structure. I addr is unset, then admin status
235 * and tun addr status is more precise then current status,
236 * it's applied. Otherwise status and type are applied only to
237 * tuner with exactly the same addr.
240 static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup)
242 struct tuner *t = i2c_get_clientdata(c);
244 if ( t->type == UNSET && ((tun_setup->addr == ADDR_UNSET &&
245 (t->mode_mask & tun_setup->mode_mask)) ||
246 tun_setup->addr == c->addr)) {
247 set_type(c, tun_setup->type, tun_setup->mode_mask);
251 static inline int check_mode(struct tuner *t, char *cmd)
253 if ((1 << t->mode & t->mode_mask) == 0) {
254 return EINVAL;
257 switch (t->mode) {
258 case V4L2_TUNER_RADIO:
259 tuner_dbg("Cmd %s accepted for radio\n", cmd);
260 break;
261 case V4L2_TUNER_ANALOG_TV:
262 tuner_dbg("Cmd %s accepted for analog TV\n", cmd);
263 break;
264 case V4L2_TUNER_DIGITAL_TV:
265 tuner_dbg("Cmd %s accepted for digital TV\n", cmd);
266 break;
268 return 0;
271 /* get more precise norm info from insmod option */
272 static int tuner_fixup_std(struct tuner *t)
274 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
275 switch (pal[0]) {
276 case 'b':
277 case 'B':
278 case 'g':
279 case 'G':
280 tuner_dbg ("insmod fixup: PAL => PAL-BG\n");
281 t->std = V4L2_STD_PAL_BG;
282 break;
283 case 'i':
284 case 'I':
285 tuner_dbg ("insmod fixup: PAL => PAL-I\n");
286 t->std = V4L2_STD_PAL_I;
287 break;
288 case 'd':
289 case 'D':
290 case 'k':
291 case 'K':
292 tuner_dbg ("insmod fixup: PAL => PAL-DK\n");
293 t->std = V4L2_STD_PAL_DK;
294 break;
295 case 'M':
296 case 'm':
297 tuner_dbg ("insmod fixup: PAL => PAL-M\n");
298 t->std = V4L2_STD_PAL_M;
299 break;
300 case 'N':
301 case 'n':
302 if (pal[1] == 'c' || pal[1] == 'C') {
303 tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
304 t->std = V4L2_STD_PAL_Nc;
305 } else {
306 tuner_dbg ("insmod fixup: PAL => PAL-N\n");
307 t->std = V4L2_STD_PAL_N;
309 break;
310 case '-':
311 /* default parameter, do nothing */
312 break;
313 default:
314 tuner_warn ("pal= argument not recognised\n");
315 break;
318 if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
319 switch (secam[0]) {
320 case 'b':
321 case 'B':
322 case 'g':
323 case 'G':
324 case 'h':
325 case 'H':
326 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
327 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H;
328 break;
329 case 'd':
330 case 'D':
331 case 'k':
332 case 'K':
333 tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n");
334 t->std = V4L2_STD_SECAM_DK;
335 break;
336 case 'l':
337 case 'L':
338 if ((secam[1]=='C')||(secam[1]=='c')) {
339 tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n");
340 t->std = V4L2_STD_SECAM_LC;
341 } else {
342 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n");
343 t->std = V4L2_STD_SECAM_L;
345 break;
346 case '-':
347 /* default parameter, do nothing */
348 break;
349 default:
350 tuner_warn ("secam= argument not recognised\n");
351 break;
355 if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
356 switch (ntsc[0]) {
357 case 'm':
358 case 'M':
359 tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
360 t->std = V4L2_STD_NTSC_M;
361 break;
362 case 'j':
363 case 'J':
364 tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
365 t->std = V4L2_STD_NTSC_M_JP;
366 break;
367 case 'k':
368 case 'K':
369 tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
370 t->std = V4L2_STD_NTSC_M_KR;
371 break;
372 case '-':
373 /* default parameter, do nothing */
374 break;
375 default:
376 tuner_info("ntsc= argument not recognised\n");
377 break;
380 return 0;
383 static void tuner_status(struct i2c_client *client)
385 struct tuner *t = i2c_get_clientdata(client);
386 unsigned long freq, freq_fraction;
387 const char *p;
389 switch (t->mode) {
390 case V4L2_TUNER_RADIO: p = "radio"; break;
391 case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break;
392 case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break;
393 default: p = "undefined"; break;
395 if (t->mode == V4L2_TUNER_RADIO) {
396 freq = t->radio_freq / 16000;
397 freq_fraction = (t->radio_freq % 16000) * 100 / 16000;
398 } else {
399 freq = t->tv_freq / 16;
400 freq_fraction = (t->tv_freq % 16) * 100 / 16;
402 tuner_info("Tuner mode: %s\n", p);
403 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
404 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
405 if (t->mode != V4L2_TUNER_RADIO)
406 return;
407 if (t->has_signal) {
408 tuner_info("Signal strength: %d\n", t->has_signal(client));
410 if (t->is_stereo) {
411 tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no");
415 /* ---------------------------------------------------------------------- */
417 /* static var Used only in tuner_attach and tuner_probe */
418 static unsigned default_mode_mask;
420 /* During client attach, set_type is called by adapter's attach_inform callback.
421 set_type must then be completed by tuner_attach.
423 static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
425 struct tuner *t;
427 client_template.adapter = adap;
428 client_template.addr = addr;
430 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
431 if (NULL == t)
432 return -ENOMEM;
433 memcpy(&t->i2c, &client_template, sizeof(struct i2c_client));
434 i2c_set_clientdata(&t->i2c, t);
435 t->type = UNSET;
436 t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
437 t->audmode = V4L2_TUNER_MODE_STEREO;
438 t->mode_mask = T_UNINITIALIZED;
439 if (tuner_debug_old) {
440 tuner_debug = tuner_debug_old;
441 printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n");
442 printk(KERN_ERR "tuner: use the debug option instead.\n");
445 if (show_i2c) {
446 unsigned char buffer[16];
447 int i,rc;
449 memset(buffer, 0, sizeof(buffer));
450 rc = i2c_master_recv(&t->i2c, buffer, sizeof(buffer));
451 tuner_info("I2C RECV = ");
452 for (i=0;i<rc;i++)
453 printk("%02x ",buffer[i]);
454 printk("\n");
456 /* autodetection code based on the i2c addr */
457 if (!no_autodetect) {
458 switch (addr) {
459 case 0x42:
460 case 0x43:
461 case 0x4a:
462 case 0x4b:
463 /* If chip is not tda8290, don't register.
464 since it can be tda9887*/
465 if (tda8290_probe(&t->i2c) != 0) {
466 tuner_dbg("chip at addr %x is not a tda8290\n", addr);
467 kfree(t);
468 return 0;
470 break;
471 case 0x60:
472 if (tea5767_autodetection(&t->i2c) != EINVAL) {
473 t->type = TUNER_TEA5767;
474 t->mode_mask = T_RADIO;
475 t->mode = T_STANDBY;
476 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
477 default_mode_mask &= ~T_RADIO;
479 goto register_client;
481 break;
485 /* Initializes only the first adapter found */
486 if (default_mode_mask != T_UNINITIALIZED) {
487 tuner_dbg ("Setting mode_mask to 0x%02x\n", default_mode_mask);
488 t->mode_mask = default_mode_mask;
489 t->tv_freq = 400 * 16; /* Sets freq to VHF High */
490 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
491 default_mode_mask = T_UNINITIALIZED;
494 /* Should be just before return */
495 register_client:
496 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
497 i2c_attach_client (&t->i2c);
498 set_type (&t->i2c,t->type, t->mode_mask);
499 return 0;
502 static int tuner_probe(struct i2c_adapter *adap)
504 if (0 != addr) {
505 normal_i2c[0] = addr;
506 normal_i2c[1] = I2C_CLIENT_END;
509 default_mode_mask = T_RADIO | T_ANALOG_TV | T_DIGITAL_TV;
511 if (adap->class & I2C_CLASS_TV_ANALOG)
512 return i2c_probe(adap, &addr_data, tuner_attach);
513 return 0;
516 static int tuner_detach(struct i2c_client *client)
518 struct tuner *t = i2c_get_clientdata(client);
519 int err;
521 err = i2c_detach_client(&t->i2c);
522 if (err) {
523 tuner_warn
524 ("Client deregistration failed, client not detached.\n");
525 return err;
528 kfree(t);
529 return 0;
533 * Switch tuner to other mode. If tuner support both tv and radio,
534 * set another frequency to some value (This is needed for some pal
535 * tuners to avoid locking). Otherwise, just put second tuner in
536 * standby mode.
539 static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
541 if (mode == t->mode)
542 return 0;
544 t->mode = mode;
546 if (check_mode(t, cmd) == EINVAL) {
547 t->mode = T_STANDBY;
548 if (t->standby)
549 t->standby (client);
550 return EINVAL;
552 return 0;
555 #define switch_v4l2() if (!t->using_v4l2) \
556 tuner_dbg("switching to v4l2\n"); \
557 t->using_v4l2 = 1;
559 static inline int check_v4l2(struct tuner *t)
561 /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
562 TV, v4l1 for radio), until that is fixed this code is disabled.
563 Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
564 first. */
565 return 0;
568 static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
570 struct tuner *t = i2c_get_clientdata(client);
572 if (tuner_debug>1)
573 v4l_i2c_print_ioctl(&(t->i2c),cmd);
575 switch (cmd) {
576 /* --- configuration --- */
577 case TUNER_SET_TYPE_ADDR:
578 tuner_dbg ("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x\n",
579 ((struct tuner_setup *)arg)->type,
580 ((struct tuner_setup *)arg)->addr,
581 ((struct tuner_setup *)arg)->mode_mask);
583 set_addr(client, (struct tuner_setup *)arg);
584 break;
585 case AUDC_SET_RADIO:
586 if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
587 == EINVAL)
588 return 0;
589 if (t->radio_freq)
590 set_freq(client, t->radio_freq);
591 break;
592 case TUNER_SET_STANDBY:
593 if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL)
594 return 0;
595 if (t->standby)
596 t->standby (client);
597 break;
598 case VIDIOCSAUDIO:
599 if (check_mode(t, "VIDIOCSAUDIO") == EINVAL)
600 return 0;
601 if (check_v4l2(t) == EINVAL)
602 return 0;
604 /* Should be implemented, since bttv calls it */
605 tuner_dbg("VIDIOCSAUDIO not implemented.\n");
606 break;
607 /* --- v4l ioctls --- */
608 /* take care: bttv does userspace copying, we'll get a
609 kernel pointer here... */
610 case VIDIOCSCHAN:
612 static const v4l2_std_id map[] = {
613 [VIDEO_MODE_PAL] = V4L2_STD_PAL,
614 [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
615 [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
616 [4 /* bttv */ ] = V4L2_STD_PAL_M,
617 [5 /* bttv */ ] = V4L2_STD_PAL_N,
618 [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
620 struct video_channel *vc = arg;
622 if (check_v4l2(t) == EINVAL)
623 return 0;
625 if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL)
626 return 0;
628 if (vc->norm < ARRAY_SIZE(map))
629 t->std = map[vc->norm];
630 tuner_fixup_std(t);
631 if (t->tv_freq)
632 set_tv_freq(client, t->tv_freq);
633 return 0;
635 case VIDIOCSFREQ:
637 unsigned long *v = arg;
639 if (check_mode(t, "VIDIOCSFREQ") == EINVAL)
640 return 0;
641 if (check_v4l2(t) == EINVAL)
642 return 0;
644 set_freq(client, *v);
645 return 0;
647 case VIDIOCGTUNER:
649 struct video_tuner *vt = arg;
651 if (check_mode(t, "VIDIOCGTUNER") == EINVAL)
652 return 0;
653 if (check_v4l2(t) == EINVAL)
654 return 0;
656 if (V4L2_TUNER_RADIO == t->mode) {
657 if (t->has_signal)
658 vt->signal = t->has_signal(client);
659 if (t->is_stereo) {
660 if (t->is_stereo(client))
661 vt->flags |=
662 VIDEO_TUNER_STEREO_ON;
663 else
664 vt->flags &=
665 ~VIDEO_TUNER_STEREO_ON;
667 vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
669 vt->rangelow = radio_range[0] * 16000;
670 vt->rangehigh = radio_range[1] * 16000;
672 } else {
673 vt->rangelow = tv_range[0] * 16;
674 vt->rangehigh = tv_range[1] * 16;
677 return 0;
679 case VIDIOCGAUDIO:
681 struct video_audio *va = arg;
683 if (check_mode(t, "VIDIOCGAUDIO") == EINVAL)
684 return 0;
685 if (check_v4l2(t) == EINVAL)
686 return 0;
688 if (V4L2_TUNER_RADIO == t->mode && t->is_stereo)
689 va->mode = t->is_stereo(client)
690 ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
691 return 0;
694 case VIDIOC_S_STD:
696 v4l2_std_id *id = arg;
698 if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
699 == EINVAL)
700 return 0;
702 switch_v4l2();
704 t->std = *id;
705 tuner_fixup_std(t);
706 if (t->tv_freq)
707 set_freq(client, t->tv_freq);
708 break;
710 case VIDIOC_S_FREQUENCY:
712 struct v4l2_frequency *f = arg;
714 switch_v4l2();
715 if ((V4L2_TUNER_RADIO == f->type && V4L2_TUNER_RADIO != t->mode)
716 || (V4L2_TUNER_DIGITAL_TV == f->type
717 && V4L2_TUNER_DIGITAL_TV != t->mode)) {
718 if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY")
719 == EINVAL)
720 return 0;
722 set_freq(client,f->frequency);
724 break;
726 case VIDIOC_G_FREQUENCY:
728 struct v4l2_frequency *f = arg;
730 if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL)
731 return 0;
732 switch_v4l2();
733 f->type = t->mode;
734 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
735 t->radio_freq : t->tv_freq;
736 break;
738 case VIDIOC_G_TUNER:
740 struct v4l2_tuner *tuner = arg;
742 if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL)
743 return 0;
744 switch_v4l2();
746 tuner->type = t->mode;
747 if (t->mode == V4L2_TUNER_ANALOG_TV)
748 tuner->capability |= V4L2_TUNER_CAP_NORM;
749 if (t->mode != V4L2_TUNER_RADIO) {
750 tuner->rangelow = tv_range[0] * 16;
751 tuner->rangehigh = tv_range[1] * 16;
752 break;
755 /* radio mode */
756 if (t->has_signal)
757 tuner->signal = t->has_signal(client);
759 tuner->rxsubchans =
760 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
761 if (t->is_stereo) {
762 tuner->rxsubchans = t->is_stereo(client) ?
763 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
766 tuner->capability |=
767 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
768 tuner->audmode = t->audmode;
769 tuner->rangelow = radio_range[0] * 16000;
770 tuner->rangehigh = radio_range[1] * 16000;
771 break;
773 case VIDIOC_S_TUNER:
775 struct v4l2_tuner *tuner = arg;
777 if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL)
778 return 0;
780 switch_v4l2();
782 /* do nothing unless we're a radio tuner */
783 if (t->mode != V4L2_TUNER_RADIO)
784 break;
785 t->audmode = tuner->audmode;
786 set_radio_freq(client, t->radio_freq);
787 break;
789 case VIDIOC_LOG_STATUS:
790 tuner_status(client);
791 break;
794 return 0;
797 static int tuner_suspend(struct device *dev, pm_message_t state)
799 struct i2c_client *c = container_of (dev, struct i2c_client, dev);
800 struct tuner *t = i2c_get_clientdata (c);
802 tuner_dbg ("suspend\n");
803 /* FIXME: power down ??? */
804 return 0;
807 static int tuner_resume(struct device *dev)
809 struct i2c_client *c = container_of (dev, struct i2c_client, dev);
810 struct tuner *t = i2c_get_clientdata (c);
812 tuner_dbg ("resume\n");
813 if (V4L2_TUNER_RADIO == t->mode) {
814 if (t->radio_freq)
815 set_freq(c, t->radio_freq);
816 } else {
817 if (t->tv_freq)
818 set_freq(c, t->tv_freq);
820 return 0;
823 /* ----------------------------------------------------------------------- */
825 static struct i2c_driver driver = {
826 .id = I2C_DRIVERID_TUNER,
827 .attach_adapter = tuner_probe,
828 .detach_client = tuner_detach,
829 .command = tuner_command,
830 .driver = {
831 .name = "tuner",
832 .suspend = tuner_suspend,
833 .resume = tuner_resume,
836 static struct i2c_client client_template = {
837 .name = "(tuner unset)",
838 .driver = &driver,
841 static int __init tuner_init_module(void)
843 return i2c_add_driver(&driver);
846 static void __exit tuner_cleanup_module(void)
848 i2c_del_driver(&driver);
851 module_init(tuner_init_module);
852 module_exit(tuner_cleanup_module);
855 * Overrides for Emacs so that we follow Linus's tabbing style.
856 * ---------------------------------------------------------------------------
857 * Local variables:
858 * c-basic-offset: 8
859 * End: