diff options
Diffstat (limited to 'drivers/media/common')
23 files changed, 1833 insertions, 1125 deletions
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c index d8229a0e9a9c..3fe158ac7bbf 100644 --- a/drivers/media/common/ir-keymaps.c +++ b/drivers/media/common/ir-keymaps.c | |||
@@ -153,6 +153,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = { | |||
153 | }; | 153 | }; |
154 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); | 154 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a); |
155 | 155 | ||
156 | /* Oldrich Jedlicka <oldium.pro@seznam.cz> */ | ||
157 | IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = { | ||
158 | [0x00] = KEY_POWER, | ||
159 | [0x01] = KEY_TUNER, /* TV/FM */ | ||
160 | [0x03] = KEY_TEXT, /* Teletext */ | ||
161 | [0x04] = KEY_EPG, | ||
162 | [0x05] = KEY_1, | ||
163 | [0x06] = KEY_2, | ||
164 | [0x07] = KEY_3, | ||
165 | [0x08] = KEY_AUDIO, | ||
166 | [0x09] = KEY_4, | ||
167 | [0x0a] = KEY_5, | ||
168 | [0x0b] = KEY_6, | ||
169 | [0x0c] = KEY_ZOOM, /* Full screen */ | ||
170 | [0x0d] = KEY_7, | ||
171 | [0x0e] = KEY_8, | ||
172 | [0x0f] = KEY_9, | ||
173 | [0x10] = KEY_PAGEUP, /* 16-CH PREV */ | ||
174 | [0x11] = KEY_0, | ||
175 | [0x12] = KEY_INFO, | ||
176 | [0x13] = KEY_AGAIN, /* CH RTN - channel return */ | ||
177 | [0x14] = KEY_MUTE, | ||
178 | [0x15] = KEY_EDIT, /* Autoscan */ | ||
179 | [0x17] = KEY_SAVE, /* Screenshot */ | ||
180 | [0x18] = KEY_PLAYPAUSE, | ||
181 | [0x19] = KEY_RECORD, | ||
182 | [0x1a] = KEY_PLAY, | ||
183 | [0x1b] = KEY_STOP, | ||
184 | [0x1c] = KEY_FASTFORWARD, | ||
185 | [0x1d] = KEY_REWIND, | ||
186 | [0x1e] = KEY_VOLUMEDOWN, | ||
187 | [0x1f] = KEY_VOLUMEUP, | ||
188 | [0x22] = KEY_SLEEP, /* Sleep */ | ||
189 | [0x23] = KEY_ZOOM, /* Aspect */ | ||
190 | [0x26] = KEY_SCREEN, /* Pos */ | ||
191 | [0x27] = KEY_ANGLE, /* Size */ | ||
192 | [0x28] = KEY_SELECT, /* Select */ | ||
193 | [0x29] = KEY_BLUE, /* Blue/Picture */ | ||
194 | [0x2a] = KEY_BACKSPACE, /* Back */ | ||
195 | [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */ | ||
196 | [0x2c] = KEY_DOWN, | ||
197 | [0x2e] = KEY_DOT, | ||
198 | [0x2f] = KEY_TV, /* Live TV */ | ||
199 | [0x32] = KEY_LEFT, | ||
200 | [0x33] = KEY_CLEAR, /* Clear */ | ||
201 | [0x35] = KEY_RED, /* Red/TV */ | ||
202 | [0x36] = KEY_UP, | ||
203 | [0x37] = KEY_HOME, /* Home */ | ||
204 | [0x39] = KEY_GREEN, /* Green/Video */ | ||
205 | [0x3d] = KEY_YELLOW, /* Yellow/Music */ | ||
206 | [0x3e] = KEY_OK, /* Ok */ | ||
207 | [0x3f] = KEY_RIGHT, | ||
208 | [0x40] = KEY_NEXT, /* Next */ | ||
209 | [0x41] = KEY_PREVIOUS, /* Previous */ | ||
210 | [0x42] = KEY_CHANNELDOWN, /* Channel down */ | ||
211 | [0x43] = KEY_CHANNELUP /* Channel up */ | ||
212 | }; | ||
213 | EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus); | ||
214 | |||
156 | /* Attila Kondoros <attila.kondoros@chello.hu> */ | 215 | /* Attila Kondoros <attila.kondoros@chello.hu> */ |
157 | IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { | 216 | IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { |
158 | 217 | ||
@@ -2452,6 +2511,55 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = { | |||
2452 | }; | 2511 | }; |
2453 | EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog); | 2512 | EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog); |
2454 | 2513 | ||
2514 | /* Kaiomy TVnPC U2 | ||
2515 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
2516 | */ | ||
2517 | IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = { | ||
2518 | [0x43] = KEY_POWER2, | ||
2519 | [0x01] = KEY_LIST, | ||
2520 | [0x0b] = KEY_ZOOM, | ||
2521 | [0x03] = KEY_POWER, | ||
2522 | |||
2523 | [0x04] = KEY_1, | ||
2524 | [0x08] = KEY_2, | ||
2525 | [0x02] = KEY_3, | ||
2526 | |||
2527 | [0x0f] = KEY_4, | ||
2528 | [0x05] = KEY_5, | ||
2529 | [0x06] = KEY_6, | ||
2530 | |||
2531 | [0x0c] = KEY_7, | ||
2532 | [0x0d] = KEY_8, | ||
2533 | [0x0a] = KEY_9, | ||
2534 | |||
2535 | [0x11] = KEY_0, | ||
2536 | |||
2537 | [0x09] = KEY_CHANNELUP, | ||
2538 | [0x07] = KEY_CHANNELDOWN, | ||
2539 | |||
2540 | [0x0e] = KEY_VOLUMEUP, | ||
2541 | [0x13] = KEY_VOLUMEDOWN, | ||
2542 | |||
2543 | [0x10] = KEY_HOME, | ||
2544 | [0x12] = KEY_ENTER, | ||
2545 | |||
2546 | [0x14] = KEY_RECORD, | ||
2547 | [0x15] = KEY_STOP, | ||
2548 | [0x16] = KEY_PLAY, | ||
2549 | [0x17] = KEY_MUTE, | ||
2550 | |||
2551 | [0x18] = KEY_UP, | ||
2552 | [0x19] = KEY_DOWN, | ||
2553 | [0x1a] = KEY_LEFT, | ||
2554 | [0x1b] = KEY_RIGHT, | ||
2555 | |||
2556 | [0x1c] = KEY_RED, | ||
2557 | [0x1d] = KEY_GREEN, | ||
2558 | [0x1e] = KEY_YELLOW, | ||
2559 | [0x1f] = KEY_BLUE, | ||
2560 | }; | ||
2561 | EXPORT_SYMBOL_GPL(ir_codes_kaiomy); | ||
2562 | |||
2455 | IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { | 2563 | IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = { |
2456 | [0x20] = KEY_LIST, | 2564 | [0x20] = KEY_LIST, |
2457 | [0x00] = KEY_POWER, | 2565 | [0x00] = KEY_POWER, |
@@ -2604,3 +2712,41 @@ IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = { | |||
2604 | }; | 2712 | }; |
2605 | 2713 | ||
2606 | EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600); | 2714 | EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600); |
2715 | |||
2716 | /* DVBWorld remotes | ||
2717 | Igor M. Liplianin <liplianin@me.by> | ||
2718 | */ | ||
2719 | IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = { | ||
2720 | [0x0a] = KEY_Q, /*power*/ | ||
2721 | [0x0c] = KEY_M, /*mute*/ | ||
2722 | [0x11] = KEY_1, | ||
2723 | [0x12] = KEY_2, | ||
2724 | [0x13] = KEY_3, | ||
2725 | [0x14] = KEY_4, | ||
2726 | [0x15] = KEY_5, | ||
2727 | [0x16] = KEY_6, | ||
2728 | [0x17] = KEY_7, | ||
2729 | [0x18] = KEY_8, | ||
2730 | [0x19] = KEY_9, | ||
2731 | [0x10] = KEY_0, | ||
2732 | [0x1c] = KEY_PAGEUP, /*ch+*/ | ||
2733 | [0x0f] = KEY_PAGEDOWN, /*ch-*/ | ||
2734 | [0x1a] = KEY_O, /*vol+*/ | ||
2735 | [0x0e] = KEY_Z, /*vol-*/ | ||
2736 | [0x04] = KEY_R, /*rec*/ | ||
2737 | [0x09] = KEY_D, /*fav*/ | ||
2738 | [0x08] = KEY_BACKSPACE, /*rewind*/ | ||
2739 | [0x07] = KEY_A, /*fast*/ | ||
2740 | [0x0b] = KEY_P, /*pause*/ | ||
2741 | [0x02] = KEY_ESC, /*cancel*/ | ||
2742 | [0x03] = KEY_G, /*tab*/ | ||
2743 | [0x00] = KEY_UP, /*up*/ | ||
2744 | [0x1f] = KEY_ENTER, /*ok*/ | ||
2745 | [0x01] = KEY_DOWN, /*down*/ | ||
2746 | [0x05] = KEY_C, /*cap*/ | ||
2747 | [0x06] = KEY_S, /*stop*/ | ||
2748 | [0x40] = KEY_F, /*full*/ | ||
2749 | [0x1e] = KEY_W, /*tvmode*/ | ||
2750 | [0x1b] = KEY_B, /*recall*/ | ||
2751 | }; | ||
2752 | EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec); | ||
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index d599d360da3f..982f000a57ff 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c | |||
@@ -452,8 +452,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent | |||
452 | INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device)); | 452 | INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device)); |
453 | dev->ext = ext; | 453 | dev->ext = ext; |
454 | 454 | ||
455 | pci_set_drvdata(pci, dev); | ||
456 | |||
457 | mutex_init(&dev->lock); | 455 | mutex_init(&dev->lock); |
458 | spin_lock_init(&dev->int_slock); | 456 | spin_lock_init(&dev->int_slock); |
459 | spin_lock_init(&dev->slock); | 457 | spin_lock_init(&dev->slock); |
@@ -477,8 +475,12 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent | |||
477 | 475 | ||
478 | if (ext->attach(dev, pci_ext)) { | 476 | if (ext->attach(dev, pci_ext)) { |
479 | DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); | 477 | DEB_D(("ext->attach() failed for %p. skipping device.\n",dev)); |
480 | goto err_unprobe; | 478 | goto err_free_i2c; |
481 | } | 479 | } |
480 | /* V4L extensions will set the pci drvdata to the v4l2_device in the | ||
481 | attach() above. So for those cards that do not use V4L we have to | ||
482 | set it explicitly. */ | ||
483 | pci_set_drvdata(pci, &dev->v4l2_dev); | ||
482 | 484 | ||
483 | INIT_LIST_HEAD(&dev->item); | 485 | INIT_LIST_HEAD(&dev->item); |
484 | list_add_tail(&dev->item,&saa7146_devices); | 486 | list_add_tail(&dev->item,&saa7146_devices); |
@@ -488,8 +490,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent | |||
488 | out: | 490 | out: |
489 | return err; | 491 | return err; |
490 | 492 | ||
491 | err_unprobe: | ||
492 | pci_set_drvdata(pci, NULL); | ||
493 | err_free_i2c: | 493 | err_free_i2c: |
494 | pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, | 494 | pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr, |
495 | dev->d_i2c.dma_handle); | 495 | dev->d_i2c.dma_handle); |
@@ -514,7 +514,8 @@ err_free: | |||
514 | 514 | ||
515 | static void saa7146_remove_one(struct pci_dev *pdev) | 515 | static void saa7146_remove_one(struct pci_dev *pdev) |
516 | { | 516 | { |
517 | struct saa7146_dev* dev = pci_get_drvdata(pdev); | 517 | struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev); |
518 | struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); | ||
518 | struct { | 519 | struct { |
519 | void *addr; | 520 | void *addr; |
520 | dma_addr_t dma; | 521 | dma_addr_t dma; |
@@ -528,6 +529,8 @@ static void saa7146_remove_one(struct pci_dev *pdev) | |||
528 | DEB_EE(("dev:%p\n",dev)); | 529 | DEB_EE(("dev:%p\n",dev)); |
529 | 530 | ||
530 | dev->ext->detach(dev); | 531 | dev->ext->detach(dev); |
532 | /* Zero the PCI drvdata after use. */ | ||
533 | pci_set_drvdata(pdev, NULL); | ||
531 | 534 | ||
532 | /* shut down all video dma transfers */ | 535 | /* shut down all video dma transfers */ |
533 | saa7146_write(dev, MC1, 0x00ff0000); | 536 | saa7146_write(dev, MC1, 0x00ff0000); |
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index cf06f4d10ad4..620f655fa9c5 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c | |||
@@ -308,14 +308,6 @@ static int fops_release(struct file *file) | |||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
312 | { | ||
313 | /* | ||
314 | DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg)); | ||
315 | */ | ||
316 | return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl); | ||
317 | } | ||
318 | |||
319 | static int fops_mmap(struct file *file, struct vm_area_struct * vma) | 311 | static int fops_mmap(struct file *file, struct vm_area_struct * vma) |
320 | { | 312 | { |
321 | struct saa7146_fh *fh = file->private_data; | 313 | struct saa7146_fh *fh = file->private_data; |
@@ -425,7 +417,7 @@ static const struct v4l2_file_operations video_fops = | |||
425 | .write = fops_write, | 417 | .write = fops_write, |
426 | .poll = fops_poll, | 418 | .poll = fops_poll, |
427 | .mmap = fops_mmap, | 419 | .mmap = fops_mmap, |
428 | .ioctl = fops_ioctl, | 420 | .ioctl = video_ioctl2, |
429 | }; | 421 | }; |
430 | 422 | ||
431 | static void vv_callback(struct saa7146_dev *dev, unsigned long status) | 423 | static void vv_callback(struct saa7146_dev *dev, unsigned long status) |
@@ -452,19 +444,22 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status) | |||
452 | } | 444 | } |
453 | } | 445 | } |
454 | 446 | ||
455 | static struct video_device device_template = | ||
456 | { | ||
457 | .fops = &video_fops, | ||
458 | .minor = -1, | ||
459 | }; | ||
460 | |||
461 | int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) | 447 | int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) |
462 | { | 448 | { |
463 | struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL); | 449 | struct saa7146_vv *vv; |
464 | if( NULL == vv ) { | 450 | int err; |
451 | |||
452 | err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev); | ||
453 | if (err) | ||
454 | return err; | ||
455 | |||
456 | vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); | ||
457 | if (vv == NULL) { | ||
465 | ERR(("out of memory. aborting.\n")); | 458 | ERR(("out of memory. aborting.\n")); |
466 | return -1; | 459 | return -ENOMEM; |
467 | } | 460 | } |
461 | ext_vv->ops = saa7146_video_ioctl_ops; | ||
462 | ext_vv->core_ops = &saa7146_video_ioctl_ops; | ||
468 | 463 | ||
469 | DEB_EE(("dev:%p\n",dev)); | 464 | DEB_EE(("dev:%p\n",dev)); |
470 | 465 | ||
@@ -507,6 +502,7 @@ int saa7146_vv_release(struct saa7146_dev* dev) | |||
507 | 502 | ||
508 | DEB_EE(("dev:%p\n",dev)); | 503 | DEB_EE(("dev:%p\n",dev)); |
509 | 504 | ||
505 | v4l2_device_unregister(&dev->v4l2_dev); | ||
510 | pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); | 506 | pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); |
511 | kfree(vv); | 507 | kfree(vv); |
512 | dev->vv_data = NULL; | 508 | dev->vv_data = NULL; |
@@ -521,6 +517,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
521 | { | 517 | { |
522 | struct saa7146_vv *vv = dev->vv_data; | 518 | struct saa7146_vv *vv = dev->vv_data; |
523 | struct video_device *vfd; | 519 | struct video_device *vfd; |
520 | int err; | ||
521 | int i; | ||
524 | 522 | ||
525 | DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); | 523 | DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type)); |
526 | 524 | ||
@@ -529,16 +527,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev, | |||
529 | if (vfd == NULL) | 527 | if (vfd == NULL) |
530 | return -ENOMEM; | 528 | return -ENOMEM; |
531 | 529 | ||
532 | memcpy(vfd, &device_template, sizeof(struct video_device)); | 530 | vfd->fops = &video_fops; |
533 | strlcpy(vfd->name, name, sizeof(vfd->name)); | 531 | vfd->ioctl_ops = &dev->ext_vv_data->ops; |
534 | vfd->release = video_device_release; | 532 | vfd->release = video_device_release; |
533 | vfd->tvnorms = 0; | ||
534 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) | ||
535 | vfd->tvnorms |= dev->ext_vv_data->stds[i].id; | ||
536 | strlcpy(vfd->name, name, sizeof(vfd->name)); | ||
535 | video_set_drvdata(vfd, dev); | 537 | video_set_drvdata(vfd, dev); |
536 | 538 | ||
537 | // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr"); | 539 | err = video_register_device(vfd, type, -1); |
538 | if (video_register_device(vfd, type, -1) < 0) { | 540 | if (err < 0) { |
539 | ERR(("cannot register v4l2 device. skipping.\n")); | 541 | ERR(("cannot register v4l2 device. skipping.\n")); |
540 | video_device_release(vfd); | 542 | video_device_release(vfd); |
541 | return -1; | 543 | return err; |
542 | } | 544 | } |
543 | 545 | ||
544 | if( VFL_TYPE_GRABBER == type ) { | 546 | if( VFL_TYPE_GRABBER == type ) { |
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c index c11da4d09cd0..7e8f56815998 100644 --- a/drivers/media/common/saa7146_i2c.c +++ b/drivers/media/common/saa7146_i2c.c | |||
@@ -293,7 +293,6 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m | |||
293 | int i = 0, count = 0; | 293 | int i = 0, count = 0; |
294 | __le32 *buffer = dev->d_i2c.cpu_addr; | 294 | __le32 *buffer = dev->d_i2c.cpu_addr; |
295 | int err = 0; | 295 | int err = 0; |
296 | int address_err = 0; | ||
297 | int short_delay = 0; | 296 | int short_delay = 0; |
298 | 297 | ||
299 | if (mutex_lock_interruptible(&dev->i2c_lock)) | 298 | if (mutex_lock_interruptible(&dev->i2c_lock)) |
@@ -333,17 +332,10 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m | |||
333 | i2c address probing, however, and address errors indicate that a | 332 | i2c address probing, however, and address errors indicate that a |
334 | device is really *not* there. retrying in that case | 333 | device is really *not* there. retrying in that case |
335 | increases the time the device needs to probe greatly, so | 334 | increases the time the device needs to probe greatly, so |
336 | it should be avoided. because of the fact, that only | 335 | it should be avoided. So we bail out in irq mode after an |
337 | analog based cards use irq based i2c transactions (for dvb | 336 | address error and trust the saa7146 address error detection. */ |
338 | cards, this screwes up other interrupt sources), we bail out | 337 | if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) |
339 | completely for analog cards after an address error and trust | 338 | goto out; |
340 | the saa7146 address error detection. */ | ||
341 | if ( -EREMOTEIO == err ) { | ||
342 | if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) { | ||
343 | goto out; | ||
344 | } | ||
345 | address_err++; | ||
346 | } | ||
347 | DEB_I2C(("error while sending message(s). starting again.\n")); | 339 | DEB_I2C(("error while sending message(s). starting again.\n")); |
348 | break; | 340 | break; |
349 | } | 341 | } |
@@ -358,10 +350,9 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m | |||
358 | 350 | ||
359 | } while (err != num && retries--); | 351 | } while (err != num && retries--); |
360 | 352 | ||
361 | /* if every retry had an address error, exit right away */ | 353 | /* quit if any error occurred */ |
362 | if (address_err == retries) { | 354 | if (err != num) |
363 | goto out; | 355 | goto out; |
364 | } | ||
365 | 356 | ||
366 | /* if any things had to be read, get the results */ | 357 | /* if any things had to be read, get the results */ |
367 | if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) { | 358 | if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) { |
@@ -390,7 +381,8 @@ out: | |||
390 | /* utility functions */ | 381 | /* utility functions */ |
391 | static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) | 382 | static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num) |
392 | { | 383 | { |
393 | struct saa7146_dev* dev = i2c_get_adapdata(adapter); | 384 | struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter); |
385 | struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev); | ||
394 | 386 | ||
395 | /* use helper function to transfer data */ | 387 | /* use helper function to transfer data */ |
396 | return saa7146_i2c_transfer(dev, msg, num, adapter->retries); | 388 | return saa7146_i2c_transfer(dev, msg, num, adapter->retries); |
@@ -417,9 +409,8 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c | |||
417 | dev->i2c_bitrate = bitrate; | 409 | dev->i2c_bitrate = bitrate; |
418 | saa7146_i2c_reset(dev); | 410 | saa7146_i2c_reset(dev); |
419 | 411 | ||
420 | if( NULL != i2c_adapter ) { | 412 | if (i2c_adapter) { |
421 | BUG_ON(!i2c_adapter->class); | 413 | i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev); |
422 | i2c_set_adapdata(i2c_adapter,dev); | ||
423 | i2c_adapter->dev.parent = &dev->pci->dev; | 414 | i2c_adapter->dev.parent = &dev->pci->dev; |
424 | i2c_adapter->algo = &saa7146_algo; | 415 | i2c_adapter->algo = &saa7146_algo; |
425 | i2c_adapter->algo_data = NULL; | 416 | i2c_adapter->algo_data = NULL; |
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 47fee05eaefb..552dab442d78 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <media/saa7146_vv.h> | 1 | #include <media/saa7146_vv.h> |
2 | #include <media/v4l2-chip-ident.h> | ||
2 | 3 | ||
3 | static int max_memory = 32; | 4 | static int max_memory = 32; |
4 | 5 | ||
@@ -97,172 +98,13 @@ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) | |||
97 | return NULL; | 98 | return NULL; |
98 | } | 99 | } |
99 | 100 | ||
100 | static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | 101 | static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f); |
101 | { | ||
102 | struct saa7146_dev *dev = fh->dev; | ||
103 | DEB_EE(("dev:%p, fh:%p\n",dev,fh)); | ||
104 | |||
105 | switch (f->type) { | ||
106 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
107 | f->fmt.pix = fh->video_fmt; | ||
108 | return 0; | ||
109 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
110 | f->fmt.win = fh->ov.win; | ||
111 | return 0; | ||
112 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
113 | { | ||
114 | f->fmt.vbi = fh->vbi_fmt; | ||
115 | return 0; | ||
116 | } | ||
117 | default: | ||
118 | DEB_D(("invalid format type '%d'.\n",f->type)); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | static int try_win(struct saa7146_dev *dev, struct v4l2_window *win) | ||
124 | { | ||
125 | struct saa7146_vv *vv = dev->vv_data; | ||
126 | enum v4l2_field field; | ||
127 | int maxw, maxh; | ||
128 | |||
129 | DEB_EE(("dev:%p\n",dev)); | ||
130 | |||
131 | if (NULL == vv->ov_fb.base) { | ||
132 | DEB_D(("no fb base set.\n")); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | if (NULL == vv->ov_fmt) { | ||
136 | DEB_D(("no fb fmt set.\n")); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | if (win->w.width < 48 || win->w.height < 32) { | ||
140 | DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height)); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | if (win->clipcount > 16) { | ||
144 | DEB_D(("clipcount too big.\n")); | ||
145 | return -EINVAL; | ||
146 | } | ||
147 | |||
148 | field = win->field; | ||
149 | maxw = vv->standard->h_max_out; | ||
150 | maxh = vv->standard->v_max_out; | ||
151 | |||
152 | if (V4L2_FIELD_ANY == field) { | ||
153 | field = (win->w.height > maxh/2) | ||
154 | ? V4L2_FIELD_INTERLACED | ||
155 | : V4L2_FIELD_TOP; | ||
156 | } | ||
157 | switch (field) { | ||
158 | case V4L2_FIELD_TOP: | ||
159 | case V4L2_FIELD_BOTTOM: | ||
160 | case V4L2_FIELD_ALTERNATE: | ||
161 | maxh = maxh / 2; | ||
162 | break; | ||
163 | case V4L2_FIELD_INTERLACED: | ||
164 | break; | ||
165 | default: { | ||
166 | DEB_D(("no known field mode '%d'.\n",field)); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | win->field = field; | ||
172 | if (win->w.width > maxw) | ||
173 | win->w.width = maxw; | ||
174 | if (win->w.height > maxh) | ||
175 | win->w.height = maxh; | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | ||
181 | { | ||
182 | struct saa7146_dev *dev = fh->dev; | ||
183 | struct saa7146_vv *vv = dev->vv_data; | ||
184 | int err; | ||
185 | |||
186 | switch (f->type) { | ||
187 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
188 | { | ||
189 | struct saa7146_format *fmt; | ||
190 | enum v4l2_field field; | ||
191 | int maxw, maxh; | ||
192 | int calc_bpl; | ||
193 | |||
194 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh)); | ||
195 | |||
196 | fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat); | ||
197 | if (NULL == fmt) { | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | field = f->fmt.pix.field; | ||
202 | maxw = vv->standard->h_max_out; | ||
203 | maxh = vv->standard->v_max_out; | ||
204 | |||
205 | if (V4L2_FIELD_ANY == field) { | ||
206 | field = (f->fmt.pix.height > maxh/2) | ||
207 | ? V4L2_FIELD_INTERLACED | ||
208 | : V4L2_FIELD_BOTTOM; | ||
209 | } | ||
210 | switch (field) { | ||
211 | case V4L2_FIELD_ALTERNATE: { | ||
212 | vv->last_field = V4L2_FIELD_TOP; | ||
213 | maxh = maxh / 2; | ||
214 | break; | ||
215 | } | ||
216 | case V4L2_FIELD_TOP: | ||
217 | case V4L2_FIELD_BOTTOM: | ||
218 | vv->last_field = V4L2_FIELD_INTERLACED; | ||
219 | maxh = maxh / 2; | ||
220 | break; | ||
221 | case V4L2_FIELD_INTERLACED: | ||
222 | vv->last_field = V4L2_FIELD_INTERLACED; | ||
223 | break; | ||
224 | default: { | ||
225 | DEB_D(("no known field mode '%d'.\n",field)); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | } | ||
229 | |||
230 | f->fmt.pix.field = field; | ||
231 | if (f->fmt.pix.width > maxw) | ||
232 | f->fmt.pix.width = maxw; | ||
233 | if (f->fmt.pix.height > maxh) | ||
234 | f->fmt.pix.height = maxh; | ||
235 | |||
236 | calc_bpl = (f->fmt.pix.width * fmt->depth)/8; | ||
237 | |||
238 | if (f->fmt.pix.bytesperline < calc_bpl) | ||
239 | f->fmt.pix.bytesperline = calc_bpl; | ||
240 | |||
241 | if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */ | ||
242 | f->fmt.pix.bytesperline = calc_bpl; | ||
243 | |||
244 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; | ||
245 | DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage)); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
250 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh)); | ||
251 | err = try_win(dev,&f->fmt.win); | ||
252 | if (0 != err) { | ||
253 | return err; | ||
254 | } | ||
255 | return 0; | ||
256 | default: | ||
257 | DEB_EE(("unknown format type '%d'\n",f->type)); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | } | ||
261 | 102 | ||
262 | int saa7146_start_preview(struct saa7146_fh *fh) | 103 | int saa7146_start_preview(struct saa7146_fh *fh) |
263 | { | 104 | { |
264 | struct saa7146_dev *dev = fh->dev; | 105 | struct saa7146_dev *dev = fh->dev; |
265 | struct saa7146_vv *vv = dev->vv_data; | 106 | struct saa7146_vv *vv = dev->vv_data; |
107 | struct v4l2_format fmt; | ||
266 | int ret = 0, err = 0; | 108 | int ret = 0, err = 0; |
267 | 109 | ||
268 | DEB_EE(("dev:%p, fh:%p\n",dev,fh)); | 110 | DEB_EE(("dev:%p, fh:%p\n",dev,fh)); |
@@ -294,12 +136,13 @@ int saa7146_start_preview(struct saa7146_fh *fh) | |||
294 | return -EBUSY; | 136 | return -EBUSY; |
295 | } | 137 | } |
296 | 138 | ||
297 | err = try_win(dev,&fh->ov.win); | 139 | fmt.fmt.win = fh->ov.win; |
140 | err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); | ||
298 | if (0 != err) { | 141 | if (0 != err) { |
299 | saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); | 142 | saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); |
300 | return -EBUSY; | 143 | return -EBUSY; |
301 | } | 144 | } |
302 | 145 | fh->ov.win = fmt.fmt.win; | |
303 | vv->ov_data = &fh->ov; | 146 | vv->ov_data = &fh->ov; |
304 | 147 | ||
305 | DEB_D(("%dx%d+%d+%d %s field=%s\n", | 148 | DEB_D(("%dx%d+%d+%d %s field=%s\n", |
@@ -355,58 +198,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh) | |||
355 | } | 198 | } |
356 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); | 199 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); |
357 | 200 | ||
358 | static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f) | ||
359 | { | ||
360 | struct saa7146_dev *dev = fh->dev; | ||
361 | struct saa7146_vv *vv = dev->vv_data; | ||
362 | |||
363 | int err; | ||
364 | |||
365 | switch (f->type) { | ||
366 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
367 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh)); | ||
368 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
369 | DEB_EE(("streaming capture is active\n")); | ||
370 | return -EBUSY; | ||
371 | } | ||
372 | err = try_fmt(fh,f); | ||
373 | if (0 != err) | ||
374 | return err; | ||
375 | fh->video_fmt = f->fmt.pix; | ||
376 | DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat)); | ||
377 | return 0; | ||
378 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | ||
379 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh)); | ||
380 | err = try_win(dev,&f->fmt.win); | ||
381 | if (0 != err) | ||
382 | return err; | ||
383 | mutex_lock(&dev->lock); | ||
384 | fh->ov.win = f->fmt.win; | ||
385 | fh->ov.nclips = f->fmt.win.clipcount; | ||
386 | if (fh->ov.nclips > 16) | ||
387 | fh->ov.nclips = 16; | ||
388 | if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) { | ||
389 | mutex_unlock(&dev->lock); | ||
390 | return -EFAULT; | ||
391 | } | ||
392 | |||
393 | /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ | ||
394 | fh->ov.fh = fh; | ||
395 | |||
396 | mutex_unlock(&dev->lock); | ||
397 | |||
398 | /* check if our current overlay is active */ | ||
399 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
400 | saa7146_stop_preview(fh); | ||
401 | saa7146_start_preview(fh); | ||
402 | } | ||
403 | return 0; | ||
404 | default: | ||
405 | DEB_D(("unknown format type '%d'\n",f->type)); | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | /********************************************************************************/ | 201 | /********************************************************************************/ |
411 | /* device controls */ | 202 | /* device controls */ |
412 | 203 | ||
@@ -419,6 +210,7 @@ static struct v4l2_queryctrl controls[] = { | |||
419 | .step = 1, | 210 | .step = 1, |
420 | .default_value = 128, | 211 | .default_value = 128, |
421 | .type = V4L2_CTRL_TYPE_INTEGER, | 212 | .type = V4L2_CTRL_TYPE_INTEGER, |
213 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
422 | },{ | 214 | },{ |
423 | .id = V4L2_CID_CONTRAST, | 215 | .id = V4L2_CID_CONTRAST, |
424 | .name = "Contrast", | 216 | .name = "Contrast", |
@@ -427,6 +219,7 @@ static struct v4l2_queryctrl controls[] = { | |||
427 | .step = 1, | 219 | .step = 1, |
428 | .default_value = 64, | 220 | .default_value = 64, |
429 | .type = V4L2_CTRL_TYPE_INTEGER, | 221 | .type = V4L2_CTRL_TYPE_INTEGER, |
222 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
430 | },{ | 223 | },{ |
431 | .id = V4L2_CID_SATURATION, | 224 | .id = V4L2_CID_SATURATION, |
432 | .name = "Saturation", | 225 | .name = "Saturation", |
@@ -435,15 +228,16 @@ static struct v4l2_queryctrl controls[] = { | |||
435 | .step = 1, | 228 | .step = 1, |
436 | .default_value = 64, | 229 | .default_value = 64, |
437 | .type = V4L2_CTRL_TYPE_INTEGER, | 230 | .type = V4L2_CTRL_TYPE_INTEGER, |
231 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
438 | },{ | 232 | },{ |
439 | .id = V4L2_CID_VFLIP, | 233 | .id = V4L2_CID_VFLIP, |
440 | .name = "Vertical flip", | 234 | .name = "Vertical Flip", |
441 | .minimum = 0, | 235 | .minimum = 0, |
442 | .maximum = 1, | 236 | .maximum = 1, |
443 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 237 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
444 | },{ | 238 | },{ |
445 | .id = V4L2_CID_HFLIP, | 239 | .id = V4L2_CID_HFLIP, |
446 | .name = "Horizontal flip", | 240 | .name = "Horizontal Flip", |
447 | .minimum = 0, | 241 | .minimum = 0, |
448 | .maximum = 1, | 242 | .maximum = 1, |
449 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 243 | .type = V4L2_CTRL_TYPE_BOOLEAN, |
@@ -463,132 +257,6 @@ static struct v4l2_queryctrl* ctrl_by_id(int id) | |||
463 | return NULL; | 257 | return NULL; |
464 | } | 258 | } |
465 | 259 | ||
466 | static int get_control(struct saa7146_fh *fh, struct v4l2_control *c) | ||
467 | { | ||
468 | struct saa7146_dev *dev = fh->dev; | ||
469 | struct saa7146_vv *vv = dev->vv_data; | ||
470 | |||
471 | const struct v4l2_queryctrl* ctrl; | ||
472 | u32 value = 0; | ||
473 | |||
474 | ctrl = ctrl_by_id(c->id); | ||
475 | if (NULL == ctrl) | ||
476 | return -EINVAL; | ||
477 | switch (c->id) { | ||
478 | case V4L2_CID_BRIGHTNESS: | ||
479 | value = saa7146_read(dev, BCS_CTRL); | ||
480 | c->value = 0xff & (value >> 24); | ||
481 | DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value)); | ||
482 | break; | ||
483 | case V4L2_CID_CONTRAST: | ||
484 | value = saa7146_read(dev, BCS_CTRL); | ||
485 | c->value = 0x7f & (value >> 16); | ||
486 | DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value)); | ||
487 | break; | ||
488 | case V4L2_CID_SATURATION: | ||
489 | value = saa7146_read(dev, BCS_CTRL); | ||
490 | c->value = 0x7f & (value >> 0); | ||
491 | DEB_D(("V4L2_CID_SATURATION: %d\n",c->value)); | ||
492 | break; | ||
493 | case V4L2_CID_VFLIP: | ||
494 | c->value = vv->vflip; | ||
495 | DEB_D(("V4L2_CID_VFLIP: %d\n",c->value)); | ||
496 | break; | ||
497 | case V4L2_CID_HFLIP: | ||
498 | c->value = vv->hflip; | ||
499 | DEB_D(("V4L2_CID_HFLIP: %d\n",c->value)); | ||
500 | break; | ||
501 | default: | ||
502 | return -EINVAL; | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | static int set_control(struct saa7146_fh *fh, struct v4l2_control *c) | ||
509 | { | ||
510 | struct saa7146_dev *dev = fh->dev; | ||
511 | struct saa7146_vv *vv = dev->vv_data; | ||
512 | |||
513 | const struct v4l2_queryctrl* ctrl; | ||
514 | |||
515 | ctrl = ctrl_by_id(c->id); | ||
516 | if (NULL == ctrl) { | ||
517 | DEB_D(("unknown control %d\n",c->id)); | ||
518 | return -EINVAL; | ||
519 | } | ||
520 | |||
521 | mutex_lock(&dev->lock); | ||
522 | |||
523 | switch (ctrl->type) { | ||
524 | case V4L2_CTRL_TYPE_BOOLEAN: | ||
525 | case V4L2_CTRL_TYPE_MENU: | ||
526 | case V4L2_CTRL_TYPE_INTEGER: | ||
527 | if (c->value < ctrl->minimum) | ||
528 | c->value = ctrl->minimum; | ||
529 | if (c->value > ctrl->maximum) | ||
530 | c->value = ctrl->maximum; | ||
531 | break; | ||
532 | default: | ||
533 | /* nothing */; | ||
534 | }; | ||
535 | |||
536 | switch (c->id) { | ||
537 | case V4L2_CID_BRIGHTNESS: { | ||
538 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
539 | value &= 0x00ffffff; | ||
540 | value |= (c->value << 24); | ||
541 | saa7146_write(dev, BCS_CTRL, value); | ||
542 | saa7146_write(dev, MC2, MASK_22 | MASK_06 ); | ||
543 | break; | ||
544 | } | ||
545 | case V4L2_CID_CONTRAST: { | ||
546 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
547 | value &= 0xff00ffff; | ||
548 | value |= (c->value << 16); | ||
549 | saa7146_write(dev, BCS_CTRL, value); | ||
550 | saa7146_write(dev, MC2, MASK_22 | MASK_06 ); | ||
551 | break; | ||
552 | } | ||
553 | case V4L2_CID_SATURATION: { | ||
554 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
555 | value &= 0xffffff00; | ||
556 | value |= (c->value << 0); | ||
557 | saa7146_write(dev, BCS_CTRL, value); | ||
558 | saa7146_write(dev, MC2, MASK_22 | MASK_06 ); | ||
559 | break; | ||
560 | } | ||
561 | case V4L2_CID_HFLIP: | ||
562 | /* fixme: we can support changing VFLIP and HFLIP here... */ | ||
563 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
564 | DEB_D(("V4L2_CID_HFLIP while active capture.\n")); | ||
565 | mutex_unlock(&dev->lock); | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | vv->hflip = c->value; | ||
569 | break; | ||
570 | case V4L2_CID_VFLIP: | ||
571 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
572 | DEB_D(("V4L2_CID_VFLIP while active capture.\n")); | ||
573 | mutex_unlock(&dev->lock); | ||
574 | return -EINVAL; | ||
575 | } | ||
576 | vv->vflip = c->value; | ||
577 | break; | ||
578 | default: { | ||
579 | mutex_unlock(&dev->lock); | ||
580 | return -EINVAL; | ||
581 | } | ||
582 | } | ||
583 | mutex_unlock(&dev->lock); | ||
584 | |||
585 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
586 | saa7146_stop_preview(fh); | ||
587 | saa7146_start_preview(fh); | ||
588 | } | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | /********************************************************************************/ | 260 | /********************************************************************************/ |
593 | /* common pagetable functions */ | 261 | /* common pagetable functions */ |
594 | 262 | ||
@@ -829,231 +497,446 @@ static int video_end(struct saa7146_fh *fh, struct file *file) | |||
829 | return 0; | 497 | return 0; |
830 | } | 498 | } |
831 | 499 | ||
832 | /* | 500 | static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) |
833 | * This function is _not_ called directly, but from | 501 | { |
834 | * video_generic_ioctl (and maybe others). userspace | 502 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
835 | * copying is done already, arg is a kernel pointer. | 503 | |
836 | */ | 504 | strcpy((char *)cap->driver, "saa7146 v4l2"); |
505 | strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); | ||
506 | sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); | ||
507 | cap->version = SAA7146_VERSION_CODE; | ||
508 | cap->capabilities = | ||
509 | V4L2_CAP_VIDEO_CAPTURE | | ||
510 | V4L2_CAP_VIDEO_OVERLAY | | ||
511 | V4L2_CAP_READWRITE | | ||
512 | V4L2_CAP_STREAMING; | ||
513 | cap->capabilities |= dev->ext_vv_data->capabilities; | ||
514 | return 0; | ||
515 | } | ||
837 | 516 | ||
838 | long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | 517 | static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) |
839 | { | 518 | { |
840 | struct saa7146_fh *fh = file->private_data; | 519 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
841 | struct saa7146_dev *dev = fh->dev; | 520 | struct saa7146_vv *vv = dev->vv_data; |
521 | |||
522 | *fb = vv->ov_fb; | ||
523 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | ||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) | ||
528 | { | ||
529 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
842 | struct saa7146_vv *vv = dev->vv_data; | 530 | struct saa7146_vv *vv = dev->vv_data; |
531 | struct saa7146_format *fmt; | ||
843 | 532 | ||
844 | long err = 0; | 533 | DEB_EE(("VIDIOC_S_FBUF\n")); |
845 | int result = 0, ee = 0; | ||
846 | 534 | ||
847 | struct saa7146_use_ops *ops; | 535 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) |
848 | struct videobuf_queue *q; | 536 | return -EPERM; |
849 | 537 | ||
850 | /* check if extension handles the command */ | 538 | /* check args */ |
851 | for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) { | 539 | fmt = format_by_fourcc(dev, fb->fmt.pixelformat); |
852 | if( cmd == dev->ext_vv_data->ioctls[ee].cmd ) | 540 | if (NULL == fmt) |
853 | break; | 541 | return -EINVAL; |
542 | |||
543 | /* planar formats are not allowed for overlay video, clipping and video dma would clash */ | ||
544 | if (fmt->flags & FORMAT_IS_PLANAR) | ||
545 | DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n", | ||
546 | (char *)&fmt->pixelformat)); | ||
547 | |||
548 | /* check if overlay is running */ | ||
549 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
550 | if (vv->video_fh != fh) { | ||
551 | DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); | ||
552 | return -EBUSY; | ||
553 | } | ||
854 | } | 554 | } |
855 | 555 | ||
856 | if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) { | 556 | mutex_lock(&dev->lock); |
857 | DEB_D(("extension handles ioctl exclusive.\n")); | 557 | |
858 | result = dev->ext_vv_data->ioctl(fh, cmd, arg); | 558 | /* ok, accept it */ |
859 | return result; | 559 | vv->ov_fb = *fb; |
560 | vv->ov_fmt = fmt; | ||
561 | if (0 == vv->ov_fb.fmt.bytesperline) | ||
562 | vv->ov_fb.fmt.bytesperline = | ||
563 | vv->ov_fb.fmt.width * fmt->depth / 8; | ||
564 | |||
565 | mutex_unlock(&dev->lock); | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) | ||
570 | { | ||
571 | if (f->index >= NUM_FORMATS) | ||
572 | return -EINVAL; | ||
573 | strlcpy((char *)f->description, formats[f->index].name, | ||
574 | sizeof(f->description)); | ||
575 | f->pixelformat = formats[f->index].pixelformat; | ||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) | ||
580 | { | ||
581 | const struct v4l2_queryctrl *ctrl; | ||
582 | |||
583 | if ((c->id < V4L2_CID_BASE || | ||
584 | c->id >= V4L2_CID_LASTP1) && | ||
585 | (c->id < V4L2_CID_PRIVATE_BASE || | ||
586 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | ||
587 | return -EINVAL; | ||
588 | |||
589 | ctrl = ctrl_by_id(c->id); | ||
590 | if (ctrl == NULL) | ||
591 | return -EINVAL; | ||
592 | |||
593 | DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id)); | ||
594 | *c = *ctrl; | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) | ||
599 | { | ||
600 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
601 | struct saa7146_vv *vv = dev->vv_data; | ||
602 | const struct v4l2_queryctrl *ctrl; | ||
603 | u32 value = 0; | ||
604 | |||
605 | ctrl = ctrl_by_id(c->id); | ||
606 | if (NULL == ctrl) | ||
607 | return -EINVAL; | ||
608 | switch (c->id) { | ||
609 | case V4L2_CID_BRIGHTNESS: | ||
610 | value = saa7146_read(dev, BCS_CTRL); | ||
611 | c->value = 0xff & (value >> 24); | ||
612 | DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value)); | ||
613 | break; | ||
614 | case V4L2_CID_CONTRAST: | ||
615 | value = saa7146_read(dev, BCS_CTRL); | ||
616 | c->value = 0x7f & (value >> 16); | ||
617 | DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value)); | ||
618 | break; | ||
619 | case V4L2_CID_SATURATION: | ||
620 | value = saa7146_read(dev, BCS_CTRL); | ||
621 | c->value = 0x7f & (value >> 0); | ||
622 | DEB_D(("V4L2_CID_SATURATION: %d\n", c->value)); | ||
623 | break; | ||
624 | case V4L2_CID_VFLIP: | ||
625 | c->value = vv->vflip; | ||
626 | DEB_D(("V4L2_CID_VFLIP: %d\n", c->value)); | ||
627 | break; | ||
628 | case V4L2_CID_HFLIP: | ||
629 | c->value = vv->hflip; | ||
630 | DEB_D(("V4L2_CID_HFLIP: %d\n", c->value)); | ||
631 | break; | ||
632 | default: | ||
633 | return -EINVAL; | ||
860 | } | 634 | } |
861 | if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) { | 635 | return 0; |
862 | DEB_D(("extension handles ioctl before.\n")); | 636 | } |
863 | result = dev->ext_vv_data->ioctl(fh, cmd, arg); | 637 | |
864 | if( -EAGAIN != result ) { | 638 | static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) |
865 | return result; | 639 | { |
866 | } | 640 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
641 | struct saa7146_vv *vv = dev->vv_data; | ||
642 | const struct v4l2_queryctrl *ctrl; | ||
643 | |||
644 | ctrl = ctrl_by_id(c->id); | ||
645 | if (NULL == ctrl) { | ||
646 | DEB_D(("unknown control %d\n", c->id)); | ||
647 | return -EINVAL; | ||
867 | } | 648 | } |
868 | 649 | ||
869 | /* fixme: add handle "after" case (is it still needed?) */ | 650 | mutex_lock(&dev->lock); |
870 | 651 | ||
871 | switch (fh->type) { | 652 | switch (ctrl->type) { |
872 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: { | 653 | case V4L2_CTRL_TYPE_BOOLEAN: |
873 | ops = &saa7146_video_uops; | 654 | case V4L2_CTRL_TYPE_MENU: |
874 | q = &fh->video_q; | 655 | case V4L2_CTRL_TYPE_INTEGER: |
656 | if (c->value < ctrl->minimum) | ||
657 | c->value = ctrl->minimum; | ||
658 | if (c->value > ctrl->maximum) | ||
659 | c->value = ctrl->maximum; | ||
875 | break; | 660 | break; |
661 | default: | ||
662 | /* nothing */; | ||
663 | } | ||
664 | |||
665 | switch (c->id) { | ||
666 | case V4L2_CID_BRIGHTNESS: { | ||
667 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
668 | value &= 0x00ffffff; | ||
669 | value |= (c->value << 24); | ||
670 | saa7146_write(dev, BCS_CTRL, value); | ||
671 | saa7146_write(dev, MC2, MASK_22 | MASK_06); | ||
672 | break; | ||
673 | } | ||
674 | case V4L2_CID_CONTRAST: { | ||
675 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
676 | value &= 0xff00ffff; | ||
677 | value |= (c->value << 16); | ||
678 | saa7146_write(dev, BCS_CTRL, value); | ||
679 | saa7146_write(dev, MC2, MASK_22 | MASK_06); | ||
680 | break; | ||
681 | } | ||
682 | case V4L2_CID_SATURATION: { | ||
683 | u32 value = saa7146_read(dev, BCS_CTRL); | ||
684 | value &= 0xffffff00; | ||
685 | value |= (c->value << 0); | ||
686 | saa7146_write(dev, BCS_CTRL, value); | ||
687 | saa7146_write(dev, MC2, MASK_22 | MASK_06); | ||
688 | break; | ||
689 | } | ||
690 | case V4L2_CID_HFLIP: | ||
691 | /* fixme: we can support changing VFLIP and HFLIP here... */ | ||
692 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
693 | DEB_D(("V4L2_CID_HFLIP while active capture.\n")); | ||
694 | mutex_unlock(&dev->lock); | ||
695 | return -EBUSY; | ||
876 | } | 696 | } |
877 | case V4L2_BUF_TYPE_VBI_CAPTURE: { | 697 | vv->hflip = c->value; |
878 | ops = &saa7146_vbi_uops; | ||
879 | q = &fh->vbi_q; | ||
880 | break; | 698 | break; |
699 | case V4L2_CID_VFLIP: | ||
700 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
701 | DEB_D(("V4L2_CID_VFLIP while active capture.\n")); | ||
702 | mutex_unlock(&dev->lock); | ||
703 | return -EBUSY; | ||
881 | } | 704 | } |
705 | vv->vflip = c->value; | ||
706 | break; | ||
882 | default: | 707 | default: |
883 | BUG(); | 708 | mutex_unlock(&dev->lock); |
884 | return 0; | 709 | return -EINVAL; |
885 | } | 710 | } |
711 | mutex_unlock(&dev->lock); | ||
886 | 712 | ||
887 | switch (cmd) { | 713 | if (IS_OVERLAY_ACTIVE(fh) != 0) { |
888 | case VIDIOC_QUERYCAP: | 714 | saa7146_stop_preview(fh); |
889 | { | 715 | saa7146_start_preview(fh); |
890 | struct v4l2_capability *cap = arg; | ||
891 | memset(cap,0,sizeof(*cap)); | ||
892 | |||
893 | DEB_EE(("VIDIOC_QUERYCAP\n")); | ||
894 | |||
895 | strcpy((char *)cap->driver, "saa7146 v4l2"); | ||
896 | strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); | ||
897 | sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci)); | ||
898 | cap->version = SAA7146_VERSION_CODE; | ||
899 | cap->capabilities = | ||
900 | V4L2_CAP_VIDEO_CAPTURE | | ||
901 | V4L2_CAP_VIDEO_OVERLAY | | ||
902 | V4L2_CAP_READWRITE | | ||
903 | V4L2_CAP_STREAMING; | ||
904 | cap->capabilities |= dev->ext_vv_data->capabilities; | ||
905 | return 0; | ||
906 | } | 716 | } |
907 | case VIDIOC_G_FBUF: | 717 | return 0; |
908 | { | 718 | } |
909 | struct v4l2_framebuffer *fb = arg; | ||
910 | |||
911 | DEB_EE(("VIDIOC_G_FBUF\n")); | ||
912 | 719 | ||
913 | *fb = vv->ov_fb; | 720 | static int vidioc_g_parm(struct file *file, void *fh, |
914 | fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; | 721 | struct v4l2_streamparm *parm) |
915 | return 0; | 722 | { |
916 | } | 723 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
917 | case VIDIOC_S_FBUF: | 724 | struct saa7146_vv *vv = dev->vv_data; |
918 | { | ||
919 | struct v4l2_framebuffer *fb = arg; | ||
920 | struct saa7146_format *fmt; | ||
921 | 725 | ||
922 | DEB_EE(("VIDIOC_S_FBUF\n")); | 726 | parm->parm.capture.readbuffers = 1; |
727 | v4l2_video_std_frame_period(vv->standard->id, | ||
728 | &parm->parm.capture.timeperframe); | ||
729 | return 0; | ||
730 | } | ||
923 | 731 | ||
924 | if(!capable(CAP_SYS_ADMIN) && | 732 | static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) |
925 | !capable(CAP_SYS_RAWIO)) | 733 | { |
926 | return -EPERM; | 734 | f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt; |
735 | return 0; | ||
736 | } | ||
927 | 737 | ||
928 | /* check args */ | 738 | static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) |
929 | fmt = format_by_fourcc(dev,fb->fmt.pixelformat); | 739 | { |
930 | if (NULL == fmt) { | 740 | f->fmt.win = ((struct saa7146_fh *)fh)->ov.win; |
931 | return -EINVAL; | 741 | return 0; |
932 | } | 742 | } |
933 | 743 | ||
934 | /* planar formats are not allowed for overlay video, clipping and video dma would clash */ | 744 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) |
935 | if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { | 745 | { |
936 | DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat)); | 746 | f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt; |
937 | } | 747 | return 0; |
748 | } | ||
938 | 749 | ||
939 | /* check if overlay is running */ | 750 | static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) |
940 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | 751 | { |
941 | if (vv->video_fh != fh) { | 752 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
942 | DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); | 753 | struct saa7146_vv *vv = dev->vv_data; |
943 | return -EBUSY; | 754 | struct saa7146_format *fmt; |
944 | } | 755 | enum v4l2_field field; |
945 | } | 756 | int maxw, maxh; |
757 | int calc_bpl; | ||
946 | 758 | ||
947 | mutex_lock(&dev->lock); | 759 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); |
948 | 760 | ||
949 | /* ok, accept it */ | 761 | fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); |
950 | vv->ov_fb = *fb; | 762 | if (NULL == fmt) |
951 | vv->ov_fmt = fmt; | 763 | return -EINVAL; |
952 | if (0 == vv->ov_fb.fmt.bytesperline) | ||
953 | vv->ov_fb.fmt.bytesperline = | ||
954 | vv->ov_fb.fmt.width*fmt->depth/8; | ||
955 | 764 | ||
956 | mutex_unlock(&dev->lock); | 765 | field = f->fmt.pix.field; |
766 | maxw = vv->standard->h_max_out; | ||
767 | maxh = vv->standard->v_max_out; | ||
957 | 768 | ||
958 | return 0; | 769 | if (V4L2_FIELD_ANY == field) { |
770 | field = (f->fmt.pix.height > maxh / 2) | ||
771 | ? V4L2_FIELD_INTERLACED | ||
772 | : V4L2_FIELD_BOTTOM; | ||
959 | } | 773 | } |
960 | case VIDIOC_ENUM_FMT: | 774 | switch (field) { |
961 | { | 775 | case V4L2_FIELD_ALTERNATE: |
962 | struct v4l2_fmtdesc *f = arg; | 776 | vv->last_field = V4L2_FIELD_TOP; |
963 | 777 | maxh = maxh / 2; | |
964 | switch (f->type) { | 778 | break; |
965 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 779 | case V4L2_FIELD_TOP: |
966 | case V4L2_BUF_TYPE_VIDEO_OVERLAY: | 780 | case V4L2_FIELD_BOTTOM: |
967 | if (f->index >= NUM_FORMATS) | 781 | vv->last_field = V4L2_FIELD_INTERLACED; |
968 | return -EINVAL; | 782 | maxh = maxh / 2; |
969 | strlcpy((char *)f->description, formats[f->index].name, | 783 | break; |
970 | sizeof(f->description)); | 784 | case V4L2_FIELD_INTERLACED: |
971 | f->pixelformat = formats[f->index].pixelformat; | 785 | vv->last_field = V4L2_FIELD_INTERLACED; |
972 | f->flags = 0; | 786 | break; |
973 | memset(f->reserved, 0, sizeof(f->reserved)); | 787 | default: |
974 | break; | 788 | DEB_D(("no known field mode '%d'.\n", field)); |
975 | default: | 789 | return -EINVAL; |
976 | return -EINVAL; | ||
977 | } | ||
978 | |||
979 | DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index)); | ||
980 | return 0; | ||
981 | } | 790 | } |
982 | case VIDIOC_QUERYCTRL: | ||
983 | { | ||
984 | const struct v4l2_queryctrl *ctrl; | ||
985 | struct v4l2_queryctrl *c = arg; | ||
986 | 791 | ||
987 | if ((c->id < V4L2_CID_BASE || | 792 | f->fmt.pix.field = field; |
988 | c->id >= V4L2_CID_LASTP1) && | 793 | if (f->fmt.pix.width > maxw) |
989 | (c->id < V4L2_CID_PRIVATE_BASE || | 794 | f->fmt.pix.width = maxw; |
990 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | 795 | if (f->fmt.pix.height > maxh) |
991 | return -EINVAL; | 796 | f->fmt.pix.height = maxh; |
992 | 797 | ||
993 | ctrl = ctrl_by_id(c->id); | 798 | calc_bpl = (f->fmt.pix.width * fmt->depth) / 8; |
994 | if( NULL == ctrl ) { | ||
995 | return -EINVAL; | ||
996 | /* | ||
997 | c->flags = V4L2_CTRL_FLAG_DISABLED; | ||
998 | return 0; | ||
999 | */ | ||
1000 | } | ||
1001 | 799 | ||
1002 | DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id)); | 800 | if (f->fmt.pix.bytesperline < calc_bpl) |
1003 | *c = *ctrl; | 801 | f->fmt.pix.bytesperline = calc_bpl; |
1004 | return 0; | 802 | |
803 | if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */ | ||
804 | f->fmt.pix.bytesperline = calc_bpl; | ||
805 | |||
806 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height; | ||
807 | DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width, | ||
808 | f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage)); | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | |||
814 | static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) | ||
815 | { | ||
816 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
817 | struct saa7146_vv *vv = dev->vv_data; | ||
818 | struct v4l2_window *win = &f->fmt.win; | ||
819 | enum v4l2_field field; | ||
820 | int maxw, maxh; | ||
821 | |||
822 | DEB_EE(("dev:%p\n", dev)); | ||
823 | |||
824 | if (NULL == vv->ov_fb.base) { | ||
825 | DEB_D(("no fb base set.\n")); | ||
826 | return -EINVAL; | ||
1005 | } | 827 | } |
1006 | case VIDIOC_G_CTRL: { | 828 | if (NULL == vv->ov_fmt) { |
1007 | DEB_EE(("VIDIOC_G_CTRL\n")); | 829 | DEB_D(("no fb fmt set.\n")); |
1008 | return get_control(fh,arg); | 830 | return -EINVAL; |
1009 | } | 831 | } |
1010 | case VIDIOC_S_CTRL: | 832 | if (win->w.width < 48 || win->w.height < 32) { |
1011 | { | 833 | DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height)); |
1012 | DEB_EE(("VIDIOC_S_CTRL\n")); | 834 | return -EINVAL; |
1013 | err = set_control(fh,arg); | ||
1014 | return err; | ||
1015 | } | 835 | } |
1016 | case VIDIOC_G_PARM: | 836 | if (win->clipcount > 16) { |
1017 | { | 837 | DEB_D(("clipcount too big.\n")); |
1018 | struct v4l2_streamparm *parm = arg; | 838 | return -EINVAL; |
1019 | if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) { | ||
1020 | return -EINVAL; | ||
1021 | } | ||
1022 | memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm)); | ||
1023 | parm->parm.capture.readbuffers = 1; | ||
1024 | // fixme: only for PAL! | ||
1025 | parm->parm.capture.timeperframe.numerator = 1; | ||
1026 | parm->parm.capture.timeperframe.denominator = 25; | ||
1027 | return 0; | ||
1028 | } | 839 | } |
1029 | case VIDIOC_G_FMT: | 840 | |
1030 | { | 841 | field = win->field; |
1031 | struct v4l2_format *f = arg; | 842 | maxw = vv->standard->h_max_out; |
1032 | DEB_EE(("VIDIOC_G_FMT\n")); | 843 | maxh = vv->standard->v_max_out; |
1033 | return g_fmt(fh,f); | 844 | |
845 | if (V4L2_FIELD_ANY == field) { | ||
846 | field = (win->w.height > maxh / 2) | ||
847 | ? V4L2_FIELD_INTERLACED | ||
848 | : V4L2_FIELD_TOP; | ||
849 | } | ||
850 | switch (field) { | ||
851 | case V4L2_FIELD_TOP: | ||
852 | case V4L2_FIELD_BOTTOM: | ||
853 | case V4L2_FIELD_ALTERNATE: | ||
854 | maxh = maxh / 2; | ||
855 | break; | ||
856 | case V4L2_FIELD_INTERLACED: | ||
857 | break; | ||
858 | default: | ||
859 | DEB_D(("no known field mode '%d'.\n", field)); | ||
860 | return -EINVAL; | ||
1034 | } | 861 | } |
1035 | case VIDIOC_S_FMT: | 862 | |
1036 | { | 863 | win->field = field; |
1037 | struct v4l2_format *f = arg; | 864 | if (win->w.width > maxw) |
1038 | DEB_EE(("VIDIOC_S_FMT\n")); | 865 | win->w.width = maxw; |
1039 | return s_fmt(fh,f); | 866 | if (win->w.height > maxh) |
867 | win->w.height = maxh; | ||
868 | |||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f) | ||
873 | { | ||
874 | struct saa7146_fh *fh = __fh; | ||
875 | struct saa7146_dev *dev = fh->dev; | ||
876 | struct saa7146_vv *vv = dev->vv_data; | ||
877 | int err; | ||
878 | |||
879 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); | ||
880 | if (IS_CAPTURE_ACTIVE(fh) != 0) { | ||
881 | DEB_EE(("streaming capture is active\n")); | ||
882 | return -EBUSY; | ||
1040 | } | 883 | } |
1041 | case VIDIOC_TRY_FMT: | 884 | err = vidioc_try_fmt_vid_cap(file, fh, f); |
1042 | { | 885 | if (0 != err) |
1043 | struct v4l2_format *f = arg; | 886 | return err; |
1044 | DEB_EE(("VIDIOC_TRY_FMT\n")); | 887 | fh->video_fmt = f->fmt.pix; |
1045 | return try_fmt(fh,f); | 888 | DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat)); |
889 | return 0; | ||
890 | } | ||
891 | |||
892 | static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f) | ||
893 | { | ||
894 | struct saa7146_fh *fh = __fh; | ||
895 | struct saa7146_dev *dev = fh->dev; | ||
896 | struct saa7146_vv *vv = dev->vv_data; | ||
897 | int err; | ||
898 | |||
899 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh)); | ||
900 | err = vidioc_try_fmt_vid_overlay(file, fh, f); | ||
901 | if (0 != err) | ||
902 | return err; | ||
903 | mutex_lock(&dev->lock); | ||
904 | fh->ov.win = f->fmt.win; | ||
905 | fh->ov.nclips = f->fmt.win.clipcount; | ||
906 | if (fh->ov.nclips > 16) | ||
907 | fh->ov.nclips = 16; | ||
908 | if (copy_from_user(fh->ov.clips, f->fmt.win.clips, | ||
909 | sizeof(struct v4l2_clip) * fh->ov.nclips)) { | ||
910 | mutex_unlock(&dev->lock); | ||
911 | return -EFAULT; | ||
1046 | } | 912 | } |
1047 | case VIDIOC_G_STD: | 913 | |
1048 | { | 914 | /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ |
1049 | v4l2_std_id *id = arg; | 915 | fh->ov.fh = fh; |
1050 | DEB_EE(("VIDIOC_G_STD\n")); | 916 | |
1051 | *id = vv->standard->id; | 917 | mutex_unlock(&dev->lock); |
1052 | return 0; | 918 | |
919 | /* check if our current overlay is active */ | ||
920 | if (IS_OVERLAY_ACTIVE(fh) != 0) { | ||
921 | saa7146_stop_preview(fh); | ||
922 | saa7146_start_preview(fh); | ||
1053 | } | 923 | } |
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm) | ||
928 | { | ||
929 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; | ||
930 | struct saa7146_vv *vv = dev->vv_data; | ||
931 | |||
932 | *norm = vv->standard->id; | ||
933 | return 0; | ||
934 | } | ||
935 | |||
1054 | /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) | 936 | /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) |
1055 | PAL / NTSC / SECAM. if your hardware does not (or does more) | 937 | PAL / NTSC / SECAM. if your hardware does not (or does more) |
1056 | -- override this function in your extension */ | 938 | -- override this function in your extension */ |
939 | /* | ||
1057 | case VIDIOC_ENUMSTD: | 940 | case VIDIOC_ENUMSTD: |
1058 | { | 941 | { |
1059 | struct v4l2_standard *e = arg; | 942 | struct v4l2_standard *e = arg; |
@@ -1066,162 +949,245 @@ long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
1066 | } | 949 | } |
1067 | return -EINVAL; | 950 | return -EINVAL; |
1068 | } | 951 | } |
1069 | case VIDIOC_S_STD: | 952 | */ |
1070 | { | ||
1071 | v4l2_std_id *id = arg; | ||
1072 | int found = 0; | ||
1073 | int i; | ||
1074 | |||
1075 | DEB_EE(("VIDIOC_S_STD\n")); | ||
1076 | 953 | ||
1077 | if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { | 954 | static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id) |
1078 | DEB_D(("cannot change video standard while streaming capture is active\n")); | 955 | { |
1079 | return -EBUSY; | 956 | struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; |
1080 | } | 957 | struct saa7146_vv *vv = dev->vv_data; |
958 | int found = 0; | ||
959 | int err, i; | ||
1081 | 960 | ||
1082 | if ((vv->video_status & STATUS_OVERLAY) != 0) { | 961 | DEB_EE(("VIDIOC_S_STD\n")); |
1083 | vv->ov_suspend = vv->video_fh; | ||
1084 | err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ | ||
1085 | if (0 != err) { | ||
1086 | DEB_D(("suspending video failed. aborting\n")); | ||
1087 | return err; | ||
1088 | } | ||
1089 | } | ||
1090 | 962 | ||
1091 | mutex_lock(&dev->lock); | 963 | if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { |
964 | DEB_D(("cannot change video standard while streaming capture is active\n")); | ||
965 | return -EBUSY; | ||
966 | } | ||
1092 | 967 | ||
1093 | for(i = 0; i < dev->ext_vv_data->num_stds; i++) | 968 | if ((vv->video_status & STATUS_OVERLAY) != 0) { |
1094 | if (*id & dev->ext_vv_data->stds[i].id) | 969 | vv->ov_suspend = vv->video_fh; |
1095 | break; | 970 | err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ |
1096 | if (i != dev->ext_vv_data->num_stds) { | 971 | if (0 != err) { |
1097 | vv->standard = &dev->ext_vv_data->stds[i]; | 972 | DEB_D(("suspending video failed. aborting\n")); |
1098 | if( NULL != dev->ext_vv_data->std_callback ) | 973 | return err; |
1099 | dev->ext_vv_data->std_callback(dev, vv->standard); | ||
1100 | found = 1; | ||
1101 | } | 974 | } |
975 | } | ||
1102 | 976 | ||
1103 | mutex_unlock(&dev->lock); | 977 | mutex_lock(&dev->lock); |
1104 | 978 | ||
1105 | if (vv->ov_suspend != NULL) { | 979 | for (i = 0; i < dev->ext_vv_data->num_stds; i++) |
1106 | saa7146_start_preview(vv->ov_suspend); | 980 | if (*id & dev->ext_vv_data->stds[i].id) |
1107 | vv->ov_suspend = NULL; | 981 | break; |
1108 | } | 982 | if (i != dev->ext_vv_data->num_stds) { |
983 | vv->standard = &dev->ext_vv_data->stds[i]; | ||
984 | if (NULL != dev->ext_vv_data->std_callback) | ||
985 | dev->ext_vv_data->std_callback(dev, vv->standard); | ||
986 | found = 1; | ||
987 | } | ||
1109 | 988 | ||
1110 | if( 0 == found ) { | 989 | mutex_unlock(&dev->lock); |
1111 | DEB_EE(("VIDIOC_S_STD: standard not found.\n")); | ||
1112 | return -EINVAL; | ||
1113 | } | ||
1114 | 990 | ||
1115 | DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name)); | 991 | if (vv->ov_suspend != NULL) { |
1116 | return 0; | 992 | saa7146_start_preview(vv->ov_suspend); |
993 | vv->ov_suspend = NULL; | ||
1117 | } | 994 | } |
1118 | case VIDIOC_OVERLAY: | ||
1119 | { | ||
1120 | int on = *(int *)arg; | ||
1121 | 995 | ||
1122 | DEB_D(("VIDIOC_OVERLAY on:%d\n",on)); | 996 | if (!found) { |
1123 | if (on != 0) { | 997 | DEB_EE(("VIDIOC_S_STD: standard not found.\n")); |
1124 | err = saa7146_start_preview(fh); | 998 | return -EINVAL; |
1125 | } else { | ||
1126 | err = saa7146_stop_preview(fh); | ||
1127 | } | ||
1128 | return err; | ||
1129 | } | ||
1130 | case VIDIOC_REQBUFS: { | ||
1131 | struct v4l2_requestbuffers *req = arg; | ||
1132 | DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type)); | ||
1133 | return videobuf_reqbufs(q,req); | ||
1134 | } | ||
1135 | case VIDIOC_QUERYBUF: { | ||
1136 | struct v4l2_buffer *buf = arg; | ||
1137 | DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset)); | ||
1138 | return videobuf_querybuf(q,buf); | ||
1139 | } | ||
1140 | case VIDIOC_QBUF: { | ||
1141 | struct v4l2_buffer *buf = arg; | ||
1142 | int ret = 0; | ||
1143 | ret = videobuf_qbuf(q,buf); | ||
1144 | DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index)); | ||
1145 | return ret; | ||
1146 | } | ||
1147 | case VIDIOC_DQBUF: { | ||
1148 | struct v4l2_buffer *buf = arg; | ||
1149 | int ret = 0; | ||
1150 | ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK); | ||
1151 | DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index)); | ||
1152 | return ret; | ||
1153 | } | 999 | } |
1154 | case VIDIOC_STREAMON: { | ||
1155 | int *type = arg; | ||
1156 | DEB_D(("VIDIOC_STREAMON, type:%d\n",*type)); | ||
1157 | 1000 | ||
1158 | err = video_begin(fh); | 1001 | DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name)); |
1159 | if( 0 != err) { | 1002 | return 0; |
1160 | return err; | 1003 | } |
1161 | } | ||
1162 | err = videobuf_streamon(q); | ||
1163 | return err; | ||
1164 | } | ||
1165 | case VIDIOC_STREAMOFF: { | ||
1166 | int *type = arg; | ||
1167 | 1004 | ||
1168 | DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type)); | 1005 | static int vidioc_overlay(struct file *file, void *fh, unsigned int on) |
1006 | { | ||
1007 | int err; | ||
1169 | 1008 | ||
1170 | /* ugly: we need to copy some checks from video_end(), | 1009 | DEB_D(("VIDIOC_OVERLAY on:%d\n", on)); |
1171 | because videobuf_streamoff() relies on the capture running. | 1010 | if (on) |
1172 | check and fix this */ | 1011 | err = saa7146_start_preview(fh); |
1173 | if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { | 1012 | else |
1174 | DEB_S(("not capturing.\n")); | 1013 | err = saa7146_stop_preview(fh); |
1175 | return 0; | 1014 | return err; |
1176 | } | 1015 | } |
1177 | 1016 | ||
1178 | if (vv->video_fh != fh) { | 1017 | static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b) |
1179 | DEB_S(("capturing, but in another open.\n")); | 1018 | { |
1180 | return -EBUSY; | 1019 | struct saa7146_fh *fh = __fh; |
1181 | } | ||
1182 | 1020 | ||
1183 | err = videobuf_streamoff(q); | 1021 | if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1184 | if (0 != err) { | 1022 | return videobuf_reqbufs(&fh->video_q, b); |
1185 | DEB_D(("warning: videobuf_streamoff() failed.\n")); | 1023 | if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE) |
1186 | video_end(fh, file); | 1024 | return videobuf_reqbufs(&fh->vbi_q, b); |
1187 | } else { | 1025 | return -EINVAL; |
1188 | err = video_end(fh, file); | 1026 | } |
1189 | } | 1027 | |
1028 | static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
1029 | { | ||
1030 | struct saa7146_fh *fh = __fh; | ||
1031 | |||
1032 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1033 | return videobuf_querybuf(&fh->video_q, buf); | ||
1034 | if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1035 | return videobuf_querybuf(&fh->vbi_q, buf); | ||
1036 | return -EINVAL; | ||
1037 | } | ||
1038 | |||
1039 | static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
1040 | { | ||
1041 | struct saa7146_fh *fh = __fh; | ||
1042 | |||
1043 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1044 | return videobuf_qbuf(&fh->video_q, buf); | ||
1045 | if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1046 | return videobuf_qbuf(&fh->vbi_q, buf); | ||
1047 | return -EINVAL; | ||
1048 | } | ||
1049 | |||
1050 | static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf) | ||
1051 | { | ||
1052 | struct saa7146_fh *fh = __fh; | ||
1053 | |||
1054 | if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1055 | return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK); | ||
1056 | if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1057 | return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK); | ||
1058 | return -EINVAL; | ||
1059 | } | ||
1060 | |||
1061 | static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
1062 | { | ||
1063 | struct saa7146_fh *fh = __fh; | ||
1064 | int err; | ||
1065 | |||
1066 | DEB_D(("VIDIOC_STREAMON, type:%d\n", type)); | ||
1067 | |||
1068 | err = video_begin(fh); | ||
1069 | if (err) | ||
1190 | return err; | 1070 | return err; |
1071 | if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1072 | return videobuf_streamon(&fh->video_q); | ||
1073 | if (type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1074 | return videobuf_streamon(&fh->vbi_q); | ||
1075 | return -EINVAL; | ||
1076 | } | ||
1077 | |||
1078 | static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type) | ||
1079 | { | ||
1080 | struct saa7146_fh *fh = __fh; | ||
1081 | struct saa7146_dev *dev = fh->dev; | ||
1082 | struct saa7146_vv *vv = dev->vv_data; | ||
1083 | int err; | ||
1084 | |||
1085 | DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type)); | ||
1086 | |||
1087 | /* ugly: we need to copy some checks from video_end(), | ||
1088 | because videobuf_streamoff() relies on the capture running. | ||
1089 | check and fix this */ | ||
1090 | if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { | ||
1091 | DEB_S(("not capturing.\n")); | ||
1092 | return 0; | ||
1191 | } | 1093 | } |
1192 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1193 | case VIDIOCGMBUF: | ||
1194 | { | ||
1195 | struct video_mbuf *mbuf = arg; | ||
1196 | int i; | ||
1197 | 1094 | ||
1198 | /* fixme: number of capture buffers and sizes for v4l apps */ | 1095 | if (vv->video_fh != fh) { |
1199 | int gbuffers = 2; | 1096 | DEB_S(("capturing, but in another open.\n")); |
1200 | int gbufsize = 768*576*4; | 1097 | return -EBUSY; |
1098 | } | ||
1201 | 1099 | ||
1202 | DEB_D(("VIDIOCGMBUF \n")); | 1100 | err = -EINVAL; |
1101 | if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1102 | err = videobuf_streamoff(&fh->video_q); | ||
1103 | else if (type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1104 | err = videobuf_streamoff(&fh->vbi_q); | ||
1105 | if (0 != err) { | ||
1106 | DEB_D(("warning: videobuf_streamoff() failed.\n")); | ||
1107 | video_end(fh, file); | ||
1108 | } else { | ||
1109 | err = video_end(fh, file); | ||
1110 | } | ||
1111 | return err; | ||
1112 | } | ||
1203 | 1113 | ||
1204 | q = &fh->video_q; | 1114 | static int vidioc_g_chip_ident(struct file *file, void *__fh, |
1205 | err = videobuf_mmap_setup(q,gbuffers,gbufsize, | 1115 | struct v4l2_dbg_chip_ident *chip) |
1206 | V4L2_MEMORY_MMAP); | 1116 | { |
1207 | if (err < 0) | 1117 | struct saa7146_fh *fh = __fh; |
1208 | return err; | 1118 | struct saa7146_dev *dev = fh->dev; |
1209 | 1119 | ||
1210 | gbuffers = err; | 1120 | chip->ident = V4L2_IDENT_NONE; |
1211 | memset(mbuf,0,sizeof(*mbuf)); | 1121 | chip->revision = 0; |
1212 | mbuf->frames = gbuffers; | 1122 | if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { |
1213 | mbuf->size = gbuffers * gbufsize; | 1123 | chip->ident = V4L2_IDENT_SAA7146; |
1214 | for (i = 0; i < gbuffers; i++) | ||
1215 | mbuf->offsets[i] = i * gbufsize; | ||
1216 | return 0; | 1124 | return 0; |
1217 | } | 1125 | } |
1218 | #endif | 1126 | return v4l2_device_call_until_err(&dev->v4l2_dev, 0, |
1219 | default: | 1127 | core, g_chip_ident, chip); |
1220 | return v4l_compat_translate_ioctl(file, cmd, arg, | 1128 | } |
1221 | saa7146_video_do_ioctl); | 1129 | |
1222 | } | 1130 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1131 | static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf) | ||
1132 | { | ||
1133 | struct saa7146_fh *fh = __fh; | ||
1134 | struct videobuf_queue *q = &fh->video_q; | ||
1135 | int err, i; | ||
1136 | |||
1137 | /* fixme: number of capture buffers and sizes for v4l apps */ | ||
1138 | int gbuffers = 2; | ||
1139 | int gbufsize = 768 * 576 * 4; | ||
1140 | |||
1141 | DEB_D(("VIDIOCGMBUF \n")); | ||
1142 | |||
1143 | q = &fh->video_q; | ||
1144 | err = videobuf_mmap_setup(q, gbuffers, gbufsize, | ||
1145 | V4L2_MEMORY_MMAP); | ||
1146 | if (err < 0) | ||
1147 | return err; | ||
1148 | |||
1149 | gbuffers = err; | ||
1150 | memset(mbuf, 0, sizeof(*mbuf)); | ||
1151 | mbuf->frames = gbuffers; | ||
1152 | mbuf->size = gbuffers * gbufsize; | ||
1153 | for (i = 0; i < gbuffers; i++) | ||
1154 | mbuf->offsets[i] = i * gbufsize; | ||
1223 | return 0; | 1155 | return 0; |
1224 | } | 1156 | } |
1157 | #endif | ||
1158 | |||
1159 | const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = { | ||
1160 | .vidioc_querycap = vidioc_querycap, | ||
1161 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
1162 | .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap, | ||
1163 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
1164 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
1165 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
1166 | .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, | ||
1167 | .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, | ||
1168 | .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, | ||
1169 | .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, | ||
1170 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1171 | |||
1172 | .vidioc_overlay = vidioc_overlay, | ||
1173 | .vidioc_g_fbuf = vidioc_g_fbuf, | ||
1174 | .vidioc_s_fbuf = vidioc_s_fbuf, | ||
1175 | .vidioc_reqbufs = vidioc_reqbufs, | ||
1176 | .vidioc_querybuf = vidioc_querybuf, | ||
1177 | .vidioc_qbuf = vidioc_qbuf, | ||
1178 | .vidioc_dqbuf = vidioc_dqbuf, | ||
1179 | .vidioc_g_std = vidioc_g_std, | ||
1180 | .vidioc_s_std = vidioc_s_std, | ||
1181 | .vidioc_queryctrl = vidioc_queryctrl, | ||
1182 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
1183 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
1184 | .vidioc_streamon = vidioc_streamon, | ||
1185 | .vidioc_streamoff = vidioc_streamoff, | ||
1186 | .vidioc_g_parm = vidioc_g_parm, | ||
1187 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
1188 | .vidiocgmbuf = vidiocgmbuf, | ||
1189 | #endif | ||
1190 | }; | ||
1225 | 1191 | ||
1226 | /*********************************************************************************/ | 1192 | /*********************************************************************************/ |
1227 | /* buffer handling functions */ | 1193 | /* buffer handling functions */ |
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig index da058c174049..607d319ce8ed 100644 --- a/drivers/media/common/tuners/Kconfig +++ b/drivers/media/common/tuners/Kconfig | |||
@@ -21,16 +21,17 @@ config MEDIA_TUNER | |||
21 | tristate | 21 | tristate |
22 | default VIDEO_MEDIA && I2C | 22 | default VIDEO_MEDIA && I2C |
23 | depends on VIDEO_MEDIA && I2C | 23 | depends on VIDEO_MEDIA && I2C |
24 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE | 24 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE |
25 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE | 25 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE |
26 | select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE | 26 | select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE |
27 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE | 27 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE |
28 | select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE | 28 | select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE |
29 | select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE | 29 | select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE |
30 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE | 30 | select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE |
31 | select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE | 31 | select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE |
32 | 32 | select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE | |
33 | menuconfig MEDIA_TUNER_CUSTOMIZE | 33 | |
34 | menuconfig MEDIA_TUNER_CUSTOMISE | ||
34 | bool "Customize analog and hybrid tuner modules to build" | 35 | bool "Customize analog and hybrid tuner modules to build" |
35 | depends on MEDIA_TUNER | 36 | depends on MEDIA_TUNER |
36 | default n | 37 | default n |
@@ -43,13 +44,13 @@ menuconfig MEDIA_TUNER_CUSTOMIZE | |||
43 | 44 | ||
44 | If unsure say N. | 45 | If unsure say N. |
45 | 46 | ||
46 | if MEDIA_TUNER_CUSTOMIZE | 47 | if MEDIA_TUNER_CUSTOMISE |
47 | 48 | ||
48 | config MEDIA_TUNER_SIMPLE | 49 | config MEDIA_TUNER_SIMPLE |
49 | tristate "Simple tuner support" | 50 | tristate "Simple tuner support" |
50 | depends on VIDEO_MEDIA && I2C | 51 | depends on VIDEO_MEDIA && I2C |
51 | select MEDIA_TUNER_TDA9887 | 52 | select MEDIA_TUNER_TDA9887 |
52 | default m if MEDIA_TUNER_CUSTOMIZE | 53 | default m if MEDIA_TUNER_CUSTOMISE |
53 | help | 54 | help |
54 | Say Y here to include support for various simple tuners. | 55 | Say Y here to include support for various simple tuners. |
55 | 56 | ||
@@ -58,28 +59,28 @@ config MEDIA_TUNER_TDA8290 | |||
58 | depends on VIDEO_MEDIA && I2C | 59 | depends on VIDEO_MEDIA && I2C |
59 | select MEDIA_TUNER_TDA827X | 60 | select MEDIA_TUNER_TDA827X |
60 | select MEDIA_TUNER_TDA18271 | 61 | select MEDIA_TUNER_TDA18271 |
61 | default m if MEDIA_TUNER_CUSTOMIZE | 62 | default m if MEDIA_TUNER_CUSTOMISE |
62 | help | 63 | help |
63 | Say Y here to include support for Philips TDA8290+8275(a) tuner. | 64 | Say Y here to include support for Philips TDA8290+8275(a) tuner. |
64 | 65 | ||
65 | config MEDIA_TUNER_TDA827X | 66 | config MEDIA_TUNER_TDA827X |
66 | tristate "Philips TDA827X silicon tuner" | 67 | tristate "Philips TDA827X silicon tuner" |
67 | depends on VIDEO_MEDIA && I2C | 68 | depends on VIDEO_MEDIA && I2C |
68 | default m if DVB_FE_CUSTOMISE | 69 | default m if MEDIA_TUNER_CUSTOMISE |
69 | help | 70 | help |
70 | A DVB-T silicon tuner module. Say Y when you want to support this tuner. | 71 | A DVB-T silicon tuner module. Say Y when you want to support this tuner. |
71 | 72 | ||
72 | config MEDIA_TUNER_TDA18271 | 73 | config MEDIA_TUNER_TDA18271 |
73 | tristate "NXP TDA18271 silicon tuner" | 74 | tristate "NXP TDA18271 silicon tuner" |
74 | depends on VIDEO_MEDIA && I2C | 75 | depends on VIDEO_MEDIA && I2C |
75 | default m if DVB_FE_CUSTOMISE | 76 | default m if MEDIA_TUNER_CUSTOMISE |
76 | help | 77 | help |
77 | A silicon tuner module. Say Y when you want to support this tuner. | 78 | A silicon tuner module. Say Y when you want to support this tuner. |
78 | 79 | ||
79 | config MEDIA_TUNER_TDA9887 | 80 | config MEDIA_TUNER_TDA9887 |
80 | tristate "TDA 9885/6/7 analog IF demodulator" | 81 | tristate "TDA 9885/6/7 analog IF demodulator" |
81 | depends on VIDEO_MEDIA && I2C | 82 | depends on VIDEO_MEDIA && I2C |
82 | default m if MEDIA_TUNER_CUSTOMIZE | 83 | default m if MEDIA_TUNER_CUSTOMISE |
83 | help | 84 | help |
84 | Say Y here to include support for Philips TDA9885/6/7 | 85 | Say Y here to include support for Philips TDA9885/6/7 |
85 | analog IF demodulator. | 86 | analog IF demodulator. |
@@ -88,63 +89,63 @@ config MEDIA_TUNER_TEA5761 | |||
88 | tristate "TEA 5761 radio tuner (EXPERIMENTAL)" | 89 | tristate "TEA 5761 radio tuner (EXPERIMENTAL)" |
89 | depends on VIDEO_MEDIA && I2C | 90 | depends on VIDEO_MEDIA && I2C |
90 | depends on EXPERIMENTAL | 91 | depends on EXPERIMENTAL |
91 | default m if MEDIA_TUNER_CUSTOMIZE | 92 | default m if MEDIA_TUNER_CUSTOMISE |
92 | help | 93 | help |
93 | Say Y here to include support for the Philips TEA5761 radio tuner. | 94 | Say Y here to include support for the Philips TEA5761 radio tuner. |
94 | 95 | ||
95 | config MEDIA_TUNER_TEA5767 | 96 | config MEDIA_TUNER_TEA5767 |
96 | tristate "TEA 5767 radio tuner" | 97 | tristate "TEA 5767 radio tuner" |
97 | depends on VIDEO_MEDIA && I2C | 98 | depends on VIDEO_MEDIA && I2C |
98 | default m if MEDIA_TUNER_CUSTOMIZE | 99 | default m if MEDIA_TUNER_CUSTOMISE |
99 | help | 100 | help |
100 | Say Y here to include support for the Philips TEA5767 radio tuner. | 101 | Say Y here to include support for the Philips TEA5767 radio tuner. |
101 | 102 | ||
102 | config MEDIA_TUNER_MT20XX | 103 | config MEDIA_TUNER_MT20XX |
103 | tristate "Microtune 2032 / 2050 tuners" | 104 | tristate "Microtune 2032 / 2050 tuners" |
104 | depends on VIDEO_MEDIA && I2C | 105 | depends on VIDEO_MEDIA && I2C |
105 | default m if MEDIA_TUNER_CUSTOMIZE | 106 | default m if MEDIA_TUNER_CUSTOMISE |
106 | help | 107 | help |
107 | Say Y here to include support for the MT2032 / MT2050 tuner. | 108 | Say Y here to include support for the MT2032 / MT2050 tuner. |
108 | 109 | ||
109 | config MEDIA_TUNER_MT2060 | 110 | config MEDIA_TUNER_MT2060 |
110 | tristate "Microtune MT2060 silicon IF tuner" | 111 | tristate "Microtune MT2060 silicon IF tuner" |
111 | depends on VIDEO_MEDIA && I2C | 112 | depends on VIDEO_MEDIA && I2C |
112 | default m if DVB_FE_CUSTOMISE | 113 | default m if MEDIA_TUNER_CUSTOMISE |
113 | help | 114 | help |
114 | A driver for the silicon IF tuner MT2060 from Microtune. | 115 | A driver for the silicon IF tuner MT2060 from Microtune. |
115 | 116 | ||
116 | config MEDIA_TUNER_MT2266 | 117 | config MEDIA_TUNER_MT2266 |
117 | tristate "Microtune MT2266 silicon tuner" | 118 | tristate "Microtune MT2266 silicon tuner" |
118 | depends on VIDEO_MEDIA && I2C | 119 | depends on VIDEO_MEDIA && I2C |
119 | default m if DVB_FE_CUSTOMISE | 120 | default m if MEDIA_TUNER_CUSTOMISE |
120 | help | 121 | help |
121 | A driver for the silicon baseband tuner MT2266 from Microtune. | 122 | A driver for the silicon baseband tuner MT2266 from Microtune. |
122 | 123 | ||
123 | config MEDIA_TUNER_MT2131 | 124 | config MEDIA_TUNER_MT2131 |
124 | tristate "Microtune MT2131 silicon tuner" | 125 | tristate "Microtune MT2131 silicon tuner" |
125 | depends on VIDEO_MEDIA && I2C | 126 | depends on VIDEO_MEDIA && I2C |
126 | default m if DVB_FE_CUSTOMISE | 127 | default m if MEDIA_TUNER_CUSTOMISE |
127 | help | 128 | help |
128 | A driver for the silicon baseband tuner MT2131 from Microtune. | 129 | A driver for the silicon baseband tuner MT2131 from Microtune. |
129 | 130 | ||
130 | config MEDIA_TUNER_QT1010 | 131 | config MEDIA_TUNER_QT1010 |
131 | tristate "Quantek QT1010 silicon tuner" | 132 | tristate "Quantek QT1010 silicon tuner" |
132 | depends on VIDEO_MEDIA && I2C | 133 | depends on VIDEO_MEDIA && I2C |
133 | default m if DVB_FE_CUSTOMISE | 134 | default m if MEDIA_TUNER_CUSTOMISE |
134 | help | 135 | help |
135 | A driver for the silicon tuner QT1010 from Quantek. | 136 | A driver for the silicon tuner QT1010 from Quantek. |
136 | 137 | ||
137 | config MEDIA_TUNER_XC2028 | 138 | config MEDIA_TUNER_XC2028 |
138 | tristate "XCeive xc2028/xc3028 tuners" | 139 | tristate "XCeive xc2028/xc3028 tuners" |
139 | depends on VIDEO_MEDIA && I2C | 140 | depends on VIDEO_MEDIA && I2C |
140 | default m if MEDIA_TUNER_CUSTOMIZE | 141 | default m if MEDIA_TUNER_CUSTOMISE |
141 | help | 142 | help |
142 | Say Y here to include support for the xc2028/xc3028 tuners. | 143 | Say Y here to include support for the xc2028/xc3028 tuners. |
143 | 144 | ||
144 | config MEDIA_TUNER_XC5000 | 145 | config MEDIA_TUNER_XC5000 |
145 | tristate "Xceive XC5000 silicon tuner" | 146 | tristate "Xceive XC5000 silicon tuner" |
146 | depends on VIDEO_MEDIA && I2C | 147 | depends on VIDEO_MEDIA && I2C |
147 | default m if DVB_FE_CUSTOMISE | 148 | default m if MEDIA_TUNER_CUSTOMISE |
148 | help | 149 | help |
149 | A driver for the silicon tuner XC5000 from Xceive. | 150 | A driver for the silicon tuner XC5000 from Xceive. |
150 | This device is only used inside a SiP called together with a | 151 | This device is only used inside a SiP called together with a |
@@ -153,15 +154,22 @@ config MEDIA_TUNER_XC5000 | |||
153 | config MEDIA_TUNER_MXL5005S | 154 | config MEDIA_TUNER_MXL5005S |
154 | tristate "MaxLinear MSL5005S silicon tuner" | 155 | tristate "MaxLinear MSL5005S silicon tuner" |
155 | depends on VIDEO_MEDIA && I2C | 156 | depends on VIDEO_MEDIA && I2C |
156 | default m if DVB_FE_CUSTOMISE | 157 | default m if MEDIA_TUNER_CUSTOMISE |
157 | help | 158 | help |
158 | A driver for the silicon tuner MXL5005S from MaxLinear. | 159 | A driver for the silicon tuner MXL5005S from MaxLinear. |
159 | 160 | ||
160 | config MEDIA_TUNER_MXL5007T | 161 | config MEDIA_TUNER_MXL5007T |
161 | tristate "MaxLinear MxL5007T silicon tuner" | 162 | tristate "MaxLinear MxL5007T silicon tuner" |
162 | depends on VIDEO_MEDIA && I2C | 163 | depends on VIDEO_MEDIA && I2C |
163 | default m if DVB_FE_CUSTOMISE | 164 | default m if MEDIA_TUNER_CUSTOMISE |
164 | help | 165 | help |
165 | A driver for the silicon tuner MxL5007T from MaxLinear. | 166 | A driver for the silicon tuner MxL5007T from MaxLinear. |
166 | 167 | ||
167 | endif # MEDIA_TUNER_CUSTOMIZE | 168 | config MEDIA_TUNER_MC44S803 |
169 | tristate "Freescale MC44S803 Low Power CMOS Broadband tuners" | ||
170 | depends on VIDEO_MEDIA && I2C | ||
171 | default m if MEDIA_TUNER_CUSTOMISE | ||
172 | help | ||
173 | Say Y here to support the Freescale MC44S803 based tuners | ||
174 | |||
175 | endif # MEDIA_TUNER_CUSTOMISE | ||
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile index 4dfbe5b8264f..4132b2be79e5 100644 --- a/drivers/media/common/tuners/Makefile +++ b/drivers/media/common/tuners/Makefile | |||
@@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o | |||
22 | obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o | 22 | obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o |
23 | obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o | 23 | obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o |
24 | obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o | 24 | obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o |
25 | obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o | ||
25 | 26 | ||
26 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 27 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
27 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends | 28 | EXTRA_CFLAGS += -Idrivers/media/dvb/frontends |
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c new file mode 100644 index 000000000000..20c4485ce16a --- /dev/null +++ b/drivers/media/common/tuners/mc44s803.c | |||
@@ -0,0 +1,371 @@ | |||
1 | /* | ||
2 | * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner | ||
3 | * | ||
4 | * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/dvb/frontend.h> | ||
25 | #include <linux/i2c.h> | ||
26 | |||
27 | #include "dvb_frontend.h" | ||
28 | |||
29 | #include "mc44s803.h" | ||
30 | #include "mc44s803_priv.h" | ||
31 | |||
32 | #define mc_printk(level, format, arg...) \ | ||
33 | printk(level "mc44s803: " format , ## arg) | ||
34 | |||
35 | /* Writes a single register */ | ||
36 | static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val) | ||
37 | { | ||
38 | u8 buf[3]; | ||
39 | struct i2c_msg msg = { | ||
40 | .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3 | ||
41 | }; | ||
42 | |||
43 | buf[0] = (val & 0xff0000) >> 16; | ||
44 | buf[1] = (val & 0xff00) >> 8; | ||
45 | buf[2] = (val & 0xff); | ||
46 | |||
47 | if (i2c_transfer(priv->i2c, &msg, 1) != 1) { | ||
48 | mc_printk(KERN_WARNING, "I2C write failed\n"); | ||
49 | return -EREMOTEIO; | ||
50 | } | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /* Reads a single register */ | ||
55 | static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val) | ||
56 | { | ||
57 | u32 wval; | ||
58 | u8 buf[3]; | ||
59 | int ret; | ||
60 | struct i2c_msg msg[] = { | ||
61 | { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, | ||
62 | .buf = buf, .len = 3 }, | ||
63 | }; | ||
64 | |||
65 | wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) | | ||
66 | MC44S803_REG_SM(reg, MC44S803_D); | ||
67 | |||
68 | ret = mc44s803_writereg(priv, wval); | ||
69 | if (ret) | ||
70 | return ret; | ||
71 | |||
72 | if (i2c_transfer(priv->i2c, msg, 1) != 1) { | ||
73 | mc_printk(KERN_WARNING, "I2C read failed\n"); | ||
74 | return -EREMOTEIO; | ||
75 | } | ||
76 | |||
77 | *val = (buf[0] << 16) | (buf[1] << 8) | buf[2]; | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int mc44s803_release(struct dvb_frontend *fe) | ||
83 | { | ||
84 | struct mc44s803_priv *priv = fe->tuner_priv; | ||
85 | |||
86 | fe->tuner_priv = NULL; | ||
87 | kfree(priv); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int mc44s803_init(struct dvb_frontend *fe) | ||
93 | { | ||
94 | struct mc44s803_priv *priv = fe->tuner_priv; | ||
95 | u32 val; | ||
96 | int err; | ||
97 | |||
98 | if (fe->ops.i2c_gate_ctrl) | ||
99 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
100 | |||
101 | /* Reset chip */ | ||
102 | val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) | | ||
103 | MC44S803_REG_SM(1, MC44S803_RS); | ||
104 | |||
105 | err = mc44s803_writereg(priv, val); | ||
106 | if (err) | ||
107 | goto exit; | ||
108 | |||
109 | val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR); | ||
110 | |||
111 | err = mc44s803_writereg(priv, val); | ||
112 | if (err) | ||
113 | goto exit; | ||
114 | |||
115 | /* Power Up and Start Osc */ | ||
116 | |||
117 | val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) | | ||
118 | MC44S803_REG_SM(0xC0, MC44S803_REFOSC) | | ||
119 | MC44S803_REG_SM(1, MC44S803_OSCSEL); | ||
120 | |||
121 | err = mc44s803_writereg(priv, val); | ||
122 | if (err) | ||
123 | goto exit; | ||
124 | |||
125 | val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) | | ||
126 | MC44S803_REG_SM(0x200, MC44S803_POWER); | ||
127 | |||
128 | err = mc44s803_writereg(priv, val); | ||
129 | if (err) | ||
130 | goto exit; | ||
131 | |||
132 | msleep(10); | ||
133 | |||
134 | val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) | | ||
135 | MC44S803_REG_SM(0x40, MC44S803_REFOSC) | | ||
136 | MC44S803_REG_SM(1, MC44S803_OSCSEL); | ||
137 | |||
138 | err = mc44s803_writereg(priv, val); | ||
139 | if (err) | ||
140 | goto exit; | ||
141 | |||
142 | msleep(20); | ||
143 | |||
144 | /* Setup Mixer */ | ||
145 | |||
146 | val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) | | ||
147 | MC44S803_REG_SM(1, MC44S803_TRI_STATE) | | ||
148 | MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES); | ||
149 | |||
150 | err = mc44s803_writereg(priv, val); | ||
151 | if (err) | ||
152 | goto exit; | ||
153 | |||
154 | /* Setup Cirquit Adjust */ | ||
155 | |||
156 | val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) | | ||
157 | MC44S803_REG_SM(1, MC44S803_G1) | | ||
158 | MC44S803_REG_SM(1, MC44S803_G3) | | ||
159 | MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) | | ||
160 | MC44S803_REG_SM(1, MC44S803_G6) | | ||
161 | MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) | | ||
162 | MC44S803_REG_SM(0x3, MC44S803_LP) | | ||
163 | MC44S803_REG_SM(1, MC44S803_CLRF) | | ||
164 | MC44S803_REG_SM(1, MC44S803_CLIF); | ||
165 | |||
166 | err = mc44s803_writereg(priv, val); | ||
167 | if (err) | ||
168 | goto exit; | ||
169 | |||
170 | val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) | | ||
171 | MC44S803_REG_SM(1, MC44S803_G1) | | ||
172 | MC44S803_REG_SM(1, MC44S803_G3) | | ||
173 | MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) | | ||
174 | MC44S803_REG_SM(1, MC44S803_G6) | | ||
175 | MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) | | ||
176 | MC44S803_REG_SM(0x3, MC44S803_LP); | ||
177 | |||
178 | err = mc44s803_writereg(priv, val); | ||
179 | if (err) | ||
180 | goto exit; | ||
181 | |||
182 | /* Setup Digtune */ | ||
183 | |||
184 | val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | | ||
185 | MC44S803_REG_SM(3, MC44S803_XOD); | ||
186 | |||
187 | err = mc44s803_writereg(priv, val); | ||
188 | if (err) | ||
189 | goto exit; | ||
190 | |||
191 | /* Setup AGC */ | ||
192 | |||
193 | val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) | | ||
194 | MC44S803_REG_SM(1, MC44S803_AT1) | | ||
195 | MC44S803_REG_SM(1, MC44S803_AT2) | | ||
196 | MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) | | ||
197 | MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) | | ||
198 | MC44S803_REG_SM(1, MC44S803_LNA0); | ||
199 | |||
200 | err = mc44s803_writereg(priv, val); | ||
201 | if (err) | ||
202 | goto exit; | ||
203 | |||
204 | if (fe->ops.i2c_gate_ctrl) | ||
205 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
206 | return 0; | ||
207 | |||
208 | exit: | ||
209 | if (fe->ops.i2c_gate_ctrl) | ||
210 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
211 | |||
212 | mc_printk(KERN_WARNING, "I/O Error\n"); | ||
213 | return err; | ||
214 | } | ||
215 | |||
216 | static int mc44s803_set_params(struct dvb_frontend *fe, | ||
217 | struct dvb_frontend_parameters *params) | ||
218 | { | ||
219 | struct mc44s803_priv *priv = fe->tuner_priv; | ||
220 | u32 r1, r2, n1, n2, lo1, lo2, freq, val; | ||
221 | int err; | ||
222 | |||
223 | priv->frequency = params->frequency; | ||
224 | |||
225 | r1 = MC44S803_OSC / 1000000; | ||
226 | r2 = MC44S803_OSC / 100000; | ||
227 | |||
228 | n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000; | ||
229 | freq = MC44S803_OSC / r1 * n1; | ||
230 | lo1 = ((60 * n1) + (r1 / 2)) / r1; | ||
231 | freq = freq - params->frequency; | ||
232 | |||
233 | n2 = (freq - MC44S803_IF2 + 50000) / 100000; | ||
234 | lo2 = ((60 * n2) + (r2 / 2)) / r2; | ||
235 | |||
236 | if (fe->ops.i2c_gate_ctrl) | ||
237 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
238 | |||
239 | val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) | | ||
240 | MC44S803_REG_SM(r1-1, MC44S803_R1) | | ||
241 | MC44S803_REG_SM(r2-1, MC44S803_R2) | | ||
242 | MC44S803_REG_SM(1, MC44S803_REFBUF_EN); | ||
243 | |||
244 | err = mc44s803_writereg(priv, val); | ||
245 | if (err) | ||
246 | goto exit; | ||
247 | |||
248 | val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) | | ||
249 | MC44S803_REG_SM(n1-2, MC44S803_LO1); | ||
250 | |||
251 | err = mc44s803_writereg(priv, val); | ||
252 | if (err) | ||
253 | goto exit; | ||
254 | |||
255 | val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) | | ||
256 | MC44S803_REG_SM(n2-2, MC44S803_LO2); | ||
257 | |||
258 | err = mc44s803_writereg(priv, val); | ||
259 | if (err) | ||
260 | goto exit; | ||
261 | |||
262 | val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | | ||
263 | MC44S803_REG_SM(1, MC44S803_DA) | | ||
264 | MC44S803_REG_SM(lo1, MC44S803_LO_REF) | | ||
265 | MC44S803_REG_SM(1, MC44S803_AT); | ||
266 | |||
267 | err = mc44s803_writereg(priv, val); | ||
268 | if (err) | ||
269 | goto exit; | ||
270 | |||
271 | val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) | | ||
272 | MC44S803_REG_SM(2, MC44S803_DA) | | ||
273 | MC44S803_REG_SM(lo2, MC44S803_LO_REF) | | ||
274 | MC44S803_REG_SM(1, MC44S803_AT); | ||
275 | |||
276 | err = mc44s803_writereg(priv, val); | ||
277 | if (err) | ||
278 | goto exit; | ||
279 | |||
280 | if (fe->ops.i2c_gate_ctrl) | ||
281 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
282 | |||
283 | return 0; | ||
284 | |||
285 | exit: | ||
286 | if (fe->ops.i2c_gate_ctrl) | ||
287 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
288 | |||
289 | mc_printk(KERN_WARNING, "I/O Error\n"); | ||
290 | return err; | ||
291 | } | ||
292 | |||
293 | static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||
294 | { | ||
295 | struct mc44s803_priv *priv = fe->tuner_priv; | ||
296 | *frequency = priv->frequency; | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static const struct dvb_tuner_ops mc44s803_tuner_ops = { | ||
301 | .info = { | ||
302 | .name = "Freescale MC44S803", | ||
303 | .frequency_min = 48000000, | ||
304 | .frequency_max = 1000000000, | ||
305 | .frequency_step = 100000, | ||
306 | }, | ||
307 | |||
308 | .release = mc44s803_release, | ||
309 | .init = mc44s803_init, | ||
310 | .set_params = mc44s803_set_params, | ||
311 | .get_frequency = mc44s803_get_frequency | ||
312 | }; | ||
313 | |||
314 | /* This functions tries to identify a MC44S803 tuner by reading the ID | ||
315 | register. This is hasty. */ | ||
316 | struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, | ||
317 | struct i2c_adapter *i2c, struct mc44s803_config *cfg) | ||
318 | { | ||
319 | struct mc44s803_priv *priv; | ||
320 | u32 reg; | ||
321 | u8 id; | ||
322 | int ret; | ||
323 | |||
324 | reg = 0; | ||
325 | |||
326 | priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL); | ||
327 | if (priv == NULL) | ||
328 | return NULL; | ||
329 | |||
330 | priv->cfg = cfg; | ||
331 | priv->i2c = i2c; | ||
332 | priv->fe = fe; | ||
333 | |||
334 | if (fe->ops.i2c_gate_ctrl) | ||
335 | fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */ | ||
336 | |||
337 | ret = mc44s803_readreg(priv, MC44S803_REG_ID, ®); | ||
338 | if (ret) | ||
339 | goto error; | ||
340 | |||
341 | id = MC44S803_REG_MS(reg, MC44S803_ID); | ||
342 | |||
343 | if (id != 0x14) { | ||
344 | mc_printk(KERN_ERR, "unsupported ID " | ||
345 | "(%x should be 0x14)\n", id); | ||
346 | goto error; | ||
347 | } | ||
348 | |||
349 | mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id); | ||
350 | memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops, | ||
351 | sizeof(struct dvb_tuner_ops)); | ||
352 | |||
353 | fe->tuner_priv = priv; | ||
354 | |||
355 | if (fe->ops.i2c_gate_ctrl) | ||
356 | fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ | ||
357 | |||
358 | return fe; | ||
359 | |||
360 | error: | ||
361 | if (fe->ops.i2c_gate_ctrl) | ||
362 | fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */ | ||
363 | |||
364 | kfree(priv); | ||
365 | return NULL; | ||
366 | } | ||
367 | EXPORT_SYMBOL(mc44s803_attach); | ||
368 | |||
369 | MODULE_AUTHOR("Jochen Friedrich"); | ||
370 | MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver"); | ||
371 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/common/tuners/mc44s803.h b/drivers/media/common/tuners/mc44s803.h new file mode 100644 index 000000000000..34f3892d3f6d --- /dev/null +++ b/drivers/media/common/tuners/mc44s803.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner | ||
3 | * | ||
4 | * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
20 | */ | ||
21 | |||
22 | #ifndef MC44S803_H | ||
23 | #define MC44S803_H | ||
24 | |||
25 | struct dvb_frontend; | ||
26 | struct i2c_adapter; | ||
27 | |||
28 | struct mc44s803_config { | ||
29 | u8 i2c_address; | ||
30 | u8 dig_out; | ||
31 | }; | ||
32 | |||
33 | #if defined(CONFIG_MEDIA_TUNER_MC44S803) || \ | ||
34 | (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE)) | ||
35 | extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, | ||
36 | struct i2c_adapter *i2c, struct mc44s803_config *cfg); | ||
37 | #else | ||
38 | static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, | ||
39 | struct i2c_adapter *i2c, struct mc44s803_config *cfg) | ||
40 | { | ||
41 | printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||
42 | return NULL; | ||
43 | } | ||
44 | #endif /* CONFIG_MEDIA_TUNER_MC44S803 */ | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/media/common/tuners/mc44s803_priv.h b/drivers/media/common/tuners/mc44s803_priv.h new file mode 100644 index 000000000000..14a92780906d --- /dev/null +++ b/drivers/media/common/tuners/mc44s803_priv.h | |||
@@ -0,0 +1,208 @@ | |||
1 | /* | ||
2 | * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner | ||
3 | * | ||
4 | * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= | ||
20 | */ | ||
21 | |||
22 | #ifndef MC44S803_PRIV_H | ||
23 | #define MC44S803_PRIV_H | ||
24 | |||
25 | /* This driver is based on the information available in the datasheet | ||
26 | http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf | ||
27 | |||
28 | SPI or I2C Address : 0xc0-0xc6 | ||
29 | |||
30 | Reg.No | Function | ||
31 | ------------------------------------------- | ||
32 | 00 | Power Down | ||
33 | 01 | Reference Oszillator | ||
34 | 02 | Reference Dividers | ||
35 | 03 | Mixer and Reference Buffer | ||
36 | 04 | Reset/Serial Out | ||
37 | 05 | LO 1 | ||
38 | 06 | LO 2 | ||
39 | 07 | Circuit Adjust | ||
40 | 08 | Test | ||
41 | 09 | Digital Tune | ||
42 | 0A | LNA AGC | ||
43 | 0B | Data Register Address | ||
44 | 0C | Regulator Test | ||
45 | 0D | VCO Test | ||
46 | 0E | LNA Gain/Input Power | ||
47 | 0F | ID Bits | ||
48 | |||
49 | */ | ||
50 | |||
51 | #define MC44S803_OSC 26000000 /* 26 MHz */ | ||
52 | #define MC44S803_IF1 1086000000 /* 1086 MHz */ | ||
53 | #define MC44S803_IF2 36125000 /* 36.125 MHz */ | ||
54 | |||
55 | #define MC44S803_REG_POWER 0 | ||
56 | #define MC44S803_REG_REFOSC 1 | ||
57 | #define MC44S803_REG_REFDIV 2 | ||
58 | #define MC44S803_REG_MIXER 3 | ||
59 | #define MC44S803_REG_RESET 4 | ||
60 | #define MC44S803_REG_LO1 5 | ||
61 | #define MC44S803_REG_LO2 6 | ||
62 | #define MC44S803_REG_CIRCADJ 7 | ||
63 | #define MC44S803_REG_TEST 8 | ||
64 | #define MC44S803_REG_DIGTUNE 9 | ||
65 | #define MC44S803_REG_LNAAGC 0x0A | ||
66 | #define MC44S803_REG_DATAREG 0x0B | ||
67 | #define MC44S803_REG_REGTEST 0x0C | ||
68 | #define MC44S803_REG_VCOTEST 0x0D | ||
69 | #define MC44S803_REG_LNAGAIN 0x0E | ||
70 | #define MC44S803_REG_ID 0x0F | ||
71 | |||
72 | /* Register definitions */ | ||
73 | #define MC44S803_ADDR 0x0F | ||
74 | #define MC44S803_ADDR_S 0 | ||
75 | /* REG_POWER */ | ||
76 | #define MC44S803_POWER 0xFFFFF0 | ||
77 | #define MC44S803_POWER_S 4 | ||
78 | /* REG_REFOSC */ | ||
79 | #define MC44S803_REFOSC 0x1FF0 | ||
80 | #define MC44S803_REFOSC_S 4 | ||
81 | #define MC44S803_OSCSEL 0x2000 | ||
82 | #define MC44S803_OSCSEL_S 13 | ||
83 | /* REG_REFDIV */ | ||
84 | #define MC44S803_R2 0x1FF0 | ||
85 | #define MC44S803_R2_S 4 | ||
86 | #define MC44S803_REFBUF_EN 0x2000 | ||
87 | #define MC44S803_REFBUF_EN_S 13 | ||
88 | #define MC44S803_R1 0x7C000 | ||
89 | #define MC44S803_R1_S 14 | ||
90 | /* REG_MIXER */ | ||
91 | #define MC44S803_R3 0x70 | ||
92 | #define MC44S803_R3_S 4 | ||
93 | #define MC44S803_MUX3 0x80 | ||
94 | #define MC44S803_MUX3_S 7 | ||
95 | #define MC44S803_MUX4 0x100 | ||
96 | #define MC44S803_MUX4_S 8 | ||
97 | #define MC44S803_OSC_SCR 0x200 | ||
98 | #define MC44S803_OSC_SCR_S 9 | ||
99 | #define MC44S803_TRI_STATE 0x400 | ||
100 | #define MC44S803_TRI_STATE_S 10 | ||
101 | #define MC44S803_BUF_GAIN 0x800 | ||
102 | #define MC44S803_BUF_GAIN_S 11 | ||
103 | #define MC44S803_BUF_IO 0x1000 | ||
104 | #define MC44S803_BUF_IO_S 12 | ||
105 | #define MC44S803_MIXER_RES 0xFE000 | ||
106 | #define MC44S803_MIXER_RES_S 13 | ||
107 | /* REG_RESET */ | ||
108 | #define MC44S803_RS 0x10 | ||
109 | #define MC44S803_RS_S 4 | ||
110 | #define MC44S803_SO 0x20 | ||
111 | #define MC44S803_SO_S 5 | ||
112 | /* REG_LO1 */ | ||
113 | #define MC44S803_LO1 0xFFF0 | ||
114 | #define MC44S803_LO1_S 4 | ||
115 | /* REG_LO2 */ | ||
116 | #define MC44S803_LO2 0x7FFF0 | ||
117 | #define MC44S803_LO2_S 4 | ||
118 | /* REG_CIRCADJ */ | ||
119 | #define MC44S803_G1 0x20 | ||
120 | #define MC44S803_G1_S 5 | ||
121 | #define MC44S803_G3 0x80 | ||
122 | #define MC44S803_G3_S 7 | ||
123 | #define MC44S803_CIRCADJ_RES 0x300 | ||
124 | #define MC44S803_CIRCADJ_RES_S 8 | ||
125 | #define MC44S803_G6 0x400 | ||
126 | #define MC44S803_G6_S 10 | ||
127 | #define MC44S803_G7 0x800 | ||
128 | #define MC44S803_G7_S 11 | ||
129 | #define MC44S803_S1 0x1000 | ||
130 | #define MC44S803_S1_S 12 | ||
131 | #define MC44S803_LP 0x7E000 | ||
132 | #define MC44S803_LP_S 13 | ||
133 | #define MC44S803_CLRF 0x80000 | ||
134 | #define MC44S803_CLRF_S 19 | ||
135 | #define MC44S803_CLIF 0x100000 | ||
136 | #define MC44S803_CLIF_S 20 | ||
137 | /* REG_TEST */ | ||
138 | /* REG_DIGTUNE */ | ||
139 | #define MC44S803_DA 0xF0 | ||
140 | #define MC44S803_DA_S 4 | ||
141 | #define MC44S803_XOD 0x300 | ||
142 | #define MC44S803_XOD_S 8 | ||
143 | #define MC44S803_RST 0x10000 | ||
144 | #define MC44S803_RST_S 16 | ||
145 | #define MC44S803_LO_REF 0x1FFF00 | ||
146 | #define MC44S803_LO_REF_S 8 | ||
147 | #define MC44S803_AT 0x200000 | ||
148 | #define MC44S803_AT_S 21 | ||
149 | #define MC44S803_MT 0x400000 | ||
150 | #define MC44S803_MT_S 22 | ||
151 | /* REG_LNAAGC */ | ||
152 | #define MC44S803_G 0x3F0 | ||
153 | #define MC44S803_G_S 4 | ||
154 | #define MC44S803_AT1 0x400 | ||
155 | #define MC44S803_AT1_S 10 | ||
156 | #define MC44S803_AT2 0x800 | ||
157 | #define MC44S803_AT2_S 11 | ||
158 | #define MC44S803_HL_GR_EN 0x8000 | ||
159 | #define MC44S803_HL_GR_EN_S 15 | ||
160 | #define MC44S803_AGC_AN_DIG 0x10000 | ||
161 | #define MC44S803_AGC_AN_DIG_S 16 | ||
162 | #define MC44S803_ATTEN_EN 0x20000 | ||
163 | #define MC44S803_ATTEN_EN_S 17 | ||
164 | #define MC44S803_AGC_READ_EN 0x40000 | ||
165 | #define MC44S803_AGC_READ_EN_S 18 | ||
166 | #define MC44S803_LNA0 0x80000 | ||
167 | #define MC44S803_LNA0_S 19 | ||
168 | #define MC44S803_AGC_SEL 0x100000 | ||
169 | #define MC44S803_AGC_SEL_S 20 | ||
170 | #define MC44S803_AT0 0x200000 | ||
171 | #define MC44S803_AT0_S 21 | ||
172 | #define MC44S803_B 0xC00000 | ||
173 | #define MC44S803_B_S 22 | ||
174 | /* REG_DATAREG */ | ||
175 | #define MC44S803_D 0xF0 | ||
176 | #define MC44S803_D_S 4 | ||
177 | /* REG_REGTEST */ | ||
178 | /* REG_VCOTEST */ | ||
179 | /* REG_LNAGAIN */ | ||
180 | #define MC44S803_IF_PWR 0x700 | ||
181 | #define MC44S803_IF_PWR_S 8 | ||
182 | #define MC44S803_RF_PWR 0x3800 | ||
183 | #define MC44S803_RF_PWR_S 11 | ||
184 | #define MC44S803_LNA_GAIN 0xFC000 | ||
185 | #define MC44S803_LNA_GAIN_S 14 | ||
186 | /* REG_ID */ | ||
187 | #define MC44S803_ID 0x3E00 | ||
188 | #define MC44S803_ID_S 9 | ||
189 | |||
190 | /* Some macros to read/write fields */ | ||
191 | |||
192 | /* First shift, then mask */ | ||
193 | #define MC44S803_REG_SM(_val, _reg) \ | ||
194 | (((_val) << _reg##_S) & (_reg)) | ||
195 | |||
196 | /* First mask, then shift */ | ||
197 | #define MC44S803_REG_MS(_val, _reg) \ | ||
198 | (((_val) & (_reg)) >> _reg##_S) | ||
199 | |||
200 | struct mc44s803_priv { | ||
201 | struct mc44s803_config *cfg; | ||
202 | struct i2c_adapter *i2c; | ||
203 | struct dvb_frontend *fe; | ||
204 | |||
205 | u32 frequency; | ||
206 | }; | ||
207 | |||
208 | #endif | ||
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c index 12206d75dd4e..c7abe3d8f90e 100644 --- a/drivers/media/common/tuners/mt2060.c +++ b/drivers/media/common/tuners/mt2060.c | |||
@@ -278,7 +278,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv) | |||
278 | while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0) | 278 | while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0) |
279 | msleep(20); | 279 | msleep(20); |
280 | 280 | ||
281 | if (i < 10) { | 281 | if (i <= 10) { |
282 | mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :) | 282 | mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :) |
283 | dprintk("calibration was successful: %d", (int)priv->fmfreq); | 283 | dprintk("calibration was successful: %d", (int)priv->fmfreq); |
284 | } else | 284 | } else |
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c index 35b763a16d53..44608ad4e2d2 100644 --- a/drivers/media/common/tuners/mt20xx.c +++ b/drivers/media/common/tuners/mt20xx.c | |||
@@ -6,7 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
8 | #include <linux/i2c.h> | 8 | #include <linux/i2c.h> |
9 | #include <linux/videodev.h> | 9 | #include <linux/videodev2.h> |
10 | #include "tuner-i2c.h" | 10 | #include "tuner-i2c.h" |
11 | #include "mt20xx.h" | 11 | #include "mt20xx.h" |
12 | 12 | ||
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c index 31522d2e318e..0803dab58fff 100644 --- a/drivers/media/common/tuners/mxl5005s.c +++ b/drivers/media/common/tuners/mxl5005s.c | |||
@@ -4003,12 +4003,11 @@ static int mxl5005s_set_params(struct dvb_frontend *fe, | |||
4003 | /* Change tuner for new modulation type if reqd */ | 4003 | /* Change tuner for new modulation type if reqd */ |
4004 | if (req_mode != state->current_mode) { | 4004 | if (req_mode != state->current_mode) { |
4005 | switch (req_mode) { | 4005 | switch (req_mode) { |
4006 | case VSB_8: | 4006 | case MXL_ATSC: |
4007 | case QAM_64: | 4007 | case MXL_QAM: |
4008 | case QAM_256: | ||
4009 | case QAM_AUTO: | ||
4010 | req_bw = MXL5005S_BANDWIDTH_6MHZ; | 4008 | req_bw = MXL5005S_BANDWIDTH_6MHZ; |
4011 | break; | 4009 | break; |
4010 | case MXL_DVBT: | ||
4012 | default: | 4011 | default: |
4013 | /* Assume DVB-T */ | 4012 | /* Assume DVB-T */ |
4014 | switch (params->u.ofdm.bandwidth) { | 4013 | switch (params->u.ofdm.bandwidth) { |
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c index 3ec28945c26f..2d02698d4f4f 100644 --- a/drivers/media/common/tuners/mxl5007t.c +++ b/drivers/media/common/tuners/mxl5007t.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner | 2 | * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org> | 4 | * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -66,22 +66,17 @@ MODULE_PARM_DESC(debug, "set debug level"); | |||
66 | #define MHz 1000000 | 66 | #define MHz 1000000 |
67 | 67 | ||
68 | enum mxl5007t_mode { | 68 | enum mxl5007t_mode { |
69 | MxL_MODE_OTA_DVBT_ATSC = 0, | 69 | MxL_MODE_ISDBT = 0, |
70 | MxL_MODE_OTA_NTSC_PAL_GH = 1, | 70 | MxL_MODE_DVBT = 1, |
71 | MxL_MODE_OTA_PAL_IB = 2, | 71 | MxL_MODE_ATSC = 2, |
72 | MxL_MODE_OTA_PAL_D_SECAM_KL = 3, | 72 | MxL_MODE_CABLE = 0x10, |
73 | MxL_MODE_OTA_ISDBT = 4, | ||
74 | MxL_MODE_CABLE_DIGITAL = 0x10, | ||
75 | MxL_MODE_CABLE_NTSC_PAL_GH = 0x11, | ||
76 | MxL_MODE_CABLE_PAL_IB = 0x12, | ||
77 | MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13, | ||
78 | MxL_MODE_CABLE_SCTE40 = 0x14, | ||
79 | }; | 73 | }; |
80 | 74 | ||
81 | enum mxl5007t_chip_version { | 75 | enum mxl5007t_chip_version { |
82 | MxL_UNKNOWN_ID = 0x00, | 76 | MxL_UNKNOWN_ID = 0x00, |
83 | MxL_5007_V1_F1 = 0x11, | 77 | MxL_5007_V1_F1 = 0x11, |
84 | MxL_5007_V1_F2 = 0x12, | 78 | MxL_5007_V1_F2 = 0x12, |
79 | MxL_5007_V4 = 0x14, | ||
85 | MxL_5007_V2_100_F1 = 0x21, | 80 | MxL_5007_V2_100_F1 = 0x21, |
86 | MxL_5007_V2_100_F2 = 0x22, | 81 | MxL_5007_V2_100_F2 = 0x22, |
87 | MxL_5007_V2_200_F1 = 0x23, | 82 | MxL_5007_V2_200_F1 = 0x23, |
@@ -96,67 +91,61 @@ struct reg_pair_t { | |||
96 | /* ------------------------------------------------------------------------- */ | 91 | /* ------------------------------------------------------------------------- */ |
97 | 92 | ||
98 | static struct reg_pair_t init_tab[] = { | 93 | static struct reg_pair_t init_tab[] = { |
99 | { 0x0b, 0x44 }, /* XTAL */ | 94 | { 0x02, 0x06 }, |
100 | { 0x0c, 0x60 }, /* IF */ | 95 | { 0x03, 0x48 }, |
101 | { 0x10, 0x00 }, /* MISC */ | 96 | { 0x05, 0x04 }, |
102 | { 0x12, 0xca }, /* IDAC */ | 97 | { 0x06, 0x10 }, |
103 | { 0x16, 0x90 }, /* MODE */ | 98 | { 0x2e, 0x15 }, /* OVERRIDE */ |
104 | { 0x32, 0x38 }, /* MODE Analog/Digital */ | 99 | { 0x30, 0x10 }, /* OVERRIDE */ |
105 | { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ | 100 | { 0x45, 0x58 }, /* OVERRIDE */ |
106 | { 0x2c, 0x34 }, /* OVERRIDE */ | 101 | { 0x48, 0x19 }, /* OVERRIDE */ |
107 | { 0x4d, 0x40 }, /* OVERRIDE */ | 102 | { 0x52, 0x03 }, /* OVERRIDE */ |
108 | { 0x7f, 0x02 }, /* OVERRIDE */ | 103 | { 0x53, 0x44 }, /* OVERRIDE */ |
109 | { 0x9a, 0x52 }, /* OVERRIDE */ | 104 | { 0x6a, 0x4b }, /* OVERRIDE */ |
110 | { 0x48, 0x5a }, /* OVERRIDE */ | 105 | { 0x76, 0x00 }, /* OVERRIDE */ |
111 | { 0x76, 0x1a }, /* OVERRIDE */ | 106 | { 0x78, 0x18 }, /* OVERRIDE */ |
112 | { 0x6a, 0x48 }, /* OVERRIDE */ | 107 | { 0x7a, 0x17 }, /* OVERRIDE */ |
113 | { 0x64, 0x28 }, /* OVERRIDE */ | 108 | { 0x85, 0x06 }, /* OVERRIDE */ |
114 | { 0x66, 0xe6 }, /* OVERRIDE */ | 109 | { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */ |
115 | { 0x35, 0x0e }, /* OVERRIDE */ | ||
116 | { 0x7e, 0x01 }, /* OVERRIDE */ | ||
117 | { 0x83, 0x00 }, /* OVERRIDE */ | ||
118 | { 0x04, 0x0b }, /* OVERRIDE */ | ||
119 | { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ | ||
120 | { 0, 0 } | 110 | { 0, 0 } |
121 | }; | 111 | }; |
122 | 112 | ||
123 | static struct reg_pair_t init_tab_cable[] = { | 113 | static struct reg_pair_t init_tab_cable[] = { |
124 | { 0x0b, 0x44 }, /* XTAL */ | 114 | { 0x02, 0x06 }, |
125 | { 0x0c, 0x60 }, /* IF */ | 115 | { 0x03, 0x48 }, |
126 | { 0x10, 0x00 }, /* MISC */ | 116 | { 0x05, 0x04 }, |
127 | { 0x12, 0xca }, /* IDAC */ | 117 | { 0x06, 0x10 }, |
128 | { 0x16, 0x90 }, /* MODE */ | 118 | { 0x09, 0x3f }, |
129 | { 0x32, 0x38 }, /* MODE A/D */ | 119 | { 0x0a, 0x3f }, |
130 | { 0x71, 0x3f }, /* TOP1 */ | 120 | { 0x0b, 0x3f }, |
131 | { 0x72, 0x3f }, /* TOP2 */ | 121 | { 0x2e, 0x15 }, /* OVERRIDE */ |
132 | { 0x74, 0x3f }, /* TOP3 */ | 122 | { 0x30, 0x10 }, /* OVERRIDE */ |
133 | { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */ | 123 | { 0x45, 0x58 }, /* OVERRIDE */ |
134 | { 0x2c, 0x34 }, /* OVERRIDE */ | 124 | { 0x48, 0x19 }, /* OVERRIDE */ |
135 | { 0x4d, 0x40 }, /* OVERRIDE */ | 125 | { 0x52, 0x03 }, /* OVERRIDE */ |
136 | { 0x7f, 0x02 }, /* OVERRIDE */ | 126 | { 0x53, 0x44 }, /* OVERRIDE */ |
137 | { 0x9a, 0x52 }, /* OVERRIDE */ | 127 | { 0x6a, 0x4b }, /* OVERRIDE */ |
138 | { 0x48, 0x5a }, /* OVERRIDE */ | 128 | { 0x76, 0x00 }, /* OVERRIDE */ |
139 | { 0x76, 0x1a }, /* OVERRIDE */ | 129 | { 0x78, 0x18 }, /* OVERRIDE */ |
140 | { 0x6a, 0x48 }, /* OVERRIDE */ | 130 | { 0x7a, 0x17 }, /* OVERRIDE */ |
141 | { 0x64, 0x28 }, /* OVERRIDE */ | 131 | { 0x85, 0x06 }, /* OVERRIDE */ |
142 | { 0x66, 0xe6 }, /* OVERRIDE */ | 132 | { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */ |
143 | { 0x35, 0x0e }, /* OVERRIDE */ | ||
144 | { 0x7e, 0x01 }, /* OVERRIDE */ | ||
145 | { 0x04, 0x0b }, /* OVERRIDE */ | ||
146 | { 0x68, 0xb4 }, /* OVERRIDE */ | ||
147 | { 0x36, 0x00 }, /* OVERRIDE */ | ||
148 | { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */ | ||
149 | { 0, 0 } | 133 | { 0, 0 } |
150 | }; | 134 | }; |
151 | 135 | ||
152 | /* ------------------------------------------------------------------------- */ | 136 | /* ------------------------------------------------------------------------- */ |
153 | 137 | ||
154 | static struct reg_pair_t reg_pair_rftune[] = { | 138 | static struct reg_pair_t reg_pair_rftune[] = { |
155 | { 0x11, 0x00 }, /* abort tune */ | 139 | { 0x0f, 0x00 }, /* abort tune */ |
156 | { 0x13, 0x15 }, | 140 | { 0x0c, 0x15 }, |
157 | { 0x14, 0x40 }, | 141 | { 0x0d, 0x40 }, |
158 | { 0x15, 0x0e }, | 142 | { 0x0e, 0x0e }, |
159 | { 0x11, 0x02 }, /* start tune */ | 143 | { 0x1f, 0x87 }, /* OVERRIDE */ |
144 | { 0x20, 0x1f }, /* OVERRIDE */ | ||
145 | { 0x21, 0x87 }, /* OVERRIDE */ | ||
146 | { 0x22, 0x1f }, /* OVERRIDE */ | ||
147 | { 0x80, 0x01 }, /* freq dependent */ | ||
148 | { 0x0f, 0x01 }, /* start tune */ | ||
160 | { 0, 0 } | 149 | { 0, 0 } |
161 | }; | 150 | }; |
162 | 151 | ||
@@ -227,63 +216,20 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state, | |||
227 | s32 if_diff_out_level) | 216 | s32 if_diff_out_level) |
228 | { | 217 | { |
229 | switch (mode) { | 218 | switch (mode) { |
230 | case MxL_MODE_OTA_DVBT_ATSC: | 219 | case MxL_MODE_ATSC: |
231 | set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); | 220 | set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12); |
232 | set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e); | ||
233 | break; | 221 | break; |
234 | case MxL_MODE_OTA_ISDBT: | 222 | case MxL_MODE_DVBT: |
235 | set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06); | 223 | set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11); |
236 | set_reg_bits(state->tab_init, 0x35, 0xff, 0x12); | ||
237 | break; | 224 | break; |
238 | case MxL_MODE_OTA_NTSC_PAL_GH: | 225 | case MxL_MODE_ISDBT: |
239 | set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); | 226 | set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10); |
240 | set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); | ||
241 | break; | 227 | break; |
242 | case MxL_MODE_OTA_PAL_IB: | 228 | case MxL_MODE_CABLE: |
243 | set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); | 229 | set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1); |
244 | set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); | 230 | set_reg_bits(state->tab_init_cable, 0x0a, 0xff, |
245 | break; | ||
246 | case MxL_MODE_OTA_PAL_D_SECAM_KL: | ||
247 | set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); | ||
248 | set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); | ||
249 | break; | ||
250 | case MxL_MODE_CABLE_DIGITAL: | ||
251 | set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); | ||
252 | set_reg_bits(state->tab_init_cable, 0x72, 0xff, | ||
253 | 8 - if_diff_out_level); | ||
254 | set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); | ||
255 | break; | ||
256 | case MxL_MODE_CABLE_NTSC_PAL_GH: | ||
257 | set_reg_bits(state->tab_init, 0x16, 0x70, 0x00); | ||
258 | set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); | ||
259 | set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); | ||
260 | set_reg_bits(state->tab_init_cable, 0x72, 0xff, | ||
261 | 8 - if_diff_out_level); | ||
262 | set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); | ||
263 | break; | ||
264 | case MxL_MODE_CABLE_PAL_IB: | ||
265 | set_reg_bits(state->tab_init, 0x16, 0x70, 0x10); | ||
266 | set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); | ||
267 | set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); | ||
268 | set_reg_bits(state->tab_init_cable, 0x72, 0xff, | ||
269 | 8 - if_diff_out_level); | 231 | 8 - if_diff_out_level); |
270 | set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); | 232 | set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17); |
271 | break; | ||
272 | case MxL_MODE_CABLE_PAL_D_SECAM_KL: | ||
273 | set_reg_bits(state->tab_init, 0x16, 0x70, 0x20); | ||
274 | set_reg_bits(state->tab_init, 0x32, 0xff, 0x85); | ||
275 | set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); | ||
276 | set_reg_bits(state->tab_init_cable, 0x72, 0xff, | ||
277 | 8 - if_diff_out_level); | ||
278 | set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); | ||
279 | break; | ||
280 | case MxL_MODE_CABLE_SCTE40: | ||
281 | set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08); | ||
282 | set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc); | ||
283 | set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01); | ||
284 | set_reg_bits(state->tab_init_cable, 0x72, 0xff, | ||
285 | 8 - if_diff_out_level); | ||
286 | set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17); | ||
287 | break; | 233 | break; |
288 | default: | 234 | default: |
289 | mxl_fail(-EINVAL); | 235 | mxl_fail(-EINVAL); |
@@ -302,43 +248,43 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, | |||
302 | val = 0x00; | 248 | val = 0x00; |
303 | break; | 249 | break; |
304 | case MxL_IF_4_5_MHZ: | 250 | case MxL_IF_4_5_MHZ: |
305 | val = 0x20; | 251 | val = 0x02; |
306 | break; | 252 | break; |
307 | case MxL_IF_4_57_MHZ: | 253 | case MxL_IF_4_57_MHZ: |
308 | val = 0x30; | 254 | val = 0x03; |
309 | break; | 255 | break; |
310 | case MxL_IF_5_MHZ: | 256 | case MxL_IF_5_MHZ: |
311 | val = 0x40; | 257 | val = 0x04; |
312 | break; | 258 | break; |
313 | case MxL_IF_5_38_MHZ: | 259 | case MxL_IF_5_38_MHZ: |
314 | val = 0x50; | 260 | val = 0x05; |
315 | break; | 261 | break; |
316 | case MxL_IF_6_MHZ: | 262 | case MxL_IF_6_MHZ: |
317 | val = 0x60; | 263 | val = 0x06; |
318 | break; | 264 | break; |
319 | case MxL_IF_6_28_MHZ: | 265 | case MxL_IF_6_28_MHZ: |
320 | val = 0x70; | 266 | val = 0x07; |
321 | break; | 267 | break; |
322 | case MxL_IF_9_1915_MHZ: | 268 | case MxL_IF_9_1915_MHZ: |
323 | val = 0x80; | 269 | val = 0x08; |
324 | break; | 270 | break; |
325 | case MxL_IF_35_25_MHZ: | 271 | case MxL_IF_35_25_MHZ: |
326 | val = 0x90; | 272 | val = 0x09; |
327 | break; | 273 | break; |
328 | case MxL_IF_36_15_MHZ: | 274 | case MxL_IF_36_15_MHZ: |
329 | val = 0xa0; | 275 | val = 0x0a; |
330 | break; | 276 | break; |
331 | case MxL_IF_44_MHZ: | 277 | case MxL_IF_44_MHZ: |
332 | val = 0xb0; | 278 | val = 0x0b; |
333 | break; | 279 | break; |
334 | default: | 280 | default: |
335 | mxl_fail(-EINVAL); | 281 | mxl_fail(-EINVAL); |
336 | return; | 282 | return; |
337 | } | 283 | } |
338 | set_reg_bits(state->tab_init, 0x0c, 0xf0, val); | 284 | set_reg_bits(state->tab_init, 0x02, 0x0f, val); |
339 | 285 | ||
340 | /* set inverted IF or normal IF */ | 286 | /* set inverted IF or normal IF */ |
341 | set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00); | 287 | set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00); |
342 | 288 | ||
343 | return; | 289 | return; |
344 | } | 290 | } |
@@ -346,56 +292,68 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state, | |||
346 | static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state, | 292 | static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state, |
347 | enum mxl5007t_xtal_freq xtal_freq) | 293 | enum mxl5007t_xtal_freq xtal_freq) |
348 | { | 294 | { |
349 | u8 val; | ||
350 | |||
351 | switch (xtal_freq) { | 295 | switch (xtal_freq) { |
352 | case MxL_XTAL_16_MHZ: | 296 | case MxL_XTAL_16_MHZ: |
353 | val = 0x00; /* select xtal freq & Ref Freq */ | 297 | /* select xtal freq & ref freq */ |
298 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00); | ||
299 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00); | ||
354 | break; | 300 | break; |
355 | case MxL_XTAL_20_MHZ: | 301 | case MxL_XTAL_20_MHZ: |
356 | val = 0x11; | 302 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10); |
303 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01); | ||
357 | break; | 304 | break; |
358 | case MxL_XTAL_20_25_MHZ: | 305 | case MxL_XTAL_20_25_MHZ: |
359 | val = 0x22; | 306 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20); |
307 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02); | ||
360 | break; | 308 | break; |
361 | case MxL_XTAL_20_48_MHZ: | 309 | case MxL_XTAL_20_48_MHZ: |
362 | val = 0x33; | 310 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30); |
311 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03); | ||
363 | break; | 312 | break; |
364 | case MxL_XTAL_24_MHZ: | 313 | case MxL_XTAL_24_MHZ: |
365 | val = 0x44; | 314 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40); |
315 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04); | ||
366 | break; | 316 | break; |
367 | case MxL_XTAL_25_MHZ: | 317 | case MxL_XTAL_25_MHZ: |
368 | val = 0x55; | 318 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50); |
319 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05); | ||
369 | break; | 320 | break; |
370 | case MxL_XTAL_25_14_MHZ: | 321 | case MxL_XTAL_25_14_MHZ: |
371 | val = 0x66; | 322 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60); |
323 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06); | ||
372 | break; | 324 | break; |
373 | case MxL_XTAL_27_MHZ: | 325 | case MxL_XTAL_27_MHZ: |
374 | val = 0x77; | 326 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70); |
327 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07); | ||
375 | break; | 328 | break; |
376 | case MxL_XTAL_28_8_MHZ: | 329 | case MxL_XTAL_28_8_MHZ: |
377 | val = 0x88; | 330 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80); |
331 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08); | ||
378 | break; | 332 | break; |
379 | case MxL_XTAL_32_MHZ: | 333 | case MxL_XTAL_32_MHZ: |
380 | val = 0x99; | 334 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90); |
335 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09); | ||
381 | break; | 336 | break; |
382 | case MxL_XTAL_40_MHZ: | 337 | case MxL_XTAL_40_MHZ: |
383 | val = 0xaa; | 338 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0); |
339 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a); | ||
384 | break; | 340 | break; |
385 | case MxL_XTAL_44_MHZ: | 341 | case MxL_XTAL_44_MHZ: |
386 | val = 0xbb; | 342 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0); |
343 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b); | ||
387 | break; | 344 | break; |
388 | case MxL_XTAL_48_MHZ: | 345 | case MxL_XTAL_48_MHZ: |
389 | val = 0xcc; | 346 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0); |
347 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c); | ||
390 | break; | 348 | break; |
391 | case MxL_XTAL_49_3811_MHZ: | 349 | case MxL_XTAL_49_3811_MHZ: |
392 | val = 0xdd; | 350 | set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0); |
351 | set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d); | ||
393 | break; | 352 | break; |
394 | default: | 353 | default: |
395 | mxl_fail(-EINVAL); | 354 | mxl_fail(-EINVAL); |
396 | return; | 355 | return; |
397 | } | 356 | } |
398 | set_reg_bits(state->tab_init, 0x0b, 0xff, val); | ||
399 | 357 | ||
400 | return; | 358 | return; |
401 | } | 359 | } |
@@ -412,16 +370,11 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state, | |||
412 | mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); | 370 | mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if); |
413 | mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); | 371 | mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz); |
414 | 372 | ||
415 | set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6); | 373 | set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable); |
416 | 374 | set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3); | |
417 | set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3); | 375 | set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp); |
418 | |||
419 | set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp); | ||
420 | 376 | ||
421 | /* set IDAC to automatic mode control by AGC */ | 377 | if (mode >= MxL_MODE_CABLE) { |
422 | set_reg_bits(state->tab_init, 0x12, 0x80, 0x00); | ||
423 | |||
424 | if (mode >= MxL_MODE_CABLE_DIGITAL) { | ||
425 | copy_reg_bits(state->tab_init, state->tab_init_cable); | 378 | copy_reg_bits(state->tab_init, state->tab_init_cable); |
426 | return state->tab_init_cable; | 379 | return state->tab_init_cable; |
427 | } else | 380 | } else |
@@ -447,7 +400,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, | |||
447 | * and DIG_MODEINDEX_CSF */ | 400 | * and DIG_MODEINDEX_CSF */ |
448 | break; | 401 | break; |
449 | case MxL_BW_7MHz: | 402 | case MxL_BW_7MHz: |
450 | val = 0x21; | 403 | val = 0x2a; |
451 | break; | 404 | break; |
452 | case MxL_BW_8MHz: | 405 | case MxL_BW_8MHz: |
453 | val = 0x3f; | 406 | val = 0x3f; |
@@ -456,7 +409,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state, | |||
456 | mxl_fail(-EINVAL); | 409 | mxl_fail(-EINVAL); |
457 | return; | 410 | return; |
458 | } | 411 | } |
459 | set_reg_bits(state->tab_rftune, 0x13, 0x3f, val); | 412 | set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val); |
460 | 413 | ||
461 | return; | 414 | return; |
462 | } | 415 | } |
@@ -493,8 +446,11 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state, | |||
493 | if (temp > 7812) | 446 | if (temp > 7812) |
494 | dig_rf_freq++; | 447 | dig_rf_freq++; |
495 | 448 | ||
496 | set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq); | 449 | set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq); |
497 | set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8)); | 450 | set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8)); |
451 | |||
452 | if (rf_freq >= 333000000) | ||
453 | set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40); | ||
498 | 454 | ||
499 | return state->tab_rftune; | 455 | return state->tab_rftune; |
500 | } | 456 | } |
@@ -551,9 +507,10 @@ static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val) | |||
551 | static int mxl5007t_soft_reset(struct mxl5007t_state *state) | 507 | static int mxl5007t_soft_reset(struct mxl5007t_state *state) |
552 | { | 508 | { |
553 | u8 d = 0xff; | 509 | u8 d = 0xff; |
554 | struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0, | 510 | struct i2c_msg msg = { |
555 | .buf = &d, .len = 1 }; | 511 | .addr = state->i2c_props.addr, .flags = 0, |
556 | 512 | .buf = &d, .len = 1 | |
513 | }; | ||
557 | int ret = i2c_transfer(state->i2c_props.adap, &msg, 1); | 514 | int ret = i2c_transfer(state->i2c_props.adap, &msg, 1); |
558 | 515 | ||
559 | if (ret != 1) { | 516 | if (ret != 1) { |
@@ -580,9 +537,6 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state, | |||
580 | if (mxl_fail(ret)) | 537 | if (mxl_fail(ret)) |
581 | goto fail; | 538 | goto fail; |
582 | mdelay(1); | 539 | mdelay(1); |
583 | |||
584 | ret = mxl5007t_write_reg(state, 0x2c, 0x35); | ||
585 | mxl_fail(ret); | ||
586 | fail: | 540 | fail: |
587 | return ret; | 541 | return ret; |
588 | } | 542 | } |
@@ -615,7 +569,7 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state, | |||
615 | *rf_locked = 0; | 569 | *rf_locked = 0; |
616 | *ref_locked = 0; | 570 | *ref_locked = 0; |
617 | 571 | ||
618 | ret = mxl5007t_read_reg(state, 0xcf, &d); | 572 | ret = mxl5007t_read_reg(state, 0xd8, &d); |
619 | if (mxl_fail(ret)) | 573 | if (mxl_fail(ret)) |
620 | goto fail; | 574 | goto fail; |
621 | 575 | ||
@@ -628,37 +582,14 @@ fail: | |||
628 | return ret; | 582 | return ret; |
629 | } | 583 | } |
630 | 584 | ||
631 | static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state, | ||
632 | s32 *rf_input_level) | ||
633 | { | ||
634 | u8 d1, d2; | ||
635 | int ret; | ||
636 | |||
637 | ret = mxl5007t_read_reg(state, 0xb7, &d1); | ||
638 | if (mxl_fail(ret)) | ||
639 | goto fail; | ||
640 | |||
641 | ret = mxl5007t_read_reg(state, 0xbf, &d2); | ||
642 | if (mxl_fail(ret)) | ||
643 | goto fail; | ||
644 | |||
645 | d2 = d2 >> 4; | ||
646 | if (d2 > 7) | ||
647 | d2 += 0xf0; | ||
648 | |||
649 | *rf_input_level = (s32)(d1 + d2 - 113); | ||
650 | fail: | ||
651 | return ret; | ||
652 | } | ||
653 | |||
654 | /* ------------------------------------------------------------------------- */ | 585 | /* ------------------------------------------------------------------------- */ |
655 | 586 | ||
656 | static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) | 587 | static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) |
657 | { | 588 | { |
658 | struct mxl5007t_state *state = fe->tuner_priv; | 589 | struct mxl5007t_state *state = fe->tuner_priv; |
659 | int rf_locked, ref_locked; | 590 | int rf_locked, ref_locked, ret; |
660 | s32 rf_input_level = 0; | 591 | |
661 | int ret; | 592 | *status = 0; |
662 | 593 | ||
663 | if (fe->ops.i2c_gate_ctrl) | 594 | if (fe->ops.i2c_gate_ctrl) |
664 | fe->ops.i2c_gate_ctrl(fe, 1); | 595 | fe->ops.i2c_gate_ctrl(fe, 1); |
@@ -669,10 +600,8 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status) | |||
669 | mxl_debug("%s%s", rf_locked ? "rf locked " : "", | 600 | mxl_debug("%s%s", rf_locked ? "rf locked " : "", |
670 | ref_locked ? "ref locked" : ""); | 601 | ref_locked ? "ref locked" : ""); |
671 | 602 | ||
672 | ret = mxl5007t_check_rf_input_power(state, &rf_input_level); | 603 | if ((rf_locked) || (ref_locked)) |
673 | if (mxl_fail(ret)) | 604 | *status |= TUNER_STATUS_LOCKED; |
674 | goto fail; | ||
675 | mxl_debug("rf input power: %d", rf_input_level); | ||
676 | fail: | 605 | fail: |
677 | if (fe->ops.i2c_gate_ctrl) | 606 | if (fe->ops.i2c_gate_ctrl) |
678 | fe->ops.i2c_gate_ctrl(fe, 0); | 607 | fe->ops.i2c_gate_ctrl(fe, 0); |
@@ -695,11 +624,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, | |||
695 | switch (params->u.vsb.modulation) { | 624 | switch (params->u.vsb.modulation) { |
696 | case VSB_8: | 625 | case VSB_8: |
697 | case VSB_16: | 626 | case VSB_16: |
698 | mode = MxL_MODE_OTA_DVBT_ATSC; | 627 | mode = MxL_MODE_ATSC; |
699 | break; | 628 | break; |
700 | case QAM_64: | 629 | case QAM_64: |
701 | case QAM_256: | 630 | case QAM_256: |
702 | mode = MxL_MODE_CABLE_DIGITAL; | 631 | mode = MxL_MODE_CABLE; |
703 | break; | 632 | break; |
704 | default: | 633 | default: |
705 | mxl_err("modulation not set!"); | 634 | mxl_err("modulation not set!"); |
@@ -721,7 +650,7 @@ static int mxl5007t_set_params(struct dvb_frontend *fe, | |||
721 | mxl_err("bandwidth not set!"); | 650 | mxl_err("bandwidth not set!"); |
722 | return -EINVAL; | 651 | return -EINVAL; |
723 | } | 652 | } |
724 | mode = MxL_MODE_OTA_DVBT_ATSC; | 653 | mode = MxL_MODE_DVBT; |
725 | } else { | 654 | } else { |
726 | mxl_err("modulation type not supported!"); | 655 | mxl_err("modulation type not supported!"); |
727 | return -EINVAL; | 656 | return -EINVAL; |
@@ -752,96 +681,20 @@ fail: | |||
752 | return ret; | 681 | return ret; |
753 | } | 682 | } |
754 | 683 | ||
755 | static int mxl5007t_set_analog_params(struct dvb_frontend *fe, | ||
756 | struct analog_parameters *params) | ||
757 | { | ||
758 | struct mxl5007t_state *state = fe->tuner_priv; | ||
759 | enum mxl5007t_bw_mhz bw = 0; /* FIXME */ | ||
760 | enum mxl5007t_mode cbl_mode; | ||
761 | enum mxl5007t_mode ota_mode; | ||
762 | char *mode_name; | ||
763 | int ret; | ||
764 | u32 freq = params->frequency * 62500; | ||
765 | |||
766 | #define cable 1 | ||
767 | if (params->std & V4L2_STD_MN) { | ||
768 | cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; | ||
769 | ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; | ||
770 | mode_name = "MN"; | ||
771 | } else if (params->std & V4L2_STD_B) { | ||
772 | cbl_mode = MxL_MODE_CABLE_PAL_IB; | ||
773 | ota_mode = MxL_MODE_OTA_PAL_IB; | ||
774 | mode_name = "B"; | ||
775 | } else if (params->std & V4L2_STD_GH) { | ||
776 | cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; | ||
777 | ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; | ||
778 | mode_name = "GH"; | ||
779 | } else if (params->std & V4L2_STD_PAL_I) { | ||
780 | cbl_mode = MxL_MODE_CABLE_PAL_IB; | ||
781 | ota_mode = MxL_MODE_OTA_PAL_IB; | ||
782 | mode_name = "I"; | ||
783 | } else if (params->std & V4L2_STD_DK) { | ||
784 | cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; | ||
785 | ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; | ||
786 | mode_name = "DK"; | ||
787 | } else if (params->std & V4L2_STD_SECAM_L) { | ||
788 | cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; | ||
789 | ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; | ||
790 | mode_name = "L"; | ||
791 | } else if (params->std & V4L2_STD_SECAM_LC) { | ||
792 | cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL; | ||
793 | ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL; | ||
794 | mode_name = "L'"; | ||
795 | } else { | ||
796 | mode_name = "xx"; | ||
797 | /* FIXME */ | ||
798 | cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH; | ||
799 | ota_mode = MxL_MODE_OTA_NTSC_PAL_GH; | ||
800 | } | ||
801 | mxl_debug("setting mxl5007 to system %s", mode_name); | ||
802 | |||
803 | if (fe->ops.i2c_gate_ctrl) | ||
804 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
805 | |||
806 | mutex_lock(&state->lock); | ||
807 | |||
808 | ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode); | ||
809 | if (mxl_fail(ret)) | ||
810 | goto fail; | ||
811 | |||
812 | ret = mxl5007t_tuner_rf_tune(state, freq, bw); | ||
813 | if (mxl_fail(ret)) | ||
814 | goto fail; | ||
815 | |||
816 | state->frequency = freq; | ||
817 | state->bandwidth = 0; | ||
818 | fail: | ||
819 | mutex_unlock(&state->lock); | ||
820 | |||
821 | if (fe->ops.i2c_gate_ctrl) | ||
822 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
823 | |||
824 | return ret; | ||
825 | } | ||
826 | |||
827 | /* ------------------------------------------------------------------------- */ | 684 | /* ------------------------------------------------------------------------- */ |
828 | 685 | ||
829 | static int mxl5007t_init(struct dvb_frontend *fe) | 686 | static int mxl5007t_init(struct dvb_frontend *fe) |
830 | { | 687 | { |
831 | struct mxl5007t_state *state = fe->tuner_priv; | 688 | struct mxl5007t_state *state = fe->tuner_priv; |
832 | int ret; | 689 | int ret; |
833 | u8 d; | ||
834 | 690 | ||
835 | if (fe->ops.i2c_gate_ctrl) | 691 | if (fe->ops.i2c_gate_ctrl) |
836 | fe->ops.i2c_gate_ctrl(fe, 1); | 692 | fe->ops.i2c_gate_ctrl(fe, 1); |
837 | 693 | ||
838 | ret = mxl5007t_read_reg(state, 0x05, &d); | 694 | /* wake from standby */ |
839 | if (mxl_fail(ret)) | 695 | ret = mxl5007t_write_reg(state, 0x01, 0x01); |
840 | goto fail; | ||
841 | |||
842 | ret = mxl5007t_write_reg(state, 0x05, d | 0x01); | ||
843 | mxl_fail(ret); | 696 | mxl_fail(ret); |
844 | fail: | 697 | |
845 | if (fe->ops.i2c_gate_ctrl) | 698 | if (fe->ops.i2c_gate_ctrl) |
846 | fe->ops.i2c_gate_ctrl(fe, 0); | 699 | fe->ops.i2c_gate_ctrl(fe, 0); |
847 | 700 | ||
@@ -852,18 +705,16 @@ static int mxl5007t_sleep(struct dvb_frontend *fe) | |||
852 | { | 705 | { |
853 | struct mxl5007t_state *state = fe->tuner_priv; | 706 | struct mxl5007t_state *state = fe->tuner_priv; |
854 | int ret; | 707 | int ret; |
855 | u8 d; | ||
856 | 708 | ||
857 | if (fe->ops.i2c_gate_ctrl) | 709 | if (fe->ops.i2c_gate_ctrl) |
858 | fe->ops.i2c_gate_ctrl(fe, 1); | 710 | fe->ops.i2c_gate_ctrl(fe, 1); |
859 | 711 | ||
860 | ret = mxl5007t_read_reg(state, 0x05, &d); | 712 | /* enter standby mode */ |
861 | if (mxl_fail(ret)) | 713 | ret = mxl5007t_write_reg(state, 0x01, 0x00); |
862 | goto fail; | ||
863 | |||
864 | ret = mxl5007t_write_reg(state, 0x05, d & ~0x01); | ||
865 | mxl_fail(ret); | 714 | mxl_fail(ret); |
866 | fail: | 715 | ret = mxl5007t_write_reg(state, 0x0f, 0x00); |
716 | mxl_fail(ret); | ||
717 | |||
867 | if (fe->ops.i2c_gate_ctrl) | 718 | if (fe->ops.i2c_gate_ctrl) |
868 | fe->ops.i2c_gate_ctrl(fe, 0); | 719 | fe->ops.i2c_gate_ctrl(fe, 0); |
869 | 720 | ||
@@ -911,7 +762,6 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = { | |||
911 | .init = mxl5007t_init, | 762 | .init = mxl5007t_init, |
912 | .sleep = mxl5007t_sleep, | 763 | .sleep = mxl5007t_sleep, |
913 | .set_params = mxl5007t_set_params, | 764 | .set_params = mxl5007t_set_params, |
914 | .set_analog_params = mxl5007t_set_analog_params, | ||
915 | .get_status = mxl5007t_get_status, | 765 | .get_status = mxl5007t_get_status, |
916 | .get_frequency = mxl5007t_get_frequency, | 766 | .get_frequency = mxl5007t_get_frequency, |
917 | .get_bandwidth = mxl5007t_get_bandwidth, | 767 | .get_bandwidth = mxl5007t_get_bandwidth, |
@@ -924,7 +774,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) | |||
924 | int ret; | 774 | int ret; |
925 | u8 id; | 775 | u8 id; |
926 | 776 | ||
927 | ret = mxl5007t_read_reg(state, 0xd3, &id); | 777 | ret = mxl5007t_read_reg(state, 0xd9, &id); |
928 | if (mxl_fail(ret)) | 778 | if (mxl_fail(ret)) |
929 | goto fail; | 779 | goto fail; |
930 | 780 | ||
@@ -947,8 +797,12 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state) | |||
947 | case MxL_5007_V2_200_F2: | 797 | case MxL_5007_V2_200_F2: |
948 | name = "MxL5007.v2.200.f2"; | 798 | name = "MxL5007.v2.200.f2"; |
949 | break; | 799 | break; |
800 | case MxL_5007_V4: | ||
801 | name = "MxL5007T.v4"; | ||
802 | break; | ||
950 | default: | 803 | default: |
951 | name = "MxL5007T"; | 804 | name = "MxL5007T"; |
805 | printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id); | ||
952 | id = MxL_UNKNOWN_ID; | 806 | id = MxL_UNKNOWN_ID; |
953 | } | 807 | } |
954 | state->chip_id = id; | 808 | state->chip_id = id; |
@@ -975,7 +829,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe, | |||
975 | mutex_lock(&mxl5007t_list_mutex); | 829 | mutex_lock(&mxl5007t_list_mutex); |
976 | instance = hybrid_tuner_request_state(struct mxl5007t_state, state, | 830 | instance = hybrid_tuner_request_state(struct mxl5007t_state, state, |
977 | hybrid_tuner_instance_list, | 831 | hybrid_tuner_instance_list, |
978 | i2c, addr, "mxl5007"); | 832 | i2c, addr, "mxl5007t"); |
979 | switch (instance) { | 833 | switch (instance) { |
980 | case 0: | 834 | case 0: |
981 | goto fail; | 835 | goto fail; |
@@ -1018,7 +872,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach); | |||
1018 | MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver"); | 872 | MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver"); |
1019 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); | 873 | MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); |
1020 | MODULE_LICENSE("GPL"); | 874 | MODULE_LICENSE("GPL"); |
1021 | MODULE_VERSION("0.1"); | 875 | MODULE_VERSION("0.2"); |
1022 | 876 | ||
1023 | /* | 877 | /* |
1024 | * Overrides for Emacs so that we follow Linus's tabbing style. | 878 | * Overrides for Emacs so that we follow Linus's tabbing style. |
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index 6fb5b4586569..fc76c30e24f1 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c | |||
@@ -490,9 +490,9 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe, | |||
490 | tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); | 490 | tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt); |
491 | 491 | ||
492 | regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ | 492 | regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */ |
493 | regs[R_EP3] |= sm ? (1 << 7) : 0 | | 493 | regs[R_EP3] |= (sm ? (1 << 7) : 0) | |
494 | sm_lt ? (1 << 6) : 0 | | 494 | (sm_lt ? (1 << 6) : 0) | |
495 | sm_xt ? (1 << 5) : 0; | 495 | (sm_xt ? (1 << 5) : 0); |
496 | 496 | ||
497 | return tda18271_write_regs(fe, R_EP3, 1); | 497 | return tda18271_write_regs(fe, R_EP3, 1); |
498 | } | 498 | } |
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 1b48b5d0bf1e..b10935630154 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c | |||
@@ -818,6 +818,38 @@ fail: | |||
818 | return ret; | 818 | return ret; |
819 | } | 819 | } |
820 | 820 | ||
821 | /* ------------------------------------------------------------------ */ | ||
822 | |||
823 | static int tda18271_agc(struct dvb_frontend *fe) | ||
824 | { | ||
825 | struct tda18271_priv *priv = fe->tuner_priv; | ||
826 | int ret = 0; | ||
827 | |||
828 | switch (priv->config) { | ||
829 | case 0: | ||
830 | /* no LNA */ | ||
831 | tda_dbg("no agc configuration provided\n"); | ||
832 | break; | ||
833 | case 3: | ||
834 | /* switch with GPIO of saa713x */ | ||
835 | tda_dbg("invoking callback\n"); | ||
836 | if (fe->callback) | ||
837 | ret = fe->callback(priv->i2c_props.adap->algo_data, | ||
838 | DVB_FRONTEND_COMPONENT_TUNER, | ||
839 | TDA18271_CALLBACK_CMD_AGC_ENABLE, | ||
840 | priv->mode); | ||
841 | break; | ||
842 | case 1: | ||
843 | case 2: | ||
844 | default: | ||
845 | /* n/a - currently not supported */ | ||
846 | tda_err("unsupported configuration: %d\n", priv->config); | ||
847 | ret = -EINVAL; | ||
848 | break; | ||
849 | } | ||
850 | return ret; | ||
851 | } | ||
852 | |||
821 | static int tda18271_tune(struct dvb_frontend *fe, | 853 | static int tda18271_tune(struct dvb_frontend *fe, |
822 | struct tda18271_std_map_item *map, u32 freq, u32 bw) | 854 | struct tda18271_std_map_item *map, u32 freq, u32 bw) |
823 | { | 855 | { |
@@ -827,6 +859,10 @@ static int tda18271_tune(struct dvb_frontend *fe, | |||
827 | tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n", | 859 | tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n", |
828 | freq, map->if_freq, bw, map->agc_mode, map->std); | 860 | freq, map->if_freq, bw, map->agc_mode, map->std); |
829 | 861 | ||
862 | ret = tda18271_agc(fe); | ||
863 | if (tda_fail(ret)) | ||
864 | tda_warn("failed to configure agc\n"); | ||
865 | |||
830 | ret = tda18271_init(fe); | 866 | ret = tda18271_init(fe); |
831 | if (tda_fail(ret)) | 867 | if (tda_fail(ret)) |
832 | goto fail; | 868 | goto fail; |
@@ -1159,6 +1195,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, | |||
1159 | /* new tuner instance */ | 1195 | /* new tuner instance */ |
1160 | priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; | 1196 | priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; |
1161 | priv->role = (cfg) ? cfg->role : TDA18271_MASTER; | 1197 | priv->role = (cfg) ? cfg->role : TDA18271_MASTER; |
1198 | priv->config = (cfg) ? cfg->config : 0; | ||
1162 | priv->cal_initialized = false; | 1199 | priv->cal_initialized = false; |
1163 | mutex_init(&priv->lock); | 1200 | mutex_init(&priv->lock); |
1164 | 1201 | ||
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h index 81a739365f8c..74beb28806f8 100644 --- a/drivers/media/common/tuners/tda18271-priv.h +++ b/drivers/media/common/tuners/tda18271-priv.h | |||
@@ -91,11 +91,6 @@ enum tda18271_pll { | |||
91 | TDA18271_CAL_PLL, | 91 | TDA18271_CAL_PLL, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | enum tda18271_mode { | ||
95 | TDA18271_ANALOG, | ||
96 | TDA18271_DIGITAL, | ||
97 | }; | ||
98 | |||
99 | struct tda18271_map_layout; | 94 | struct tda18271_map_layout; |
100 | 95 | ||
101 | enum tda18271_ver { | 96 | enum tda18271_ver { |
@@ -114,6 +109,7 @@ struct tda18271_priv { | |||
114 | enum tda18271_i2c_gate gate; | 109 | enum tda18271_i2c_gate gate; |
115 | enum tda18271_ver id; | 110 | enum tda18271_ver id; |
116 | 111 | ||
112 | unsigned int config; /* interface to saa713x / tda829x */ | ||
117 | unsigned int tm_rfcal; | 113 | unsigned int tm_rfcal; |
118 | unsigned int cal_initialized:1; | 114 | unsigned int cal_initialized:1; |
119 | unsigned int small_i2c:1; | 115 | unsigned int small_i2c:1; |
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h index 7db9831c0cb0..53a9892a18d0 100644 --- a/drivers/media/common/tuners/tda18271.h +++ b/drivers/media/common/tuners/tda18271.h | |||
@@ -79,6 +79,16 @@ struct tda18271_config { | |||
79 | 79 | ||
80 | /* some i2c providers cant write all 39 registers at once */ | 80 | /* some i2c providers cant write all 39 registers at once */ |
81 | unsigned int small_i2c:1; | 81 | unsigned int small_i2c:1; |
82 | |||
83 | /* interface to saa713x / tda829x */ | ||
84 | unsigned int config; | ||
85 | }; | ||
86 | |||
87 | #define TDA18271_CALLBACK_CMD_AGC_ENABLE 0 | ||
88 | |||
89 | enum tda18271_mode { | ||
90 | TDA18271_ANALOG = 0, | ||
91 | TDA18271_DIGITAL, | ||
82 | }; | 92 | }; |
83 | 93 | ||
84 | #if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE)) | 94 | #if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE)) |
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c index f4d931f14fad..36a7bc7585ab 100644 --- a/drivers/media/common/tuners/tda827x.c +++ b/drivers/media/common/tuners/tda827x.c | |||
@@ -132,11 +132,31 @@ static const struct tda827x_data tda827x_table[] = { | |||
132 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} | 132 | { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0} |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static int tuner_transfer(struct dvb_frontend *fe, | ||
136 | struct i2c_msg *msg, | ||
137 | const int size) | ||
138 | { | ||
139 | int rc; | ||
140 | struct tda827x_priv *priv = fe->tuner_priv; | ||
141 | |||
142 | if (fe->ops.i2c_gate_ctrl) | ||
143 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
144 | rc = i2c_transfer(priv->i2c_adap, msg, size); | ||
145 | if (fe->ops.i2c_gate_ctrl) | ||
146 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
147 | |||
148 | if (rc >= 0 && rc != size) | ||
149 | return -EIO; | ||
150 | |||
151 | return rc; | ||
152 | } | ||
153 | |||
135 | static int tda827xo_set_params(struct dvb_frontend *fe, | 154 | static int tda827xo_set_params(struct dvb_frontend *fe, |
136 | struct dvb_frontend_parameters *params) | 155 | struct dvb_frontend_parameters *params) |
137 | { | 156 | { |
138 | struct tda827x_priv *priv = fe->tuner_priv; | 157 | struct tda827x_priv *priv = fe->tuner_priv; |
139 | u8 buf[14]; | 158 | u8 buf[14]; |
159 | int rc; | ||
140 | 160 | ||
141 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 161 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, |
142 | .buf = buf, .len = sizeof(buf) }; | 162 | .buf = buf, .len = sizeof(buf) }; |
@@ -183,27 +203,29 @@ static int tda827xo_set_params(struct dvb_frontend *fe, | |||
183 | buf[13] = 0x40; | 203 | buf[13] = 0x40; |
184 | 204 | ||
185 | msg.len = 14; | 205 | msg.len = 14; |
186 | if (fe->ops.i2c_gate_ctrl) | 206 | rc = tuner_transfer(fe, &msg, 1); |
187 | fe->ops.i2c_gate_ctrl(fe, 1); | 207 | if (rc < 0) |
188 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | 208 | goto err; |
189 | printk("%s: could not write to tuner at addr: 0x%02x\n", | 209 | |
190 | __func__, priv->i2c_addr << 1); | ||
191 | return -EIO; | ||
192 | } | ||
193 | msleep(500); | 210 | msleep(500); |
194 | /* correct CP value */ | 211 | /* correct CP value */ |
195 | buf[0] = 0x30; | 212 | buf[0] = 0x30; |
196 | buf[1] = 0x50 + tda827x_table[i].cp; | 213 | buf[1] = 0x50 + tda827x_table[i].cp; |
197 | msg.len = 2; | 214 | msg.len = 2; |
198 | 215 | ||
199 | if (fe->ops.i2c_gate_ctrl) | 216 | rc = tuner_transfer(fe, &msg, 1); |
200 | fe->ops.i2c_gate_ctrl(fe, 1); | 217 | if (rc < 0) |
201 | i2c_transfer(priv->i2c_adap, &msg, 1); | 218 | goto err; |
202 | 219 | ||
203 | priv->frequency = params->frequency; | 220 | priv->frequency = params->frequency; |
204 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | 221 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; |
205 | 222 | ||
206 | return 0; | 223 | return 0; |
224 | |||
225 | err: | ||
226 | printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", | ||
227 | __func__, priv->i2c_addr << 1); | ||
228 | return rc; | ||
207 | } | 229 | } |
208 | 230 | ||
209 | static int tda827xo_sleep(struct dvb_frontend *fe) | 231 | static int tda827xo_sleep(struct dvb_frontend *fe) |
@@ -214,9 +236,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe) | |||
214 | .buf = buf, .len = sizeof(buf) }; | 236 | .buf = buf, .len = sizeof(buf) }; |
215 | 237 | ||
216 | dprintk("%s:\n", __func__); | 238 | dprintk("%s:\n", __func__); |
217 | if (fe->ops.i2c_gate_ctrl) | 239 | tuner_transfer(fe, &msg, 1); |
218 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
219 | i2c_transfer(priv->i2c_adap, &msg, 1); | ||
220 | 240 | ||
221 | if (priv->cfg && priv->cfg->sleep) | 241 | if (priv->cfg && priv->cfg->sleep) |
222 | priv->cfg->sleep(fe); | 242 | priv->cfg->sleep(fe); |
@@ -266,44 +286,44 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe, | |||
266 | 286 | ||
267 | msg.buf = tuner_reg; | 287 | msg.buf = tuner_reg; |
268 | msg.len = 8; | 288 | msg.len = 8; |
269 | i2c_transfer(priv->i2c_adap, &msg, 1); | 289 | tuner_transfer(fe, &msg, 1); |
270 | 290 | ||
271 | msg.buf = reg2; | 291 | msg.buf = reg2; |
272 | msg.len = 2; | 292 | msg.len = 2; |
273 | reg2[0] = 0x80; | 293 | reg2[0] = 0x80; |
274 | reg2[1] = 0; | 294 | reg2[1] = 0; |
275 | i2c_transfer(priv->i2c_adap, &msg, 1); | 295 | tuner_transfer(fe, &msg, 1); |
276 | 296 | ||
277 | reg2[0] = 0x60; | 297 | reg2[0] = 0x60; |
278 | reg2[1] = 0xbf; | 298 | reg2[1] = 0xbf; |
279 | i2c_transfer(priv->i2c_adap, &msg, 1); | 299 | tuner_transfer(fe, &msg, 1); |
280 | 300 | ||
281 | reg2[0] = 0x30; | 301 | reg2[0] = 0x30; |
282 | reg2[1] = tuner_reg[4] + 0x80; | 302 | reg2[1] = tuner_reg[4] + 0x80; |
283 | i2c_transfer(priv->i2c_adap, &msg, 1); | 303 | tuner_transfer(fe, &msg, 1); |
284 | 304 | ||
285 | msleep(1); | 305 | msleep(1); |
286 | reg2[0] = 0x30; | 306 | reg2[0] = 0x30; |
287 | reg2[1] = tuner_reg[4] + 4; | 307 | reg2[1] = tuner_reg[4] + 4; |
288 | i2c_transfer(priv->i2c_adap, &msg, 1); | 308 | tuner_transfer(fe, &msg, 1); |
289 | 309 | ||
290 | msleep(1); | 310 | msleep(1); |
291 | reg2[0] = 0x30; | 311 | reg2[0] = 0x30; |
292 | reg2[1] = tuner_reg[4]; | 312 | reg2[1] = tuner_reg[4]; |
293 | i2c_transfer(priv->i2c_adap, &msg, 1); | 313 | tuner_transfer(fe, &msg, 1); |
294 | 314 | ||
295 | msleep(550); | 315 | msleep(550); |
296 | reg2[0] = 0x30; | 316 | reg2[0] = 0x30; |
297 | reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp; | 317 | reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp; |
298 | i2c_transfer(priv->i2c_adap, &msg, 1); | 318 | tuner_transfer(fe, &msg, 1); |
299 | 319 | ||
300 | reg2[0] = 0x60; | 320 | reg2[0] = 0x60; |
301 | reg2[1] = 0x3f; | 321 | reg2[1] = 0x3f; |
302 | i2c_transfer(priv->i2c_adap, &msg, 1); | 322 | tuner_transfer(fe, &msg, 1); |
303 | 323 | ||
304 | reg2[0] = 0x80; | 324 | reg2[0] = 0x80; |
305 | reg2[1] = 0x08; /* Vsync en */ | 325 | reg2[1] = 0x08; /* Vsync en */ |
306 | i2c_transfer(priv->i2c_adap, &msg, 1); | 326 | tuner_transfer(fe, &msg, 1); |
307 | 327 | ||
308 | priv->frequency = params->frequency; | 328 | priv->frequency = params->frequency; |
309 | 329 | ||
@@ -317,7 +337,7 @@ static void tda827xo_agcf(struct dvb_frontend *fe) | |||
317 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 337 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, |
318 | .buf = data, .len = 2}; | 338 | .buf = data, .len = 2}; |
319 | 339 | ||
320 | i2c_transfer(priv->i2c_adap, &msg, 1); | 340 | tuner_transfer(fe, &msg, 1); |
321 | } | 341 | } |
322 | 342 | ||
323 | /* ------------------------------------------------------------------ */ | 343 | /* ------------------------------------------------------------------ */ |
@@ -331,7 +351,7 @@ struct tda827xa_data { | |||
331 | u8 gc3; | 351 | u8 gc3; |
332 | }; | 352 | }; |
333 | 353 | ||
334 | static const struct tda827xa_data tda827xa_dvbt[] = { | 354 | static struct tda827xa_data tda827xa_dvbt[] = { |
335 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, | 355 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1}, |
336 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | 356 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, |
337 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, | 357 | { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1}, |
@@ -361,6 +381,36 @@ static const struct tda827xa_data tda827xa_dvbt[] = { | |||
361 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | 381 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} |
362 | }; | 382 | }; |
363 | 383 | ||
384 | static struct tda827xa_data tda827xa_dvbc[] = { | ||
385 | { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, | ||
386 | { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3}, | ||
387 | { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, | ||
388 | { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, | ||
389 | { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3}, | ||
390 | { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, | ||
391 | { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1}, | ||
392 | { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, | ||
393 | { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, | ||
394 | { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1}, | ||
395 | { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1}, | ||
396 | { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3}, | ||
397 | { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3}, | ||
398 | { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1}, | ||
399 | { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, | ||
400 | { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3}, | ||
401 | { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1}, | ||
402 | { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1}, | ||
403 | { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1}, | ||
404 | { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | ||
405 | { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, | ||
406 | { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | ||
407 | { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, | ||
408 | { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | ||
409 | { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1}, | ||
410 | { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1}, | ||
411 | { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0} | ||
412 | }; | ||
413 | |||
364 | static struct tda827xa_data tda827xa_analog[] = { | 414 | static struct tda827xa_data tda827xa_analog[] = { |
365 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, | 415 | { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3}, |
366 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, | 416 | { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3}, |
@@ -398,13 +448,8 @@ static int tda827xa_sleep(struct dvb_frontend *fe) | |||
398 | .buf = buf, .len = sizeof(buf) }; | 448 | .buf = buf, .len = sizeof(buf) }; |
399 | 449 | ||
400 | dprintk("%s:\n", __func__); | 450 | dprintk("%s:\n", __func__); |
401 | if (fe->ops.i2c_gate_ctrl) | ||
402 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
403 | 451 | ||
404 | i2c_transfer(priv->i2c_adap, &msg, 1); | 452 | tuner_transfer(fe, &msg, 1); |
405 | |||
406 | if (fe->ops.i2c_gate_ctrl) | ||
407 | fe->ops.i2c_gate_ctrl(fe, 0); | ||
408 | 453 | ||
409 | if (priv->cfg && priv->cfg->sleep) | 454 | if (priv->cfg && priv->cfg->sleep) |
410 | priv->cfg->sleep(fe); | 455 | priv->cfg->sleep(fe); |
@@ -455,7 +500,7 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, | |||
455 | buf[1] = high ? 0 : 1; | 500 | buf[1] = high ? 0 : 1; |
456 | if (priv->cfg->config == 2) | 501 | if (priv->cfg->config == 2) |
457 | buf[1] = high ? 1 : 0; | 502 | buf[1] = high ? 1 : 0; |
458 | i2c_transfer(priv->i2c_adap, &msg, 1); | 503 | tuner_transfer(fe, &msg, 1); |
459 | break; | 504 | break; |
460 | case 3: /* switch with GPIO of saa713x */ | 505 | case 3: /* switch with GPIO of saa713x */ |
461 | if (fe->callback) | 506 | if (fe->callback) |
@@ -469,12 +514,13 @@ static int tda827xa_set_params(struct dvb_frontend *fe, | |||
469 | struct dvb_frontend_parameters *params) | 514 | struct dvb_frontend_parameters *params) |
470 | { | 515 | { |
471 | struct tda827x_priv *priv = fe->tuner_priv; | 516 | struct tda827x_priv *priv = fe->tuner_priv; |
517 | struct tda827xa_data *frequency_map = tda827xa_dvbt; | ||
472 | u8 buf[11]; | 518 | u8 buf[11]; |
473 | 519 | ||
474 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, | 520 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, |
475 | .buf = buf, .len = sizeof(buf) }; | 521 | .buf = buf, .len = sizeof(buf) }; |
476 | 522 | ||
477 | int i, tuner_freq, if_freq; | 523 | int i, tuner_freq, if_freq, rc; |
478 | u32 N; | 524 | u32 N; |
479 | 525 | ||
480 | dprintk("%s:\n", __func__); | 526 | dprintk("%s:\n", __func__); |
@@ -495,56 +541,58 @@ static int tda827xa_set_params(struct dvb_frontend *fe, | |||
495 | } | 541 | } |
496 | tuner_freq = params->frequency + if_freq; | 542 | tuner_freq = params->frequency + if_freq; |
497 | 543 | ||
544 | if (fe->ops.info.type == FE_QAM) { | ||
545 | dprintk("%s select tda827xa_dvbc\n", __func__); | ||
546 | frequency_map = tda827xa_dvbc; | ||
547 | } | ||
548 | |||
498 | i = 0; | 549 | i = 0; |
499 | while (tda827xa_dvbt[i].lomax < tuner_freq) { | 550 | while (frequency_map[i].lomax < tuner_freq) { |
500 | if(tda827xa_dvbt[i + 1].lomax == 0) | 551 | if (frequency_map[i + 1].lomax == 0) |
501 | break; | 552 | break; |
502 | i++; | 553 | i++; |
503 | } | 554 | } |
504 | 555 | ||
505 | N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd; | 556 | N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd; |
506 | buf[0] = 0; // subaddress | 557 | buf[0] = 0; // subaddress |
507 | buf[1] = N >> 8; | 558 | buf[1] = N >> 8; |
508 | buf[2] = N & 0xff; | 559 | buf[2] = N & 0xff; |
509 | buf[3] = 0; | 560 | buf[3] = 0; |
510 | buf[4] = 0x16; | 561 | buf[4] = 0x16; |
511 | buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) + | 562 | buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) + |
512 | tda827xa_dvbt[i].sbs; | 563 | frequency_map[i].sbs; |
513 | buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4); | 564 | buf[6] = 0x4b + (frequency_map[i].gc3 << 4); |
514 | buf[7] = 0x1c; | 565 | buf[7] = 0x1c; |
515 | buf[8] = 0x06; | 566 | buf[8] = 0x06; |
516 | buf[9] = 0x24; | 567 | buf[9] = 0x24; |
517 | buf[10] = 0x00; | 568 | buf[10] = 0x00; |
518 | msg.len = 11; | 569 | msg.len = 11; |
519 | if (fe->ops.i2c_gate_ctrl) | 570 | rc = tuner_transfer(fe, &msg, 1); |
520 | fe->ops.i2c_gate_ctrl(fe, 1); | 571 | if (rc < 0) |
521 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | 572 | goto err; |
522 | printk("%s: could not write to tuner at addr: 0x%02x\n", | 573 | |
523 | __func__, priv->i2c_addr << 1); | ||
524 | return -EIO; | ||
525 | } | ||
526 | buf[0] = 0x90; | 574 | buf[0] = 0x90; |
527 | buf[1] = 0xff; | 575 | buf[1] = 0xff; |
528 | buf[2] = 0x60; | 576 | buf[2] = 0x60; |
529 | buf[3] = 0x00; | 577 | buf[3] = 0x00; |
530 | buf[4] = 0x59; // lpsel, for 6MHz + 2 | 578 | buf[4] = 0x59; // lpsel, for 6MHz + 2 |
531 | msg.len = 5; | 579 | msg.len = 5; |
532 | if (fe->ops.i2c_gate_ctrl) | 580 | rc = tuner_transfer(fe, &msg, 1); |
533 | fe->ops.i2c_gate_ctrl(fe, 1); | 581 | if (rc < 0) |
534 | i2c_transfer(priv->i2c_adap, &msg, 1); | 582 | goto err; |
535 | 583 | ||
536 | buf[0] = 0xa0; | 584 | buf[0] = 0xa0; |
537 | buf[1] = 0x40; | 585 | buf[1] = 0x40; |
538 | msg.len = 2; | 586 | msg.len = 2; |
539 | if (fe->ops.i2c_gate_ctrl) | 587 | rc = tuner_transfer(fe, &msg, 1); |
540 | fe->ops.i2c_gate_ctrl(fe, 1); | 588 | if (rc < 0) |
541 | i2c_transfer(priv->i2c_adap, &msg, 1); | 589 | goto err; |
542 | 590 | ||
543 | msleep(11); | 591 | msleep(11); |
544 | msg.flags = I2C_M_RD; | 592 | msg.flags = I2C_M_RD; |
545 | if (fe->ops.i2c_gate_ctrl) | 593 | rc = tuner_transfer(fe, &msg, 1); |
546 | fe->ops.i2c_gate_ctrl(fe, 1); | 594 | if (rc < 0) |
547 | i2c_transfer(priv->i2c_adap, &msg, 1); | 595 | goto err; |
548 | msg.flags = 0; | 596 | msg.flags = 0; |
549 | 597 | ||
550 | buf[1] >>= 4; | 598 | buf[1] >>= 4; |
@@ -553,49 +601,55 @@ static int tda827xa_set_params(struct dvb_frontend *fe, | |||
553 | tda827xa_lna_gain(fe, 0, NULL); | 601 | tda827xa_lna_gain(fe, 0, NULL); |
554 | buf[0] = 0x60; | 602 | buf[0] = 0x60; |
555 | buf[1] = 0x0c; | 603 | buf[1] = 0x0c; |
556 | if (fe->ops.i2c_gate_ctrl) | 604 | rc = tuner_transfer(fe, &msg, 1); |
557 | fe->ops.i2c_gate_ctrl(fe, 1); | 605 | if (rc < 0) |
558 | i2c_transfer(priv->i2c_adap, &msg, 1); | 606 | goto err; |
559 | } | 607 | } |
560 | 608 | ||
561 | buf[0] = 0xc0; | 609 | buf[0] = 0xc0; |
562 | buf[1] = 0x99; // lpsel, for 6MHz + 2 | 610 | buf[1] = 0x99; // lpsel, for 6MHz + 2 |
563 | if (fe->ops.i2c_gate_ctrl) | 611 | rc = tuner_transfer(fe, &msg, 1); |
564 | fe->ops.i2c_gate_ctrl(fe, 1); | 612 | if (rc < 0) |
565 | i2c_transfer(priv->i2c_adap, &msg, 1); | 613 | goto err; |
566 | 614 | ||
567 | buf[0] = 0x60; | 615 | buf[0] = 0x60; |
568 | buf[1] = 0x3c; | 616 | buf[1] = 0x3c; |
569 | if (fe->ops.i2c_gate_ctrl) | 617 | rc = tuner_transfer(fe, &msg, 1); |
570 | fe->ops.i2c_gate_ctrl(fe, 1); | 618 | if (rc < 0) |
571 | i2c_transfer(priv->i2c_adap, &msg, 1); | 619 | goto err; |
572 | 620 | ||
573 | /* correct CP value */ | 621 | /* correct CP value */ |
574 | buf[0] = 0x30; | 622 | buf[0] = 0x30; |
575 | buf[1] = 0x10 + tda827xa_dvbt[i].scr; | 623 | buf[1] = 0x10 + frequency_map[i].scr; |
576 | if (fe->ops.i2c_gate_ctrl) | 624 | rc = tuner_transfer(fe, &msg, 1); |
577 | fe->ops.i2c_gate_ctrl(fe, 1); | 625 | if (rc < 0) |
578 | i2c_transfer(priv->i2c_adap, &msg, 1); | 626 | goto err; |
579 | 627 | ||
580 | msleep(163); | 628 | msleep(163); |
581 | buf[0] = 0xc0; | 629 | buf[0] = 0xc0; |
582 | buf[1] = 0x39; // lpsel, for 6MHz + 2 | 630 | buf[1] = 0x39; // lpsel, for 6MHz + 2 |
583 | if (fe->ops.i2c_gate_ctrl) | 631 | rc = tuner_transfer(fe, &msg, 1); |
584 | fe->ops.i2c_gate_ctrl(fe, 1); | 632 | if (rc < 0) |
585 | i2c_transfer(priv->i2c_adap, &msg, 1); | 633 | goto err; |
586 | 634 | ||
587 | msleep(3); | 635 | msleep(3); |
588 | /* freeze AGC1 */ | 636 | /* freeze AGC1 */ |
589 | buf[0] = 0x50; | 637 | buf[0] = 0x50; |
590 | buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4); | 638 | buf[1] = 0x4f + (frequency_map[i].gc3 << 4); |
591 | if (fe->ops.i2c_gate_ctrl) | 639 | rc = tuner_transfer(fe, &msg, 1); |
592 | fe->ops.i2c_gate_ctrl(fe, 1); | 640 | if (rc < 0) |
593 | i2c_transfer(priv->i2c_adap, &msg, 1); | 641 | goto err; |
594 | 642 | ||
595 | priv->frequency = params->frequency; | 643 | priv->frequency = params->frequency; |
596 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; | 644 | priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0; |
597 | 645 | ||
646 | |||
598 | return 0; | 647 | return 0; |
648 | |||
649 | err: | ||
650 | printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n", | ||
651 | __func__, priv->i2c_addr << 1); | ||
652 | return rc; | ||
599 | } | 653 | } |
600 | 654 | ||
601 | 655 | ||
@@ -643,7 +697,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, | |||
643 | tuner_reg[9] = 0x20; | 697 | tuner_reg[9] = 0x20; |
644 | tuner_reg[10] = 0x00; | 698 | tuner_reg[10] = 0x00; |
645 | msg.len = 11; | 699 | msg.len = 11; |
646 | i2c_transfer(priv->i2c_adap, &msg, 1); | 700 | tuner_transfer(fe, &msg, 1); |
647 | 701 | ||
648 | tuner_reg[0] = 0x90; | 702 | tuner_reg[0] = 0x90; |
649 | tuner_reg[1] = 0xff; | 703 | tuner_reg[1] = 0xff; |
@@ -651,19 +705,19 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, | |||
651 | tuner_reg[3] = 0; | 705 | tuner_reg[3] = 0; |
652 | tuner_reg[4] = 0x99 + (priv->lpsel << 1); | 706 | tuner_reg[4] = 0x99 + (priv->lpsel << 1); |
653 | msg.len = 5; | 707 | msg.len = 5; |
654 | i2c_transfer(priv->i2c_adap, &msg, 1); | 708 | tuner_transfer(fe, &msg, 1); |
655 | 709 | ||
656 | tuner_reg[0] = 0xa0; | 710 | tuner_reg[0] = 0xa0; |
657 | tuner_reg[1] = 0xc0; | 711 | tuner_reg[1] = 0xc0; |
658 | msg.len = 2; | 712 | msg.len = 2; |
659 | i2c_transfer(priv->i2c_adap, &msg, 1); | 713 | tuner_transfer(fe, &msg, 1); |
660 | 714 | ||
661 | tuner_reg[0] = 0x30; | 715 | tuner_reg[0] = 0x30; |
662 | tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; | 716 | tuner_reg[1] = 0x10 + tda827xa_analog[i].scr; |
663 | i2c_transfer(priv->i2c_adap, &msg, 1); | 717 | tuner_transfer(fe, &msg, 1); |
664 | 718 | ||
665 | msg.flags = I2C_M_RD; | 719 | msg.flags = I2C_M_RD; |
666 | i2c_transfer(priv->i2c_adap, &msg, 1); | 720 | tuner_transfer(fe, &msg, 1); |
667 | msg.flags = 0; | 721 | msg.flags = 0; |
668 | tuner_reg[1] >>= 4; | 722 | tuner_reg[1] >>= 4; |
669 | dprintk("AGC2 gain is: %d\n", tuner_reg[1]); | 723 | dprintk("AGC2 gain is: %d\n", tuner_reg[1]); |
@@ -673,24 +727,24 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe, | |||
673 | msleep(100); | 727 | msleep(100); |
674 | tuner_reg[0] = 0x60; | 728 | tuner_reg[0] = 0x60; |
675 | tuner_reg[1] = 0x3c; | 729 | tuner_reg[1] = 0x3c; |
676 | i2c_transfer(priv->i2c_adap, &msg, 1); | 730 | tuner_transfer(fe, &msg, 1); |
677 | 731 | ||
678 | msleep(163); | 732 | msleep(163); |
679 | tuner_reg[0] = 0x50; | 733 | tuner_reg[0] = 0x50; |
680 | tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); | 734 | tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4); |
681 | i2c_transfer(priv->i2c_adap, &msg, 1); | 735 | tuner_transfer(fe, &msg, 1); |
682 | 736 | ||
683 | tuner_reg[0] = 0x80; | 737 | tuner_reg[0] = 0x80; |
684 | tuner_reg[1] = 0x28; | 738 | tuner_reg[1] = 0x28; |
685 | i2c_transfer(priv->i2c_adap, &msg, 1); | 739 | tuner_transfer(fe, &msg, 1); |
686 | 740 | ||
687 | tuner_reg[0] = 0xb0; | 741 | tuner_reg[0] = 0xb0; |
688 | tuner_reg[1] = 0x01; | 742 | tuner_reg[1] = 0x01; |
689 | i2c_transfer(priv->i2c_adap, &msg, 1); | 743 | tuner_transfer(fe, &msg, 1); |
690 | 744 | ||
691 | tuner_reg[0] = 0xc0; | 745 | tuner_reg[0] = 0xc0; |
692 | tuner_reg[1] = 0x19 + (priv->lpsel << 1); | 746 | tuner_reg[1] = 0x19 + (priv->lpsel << 1); |
693 | i2c_transfer(priv->i2c_adap, &msg, 1); | 747 | tuner_transfer(fe, &msg, 1); |
694 | 748 | ||
695 | priv->frequency = params->frequency; | 749 | priv->frequency = params->frequency; |
696 | 750 | ||
@@ -703,7 +757,7 @@ static void tda827xa_agcf(struct dvb_frontend *fe) | |||
703 | unsigned char data[] = {0x80, 0x2c}; | 757 | unsigned char data[] = {0x80, 0x2c}; |
704 | struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, | 758 | struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0, |
705 | .buf = data, .len = 2}; | 759 | .buf = data, .len = 2}; |
706 | i2c_transfer(priv->i2c_adap, &msg, 1); | 760 | tuner_transfer(fe, &msg, 1); |
707 | } | 761 | } |
708 | 762 | ||
709 | /* ------------------------------------------------------------------ */ | 763 | /* ------------------------------------------------------------------ */ |
@@ -792,16 +846,19 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = { | |||
792 | }; | 846 | }; |
793 | 847 | ||
794 | static int tda827x_probe_version(struct dvb_frontend *fe) | 848 | static int tda827x_probe_version(struct dvb_frontend *fe) |
795 | { u8 data; | 849 | { |
850 | u8 data; | ||
851 | int rc; | ||
796 | struct tda827x_priv *priv = fe->tuner_priv; | 852 | struct tda827x_priv *priv = fe->tuner_priv; |
797 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, | 853 | struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD, |
798 | .buf = &data, .len = 1 }; | 854 | .buf = &data, .len = 1 }; |
799 | if (fe->ops.i2c_gate_ctrl) | 855 | |
800 | fe->ops.i2c_gate_ctrl(fe, 1); | 856 | rc = tuner_transfer(fe, &msg, 1); |
801 | if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) { | 857 | |
858 | if (rc < 0) { | ||
802 | printk("%s: could not read from tuner at addr: 0x%02x\n", | 859 | printk("%s: could not read from tuner at addr: 0x%02x\n", |
803 | __func__, msg.addr << 1); | 860 | __func__, msg.addr << 1); |
804 | return -EIO; | 861 | return rc; |
805 | } | 862 | } |
806 | if ((data & 0x3c) == 0) { | 863 | if ((data & 0x3c) == 0) { |
807 | dprintk("tda827x tuner found\n"); | 864 | dprintk("tda827x tuner found\n"); |
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c index 4b8662edb7cb..064d14c8d7b2 100644 --- a/drivers/media/common/tuners/tda8290.c +++ b/drivers/media/common/tuners/tda8290.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/videodev.h> | 25 | #include <linux/videodev2.h> |
26 | #include "tuner-i2c.h" | 26 | #include "tuner-i2c.h" |
27 | #include "tda8290.h" | 27 | #include "tda8290.h" |
28 | #include "tda827x.h" | 28 | #include "tda827x.h" |
@@ -566,8 +566,11 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
566 | u8 data; | 566 | u8 data; |
567 | struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; | 567 | struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 }; |
568 | 568 | ||
569 | if (NULL == analog_ops->i2c_gate_ctrl) | 569 | if (!analog_ops->i2c_gate_ctrl) { |
570 | printk(KERN_ERR "tda8290: no gate control were provided!\n"); | ||
571 | |||
570 | return -EINVAL; | 572 | return -EINVAL; |
573 | } | ||
571 | 574 | ||
572 | analog_ops->i2c_gate_ctrl(fe, 1); | 575 | analog_ops->i2c_gate_ctrl(fe, 1); |
573 | 576 | ||
@@ -615,11 +618,13 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) | |||
615 | 618 | ||
616 | if (ret != 1) { | 619 | if (ret != 1) { |
617 | tuner_warn("tuner access failed!\n"); | 620 | tuner_warn("tuner access failed!\n"); |
621 | analog_ops->i2c_gate_ctrl(fe, 0); | ||
618 | return -EREMOTEIO; | 622 | return -EREMOTEIO; |
619 | } | 623 | } |
620 | 624 | ||
621 | if ((data == 0x83) || (data == 0x84)) { | 625 | if ((data == 0x83) || (data == 0x84)) { |
622 | priv->ver |= TDA18271; | 626 | priv->ver |= TDA18271; |
627 | tda829x_tda18271_config.config = priv->cfg.config; | ||
623 | dvb_attach(tda18271_attach, fe, priv->tda827x_addr, | 628 | dvb_attach(tda18271_attach, fe, priv->tda827x_addr, |
624 | priv->i2c_props.adap, &tda829x_tda18271_config); | 629 | priv->i2c_props.adap, &tda829x_tda18271_config); |
625 | } else { | 630 | } else { |
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c index b23dadeecd05..60ed872f3d44 100644 --- a/drivers/media/common/tuners/tea5761.c +++ b/drivers/media/common/tuners/tea5761.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/videodev.h> | 12 | #include <linux/videodev2.h> |
13 | #include <media/tuner.h> | 13 | #include <media/tuner.h> |
14 | #include "tuner-i2c.h" | 14 | #include "tuner-i2c.h" |
15 | #include "tea5761.h" | 15 | #include "tea5761.h" |
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c index 1f5646334a8f..223a226d20a1 100644 --- a/drivers/media/common/tuners/tea5767.c +++ b/drivers/media/common/tuners/tea5767.c | |||
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/videodev.h> | 15 | #include <linux/videodev2.h> |
16 | #include "tuner-i2c.h" | 16 | #include "tuner-i2c.h" |
17 | #include "tea5767.h" | 17 | #include "tea5767.h" |
18 | 18 | ||
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c index 493ce93caf43..b54598550dc4 100644 --- a/drivers/media/common/tuners/xc5000.c +++ b/drivers/media/common/tuners/xc5000.c | |||
@@ -739,7 +739,10 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe, | |||
739 | dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", | 739 | dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", |
740 | __func__, params->frequency); | 740 | __func__, params->frequency); |
741 | 741 | ||
742 | priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */ | 742 | /* Fix me: it could be air. */ |
743 | priv->rf_mode = params->mode; | ||
744 | if (params->mode > XC_RF_MODE_CABLE) | ||
745 | priv->rf_mode = XC_RF_MODE_CABLE; | ||
743 | 746 | ||
744 | /* params->frequency is in units of 62.5khz */ | 747 | /* params->frequency is in units of 62.5khz */ |
745 | priv->freq_hz = params->frequency * 62500; | 748 | priv->freq_hz = params->frequency * 62500; |
@@ -970,8 +973,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
970 | case 1: | 973 | case 1: |
971 | /* new tuner instance */ | 974 | /* new tuner instance */ |
972 | priv->bandwidth = BANDWIDTH_6_MHZ; | 975 | priv->bandwidth = BANDWIDTH_6_MHZ; |
973 | priv->if_khz = cfg->if_khz; | ||
974 | |||
975 | fe->tuner_priv = priv; | 976 | fe->tuner_priv = priv; |
976 | break; | 977 | break; |
977 | default: | 978 | default: |
@@ -980,6 +981,13 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, | |||
980 | break; | 981 | break; |
981 | } | 982 | } |
982 | 983 | ||
984 | if (priv->if_khz == 0) { | ||
985 | /* If the IF hasn't been set yet, use the value provided by | ||
986 | the caller (occurs in hybrid devices where the analog | ||
987 | call to xc5000_attach occurs before the digital side) */ | ||
988 | priv->if_khz = cfg->if_khz; | ||
989 | } | ||
990 | |||
983 | /* Check if firmware has been loaded. It is possible that another | 991 | /* Check if firmware has been loaded. It is possible that another |
984 | instance of the driver has loaded the firmware. | 992 | instance of the driver has loaded the firmware. |
985 | */ | 993 | */ |