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