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